12

this is my first quesiton 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 showacased 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, only thing that matters is "pictures". It's what the user cares. The reason they click on 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 my self if i'm crazy?

Thanks in advance, i'm just confused how such thing could happend.

On my magento 1, it loads instantly.

  • Agreed, they could at least have the base image displayed while fotorama loads. I'll have to build a module to do that. – Aaron Allen Sep 6 '16 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 Sep 6 '16 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 Jan 24 '17 at 15:34
  • Sometimes this command will work : php bin/magento catalog:images:resize – Saphal Jha Feb 18 '17 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 Mar 25 '18 at 12:16
11

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.

| improve this answer | |
  • Thanks Aaron! I will try tonight once i'm home! Really appreciate it! – Fancyman Sep 12 '16 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 Sep 12 '16 at 19:27
  • @Aaron Allen please explain what have you done with a comment in the post or in the code. – LucScu Oct 3 '16 at 9:03
  • 1
    I added the line for the first img element. – Aaron Allen Oct 3 '16 at 9:58
  • This worked for me on Magento EE 2.1.7. – sparecycle Dec 22 '17 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.

| improve this answer | |

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