Search code examples
wordpressmasonry

Stop Masonry re-sizing when not all images are loaded


I am using Masonry (and imagesLoaded) with Wordpress:

<script src="http://cdnjs.cloudflare.com/ajax/libs/masonry/3.3.2/masonry.pkgd.min.js"></script>

and my site includes a number of images that ranges between 1 to 8 MB. I have noticed that the loading times are very long (I am using no pagination on Wordpress, so the page loads all content) and the grid keeps resizing until all images are loaded.

Is there a way to fix this?

This is my custom js:

$(document).ready(function() {

    let $masonryGrid = $('.masonry-grid');
    $masonryGrid.imagesLoaded(() => {
        $masonryGrid.masonry({
            columnWidth: '.grid-sizer',
            itemSelector: '.grid-item',
            gutter: 0,
            percentPosition: true,
            transitionDuration: 0
        });
    });
});

Solution

  • You can create a preview version for all of your images - same dimensions, but drastically downscaled quality. Maybe with a "Loading" text or symbol over them.

    Those previews should have the same filename with a suffix. You will have pairs of images like this

    image001.jpg
    image001_thumb.jpg
    

    Then the individual image elements will then automatically start loading the full version :

    <img src="image001_thumb.jpg" onload="this.src=this.src.replace('_thumb','');" />
    

    And if you cannot directly influence image elements like this, add this to your custom .ready function (this is an example that would affect all images, just to give you an idea, you have to filter out only the images that are inside the grid)

    var images = document.getElementsByTagName('img');
    for(var i=0;i<images.length;i++){
     // If the image is already loaded, change it immediately
     if(images[i].naturalWidth != 0) images[i].src = images[i].src.replace('_thumb','');
     else // If not, give it an onLoad function to change after it does
     images[i].onload = function(){
      this.src = this.src.replace('_thumb','');
     }
    }