Lazy load images on include content

I’m working on this [page][1]

The problem is that Homepage has a lot of items to show, so it loads really slow. The solution I found is to use lazy load on images (I’m using this plugin). It works on the left column (Which is not content included. You can see the images load as you scroll down) but it is not working with the items of the center and right columns which is the content I’m including.

Read More

I’m including the center and right column content this way:

<?php include("parts/backbone_tmpl_productos_main.php"); ?>

And this is the contents of the backbone_tmpl_productos_main.php file:

    <script id="tmpl_Post" type="template">
        <div class="image"><img src="<%= post_item.image_url.url %>" /></div>
        <div class="obra_meta">
            <span class="nombre_artista"><%
             _.each(taxonomy_product_cat, function(item){
                if(item.parent === 146){%><%= item.title %><% } 
                if(item.parent === 216){%><%= item.title %><% } 
             })
             %></span>
            <span class="nombre_obra"><%= title %></span>
        </div>
        <div class="descripcion_obra"></div>

        <div class="buy_opts">
            <?php if (ICL_LANGUAGE_CODE == 'en') {
                echo '<div class="precio pull-left">From: 24.99 €</div>';
            }else{
                echo '<% if(price != "") {%><div class="precio pull-left"><%= price %></div><% } %>';
            }
            ?>
            <div class="pull-right"><button class="btn btn-default boton_comprar comprar"><?=__('COMPRAR');?></button></div>
        </div>
    </script>

I think the problem that the plugin doesn’t work with the include content is because the content is loaded after the plugin loads.

Any idea what’s the real problem? how can I fix it?

Related posts

Leave a Reply

3 comments

  1. Lazy loading is a JavaScript (browser-side) effect. If has nothing to do with the “include” in PHP.

    Basically PHP generates the page, including all includes, and passes to browser. Browser then executes JS and initiates lazy loading.[1] The exact method with how PHP generates the page is irrelevant.

    Where the problem lies is most likely with the fact you have another script that appears to be positioning the “product” classes absolutely – presumable from the “datos” object you have in code. The datos script itself might be forcing the loading as otherwise it won’t know the size in order to position them – check what’s going on in this script.

    Also, there’s no guarantee what script is going to win; when your lazy-load script runs through all the products, finds they are “top 0” which is “above the fold” and so loads the images straight away. Then the datos script presumably then goes and positions those products below the fold, but it’s too late, they are loading (if not already loaded). Can’t be sure of the exact mechanics, but this is the most likely scenario.

    Solution:

    Firstly, check the datos script isn’t forcing a load in order to position the item. If it is, do you really need them absolutely positioned? Why not let them flow, then you can remove the src as below? If you do need absolutely position, I think it’s “tough”.

    Secondly: Assuming the datos script is not forcing a load, copy a bit of what coding-idiot suggested, and move the “src” into “data-src”, but then you need to modify the lazy-load script to pull the image from there. The code references a “settings.data_attribute” but there is nothing in the documentation. A quick read suggests that setting “dettings.data_atribute” to “src” may work, or ask the developer how to use those settings. (You may also need settings-placeholder at the same time). But by moving out of “src” and into a data attribute you stop the browser from loading initially and let the script do it’s job, because…

    Finally: Add a timeout in the lazy-load script so it triggers after the other script that positions the products.

    Other note: Plugins are great, but if you have this many, you’d probably be better off programming some of these yourself. They appear to conflict. Also, the lazy load plugin could be improved by storing/caching the $(element) jQuery object as opposed to repeatedly recreating it. You also have malformed HTML by adding scripts after the HTML closing tag. Some small improvements that may encourage you to dig deeper into exactly what is going on.

    [1] Note: to avoid comments, this is simplifying things as it IS possible to get JS to start before the entire page is loaded; buy you have the include at the bottom of the body so argument is mute.

  2. You could try to add later-reload-script to reload any failed to load
    images, that sometime the server refuse to process the incoming request.
    Here is the workaround that help me solved the problem.

    Add below javascript snippet in your template or view page

    function reload_img(idx, no_of_try)
    {

    console.log("Reload fired " + idx);
    var MAX_RETRIES = 100;
    var glob = true;
    
    $.each($("img"), function(index, value){
    
        if ( this.naturalWidth == 0)
        {
            $(this).attr("src", $(this).attr("src"));
            console.log( $(this).attr('src'));
            glob = false;
        }
    } );
    
    if ( !glob && no_of_try < MAX_RETRIES )
        setTimeout(function(){ reload_img(idx + 1, no_of_try + 1); }, 1500); 
    

    }

    setTimeout(function(){ reload_img(1,1); }, 1500); // start the reload_img() here

    The code simply checks if an element is loaded and rendered.
    If not, then retry to load the image with max of 100 retries.