Last active
December 25, 2022 09:04
-
-
Save optimalisatie/be5793eee869082fea2e1ab7ffd77ef2 to your computer and use it in GitHub Desktop.
Image lazy loading with instant visibility of in-view images on page load (MutationObserver)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Performance tests such as Google Lighthouse often complain about below the fold images while lazy loading | |
// techniques may introduce a flash effect for images on bigger screens | |
// This snippet shows a solution to instantly display images as if loaded using src="" while maintaining | |
// the lazy loading benefit on smaller screens. | |
// Tip: a second and potentially better technique is to rewrite lazy loaded images to regular src="" images in a Service Worker. | |
// this snippet depends on in-view (5kb) | |
// @link https://github.com/camwiegert/in-view/ | |
// tiny cross browser domready method | |
// @link https://gist.github.com/dciccale/4087856 | |
var DOMReady = function(a,b,c){b=document,c='addEventListener';b[c]?b[c]('DOMContentLoaded',a):window.attachEvent('onload',a)} | |
// requestAnimationframe | |
var RAF = window.requestAnimationframe || setTimeout; | |
var lazyToken = 'data-lzy'; | |
// display image | |
var lazyResolve = function(el) { | |
// already loaded | |
if (!el.hasAttribute(lazyToken)) { | |
return; | |
} | |
// verify if image is hidden by parent | |
if (el.offsetParent !== null) { | |
// remove lazy marker (to mark as completed) | |
el.removeAttribute(lazyToken); | |
// requestAnimationFrame to prevent layout trashing | |
RAF(function() { | |
el.setAttribute('src', el.getAttribute(lazyToken)); | |
}); | |
} | |
} | |
// setup lazy load method | |
DOMReady(function() { | |
inView('['+lazyToken+']').on('enter', lazyResolve); | |
}); | |
// instantly load visible images on render | |
var mutationObserver = window.MutationObserver || window.WebKitMutationObserver, | |
observer; | |
if (mutationObserver) { | |
observer = new mutationObserver(function(mutations) { | |
mutations.forEach(function(mutation) { | |
var node; | |
for (var i = 0; i < mutation.addedNodes.length; i++) { | |
node = mutation.addedNodes[i]; | |
if (node.nodeName === 'IMG' && node.hasAttribute(lazyToken)) { | |
if (inView.is(node)) { | |
// start download | |
new Image().src = node.getAttribute(lazyToken); | |
// display image with requestAnimationFrame | |
lazyResolve(node); | |
} | |
} | |
} | |
}); | |
}); | |
observer.observe(document.documentElement, { | |
childList: true, | |
subtree: true | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment