14

this is my first question bare with me :)

Problem: The fotorama gallery used in Magento 2 makes the user experience sluggish. It does not matter how fast my cached static Magento 2 runs if the product image is not "instant".

https://www.ninewest.co.uk/sandals/high-heel/allclear-black-snake-print-nine-west

If you go to the above link, (a store showcased on Magento blog), you can see it opens, then it shows a loading icon, and then it loads the images. That's horrible.

It should load instantly. Like bamm. Done, Specially with full page cache and opcache enabled.

Is there a way to change this behavior? To load it instantly?

For the user, it's the most important "element" on the page. and it loads as the latest.

I don't understand how no one is complaining about this.

This is E-commerce, the only thing that matters is "pictures". It's what the user cares about. The reason they click on the product page is to "see the images better. Personally, for me, it truly bugs me. For no reason, I become super angry and then I ask myself if I'm crazy?

I'm just confused about how such a thing could happen.

On my Magento 1, it loads instantly.

5
  • Agreed, they could at least have the base image displayed while fotorama loads. I'll have to build a module to do that. Commented Sep 6, 2016 at 1:16
  • They have added it to feature improvement request. On mobile it's even worse. But funny thing is, when you go to fotorama website on mobile, those big image gallery's load faster then magento one. When you do a refresh, it's almost instant. The problem lies with magento.
    – Fancyman
    Commented Sep 6, 2016 at 13:49
  • Surely must be a fix for this by now? Its still super slow, thanks for asking the question, i'll keep checking back on this to see if anything ever changes haha.
    – andy jones
    Commented Jan 24, 2017 at 15:34
  • Sometimes this command will work : php bin/magento catalog:images:resize
    – Saphal Jha
    Commented Feb 18, 2017 at 12:23
  • What does it mean and how to do "Fix for jumping content. Loader must be the same size as gallery" I found one problem which is when my product load than image shows first small and than big
    – Akbar Mo
    Commented Mar 25, 2018 at 12:16

3 Answers 3

13

Here's a simple solution that will cause the product's base image to be displayed while the JS is loading.

Create the following file in your theme: {theme_dir}/Magento_Catalog/templates/product/view/gallery.phtml containing:

<div class="gallery-placeholder _block-content-loading" data-gallery-role="gallery-placeholder">
    <div data-role="loader" class="loading-mask">
        <div class="loader">

            <img src="<?php echo $block->getGalleryImages()->getFirstItem()->getData('medium_image_url') ?>" style="max-width: 100%; max-height: 100%">

            <img src="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-1.gif'); ?>"
                 alt="<?php /* @escapeNotVerified */ echo __('Loading...') ?>">
        </div>
    </div>
</div>
<!--Fix for jumping content. Loader must be the same size as gallery.-->
<script>
    var config = {
            "width": <?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_medium', 'width'); ?>,
            "thumbheight": <?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_small', 'height')
                        ?: $block->getImageAttribute('product_page_image_small', 'width'); ?>,
            "navtype": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/navtype"); ?>",
            "height": <?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_medium', 'height'); ?>
        },
        thumbBarHeight = 0,
        loader = document.querySelectorAll('[data-gallery-role="gallery-placeholder"] [data-role="loader"]')[0];

    if (config.navtype === 'horizontal') {
        thumbBarHeight = config.thumbheight;
    }

    loader.style.paddingBottom = ( config.height / config.width * 100) + "%";
</script>
<script type="text/x-magento-init">
    {
        "[data-gallery-role=gallery-placeholder]": {
            "mage/gallery/gallery": {
                "mixins":["magnifier/magnify"],
                "magnifierOpts": <?php /* @escapeNotVerified */ echo $block->getMagnifier(); ?>,
                "data": <?php /* @escapeNotVerified */ echo $block->getGalleryImagesJson(); ?>,
                "options": {
                    "nav": "<?php /* @escapeNotVerified */ echo $block->getVar("gallery/nav"); ?>",
                    <?php if (($block->getVar("gallery/loop"))): ?>
                        "loop": <?php /* @escapeNotVerified */ echo $block->getVar("gallery/loop"); ?>,
                    <?php endif; ?>
                    <?php if (($block->getVar("gallery/keyboard"))): ?>
                        "keyboard": <?php /* @escapeNotVerified */ echo $block->getVar("gallery/keyboard"); ?>,
                    <?php endif; ?>
                    <?php if (($block->getVar("gallery/arrows"))): ?>
                        "arrows": <?php /* @escapeNotVerified */ echo $block->getVar("gallery/arrows"); ?>,
                    <?php endif; ?>
                    <?php if (($block->getVar("gallery/allowfullscreen"))): ?>
                        "allowfullscreen": <?php /* @escapeNotVerified */ echo $block->getVar("gallery/allowfullscreen"); ?>,
                    <?php endif; ?>
                    <?php if (($block->getVar("gallery/caption"))): ?>
                        "showCaption": <?php /* @escapeNotVerified */ echo $block->getVar("gallery/caption"); ?>,
                    <?php endif; ?>
                    "width": "<?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_medium', 'width'); ?>",
                    "thumbwidth": "<?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_small', 'width'); ?>",
                    <?php if ($block->getImageAttribute('product_page_image_small', 'height') || $block->getImageAttribute('product_page_image_small', 'width')): ?>
                        "thumbheight": <?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_small', 'height')
                        ?: $block->getImageAttribute('product_page_image_small', 'width'); ?>,
                    <?php endif; ?>
                    <?php if ($block->getImageAttribute('product_page_image_medium', 'height') || $block->getImageAttribute('product_page_image_medium', 'width')): ?>
                        "height": <?php /* @escapeNotVerified */ echo $block->getImageAttribute('product_page_image_medium', 'height')
                        ?: $block->getImageAttribute('product_page_image_medium', 'width'); ?>,
                    <?php endif; ?>
                    <?php if ($block->getVar("gallery/transition/duration")): ?>
                        "transitionduration": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/transition/duration"); ?>,
                    <?php endif; ?>
                    "transition": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/transition/effect"); ?>",
                    <?php if (($block->getVar("gallery/navarrows"))): ?>
                        "navarrows": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/navarrows"); ?>,
                    <?php endif; ?>
                    "navtype": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/navtype"); ?>",
                    "navdir": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/navdir"); ?>"
                },
                "fullscreen": {
                    "nav": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/nav"); ?>",
                    <?php if ($block->getVar("gallery/fullscreen/loop")): ?>
                        "loop": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/loop"); ?>,
                    <?php endif; ?>
                    "navdir": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/navdir"); ?>",
                    <?php if ($block->getVar("gallery/transition/navarrows")): ?>
                        "navarrows": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/navarrows"); ?>,
                    <?php endif; ?>
                    "navtype": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/navtype"); ?>",
                    <?php if ($block->getVar("gallery/fullscreen/arrows")): ?>
                        "arrows": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/arrows"); ?>,
                    <?php endif; ?>
                    <?php if ($block->getVar("gallery/fullscreen/caption")): ?>
                        "showCaption": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/caption"); ?>,
                    <?php endif; ?>
                    <?php if ($block->getVar("gallery/fullscreen/transition/duration")): ?>
                        "transitionduration": <?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/transition/duration"); ?>,
                    <?php endif; ?>
                    "transition": "<?php /* @escapeNotVerified */  echo $block->getVar("gallery/fullscreen/transition/effect"); ?>"
                },
                "breakpoints": <?php /* @escapeNotVerified */ echo $block->getBreakpoints(); ?>
            }
        }
    }
</script>

Hope this helps.

8
  • Thanks Aaron! I will try tonight once i'm home! Really appreciate it!
    – Fancyman
    Commented Sep 12, 2016 at 17:40
  • Aaron I tried it. It works. It's a nice temporary solution but i wish they could have fix the gallery load speed. I don't understand why it loads so slow. On fotorama site ,it's bigger gallery and it loads instantly. You can even try on your mobile fotorama.io , u can see it's alot faster and the images are alot bigger.
    – Fancyman
    Commented Sep 12, 2016 at 19:27
  • @Aaron Allen please explain what have you done with a comment in the post or in the code.
    – LucScu
    Commented Oct 3, 2016 at 9:03
  • 1
    I added the line for the first img element. Commented Oct 3, 2016 at 9:58
  • This worked for me on Magento EE 2.1.7.
    – sparecycle
    Commented Dec 22, 2017 at 19:57
2

Aaron Allen's answer was great and i used it to figure out how to do it for my custom setup.

All i had to do was add the image with some inline css and add padding-bottom: 100% to the loading-mask.

...
<div class="gallery-placeholder _block-content-loading" data-gallery-role="gallery-placeholder">
    <div data-role="loader" class="loading-mask" style="padding-bottom:100%;">
        <div class="loader">
            <img src="<?php echo $_product->getData('img_url'); ?>" style="max-width: 100%; max-height: 100%; display: block;">
            <img src="<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-1.gif'); ?>"
                 alt="<?php /* @escapeNotVerified */ echo __('Loading...') ?>">
        </div>
    </div>
</div>
...

Its quite similar to the answer above but i wanted to add my 2 cents.

0

in Magento 2.4 you have the make the div gallery-placeholder like this, else it keeps loading

<div class="gallery-placeholder _block-content-loading" data-gallery-role="gallery-placeholder">
    <img class="gallery-placeholder__image"
         src="<?= /* @escapeNotVerified */
         $block->getViewFileUrl('images/loader-1.gif') ?>"
         alt="<?= /* @escapeNotVerified */
         __('Loading...') ?>">
</div>

Not the answer you're looking for? Browse other questions tagged or ask your own question.