diff --git a/lib/tools/phantomas/custom_modules/modules/lazyLoadableYLT/lazyLoadableYLT.js b/lib/tools/phantomas/custom_modules/modules/lazyLoadableYLT/lazyLoadableYLT.js new file mode 100644 index 0000000..0547d98 --- /dev/null +++ b/lib/tools/phantomas/custom_modules/modules/lazyLoadableYLT/lazyLoadableYLT.js @@ -0,0 +1,78 @@ +/** + * Analyzes images and detects which one can be lazy-loaded (are below the fold) + * + * @see https://github.com/macbre/phantomas/issues/494 + */ +/* global document: true, window: true */ +'use strict'; + +exports.version = '1.0.a'; + +exports.module = function(phantomas) { + phantomas.setMetric('lazyLoadableImagesBelowTheFold'); // @desc number of images displayed below the fold that can be lazy-loaded + + phantomas.on('report', function() { + phantomas.log('lazyLoadableImages: analyzing which images can be lazy-loaded...'); + + phantomas.evaluate(function() { + (function(phantomas) { + phantomas.spyEnabled(false, 'analyzing which images can be lazy-loaded'); + + var images = document.body.getElementsByTagName('img'), + i, + len = images.length, + offset, + path, + processedImages = {}, + src, + viewportHeight = window.innerHeight; + + phantomas.log('lazyLoadableImages: %d image(s) found, assuming %dpx offset to be the fold', len, viewportHeight); + + for (i = 0; i < len; i++) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect + offset = images[i].getBoundingClientRect().top; + src = images[i].src; + + // ignore base64-encoded images + if (src === '' || /^data:/.test(src)) { + continue; + } + + path = phantomas.getDOMPath(images[i]); + + // get the most top position for a given image (deduplicate by src) + if (typeof processedImages[src] === 'undefined') { + processedImages[src] = { + offset: offset, + path: path + }; + } + + // maybe there's the same image loaded above the fold? + if (offset < processedImages[src].offset) { + processedImages[src] = { + offset: offset, + path: path + }; + } + } + + phantomas.log('lazyLoadableImages: checking %d unique image(s)', Object.keys(processedImages).length); + + Object.keys(processedImages).forEach(function(src) { + var img = processedImages[src]; + + if (img.offset > viewportHeight) { + phantomas.log('lazyLoadableImages: <%s> image (%s) is below the fold (at %dpx)', src, img.path, img.offset); + + phantomas.incrMetric('lazyLoadableImagesBelowTheFold'); + phantomas.addOffender('lazyLoadableImagesBelowTheFold', src); + } + }); + + phantomas.spyEnabled(true); + })(window.__phantomas); + }); + }); +}; \ No newline at end of file diff --git a/lib/tools/phantomas/phantomasWrapper.js b/lib/tools/phantomas/phantomasWrapper.js index e739a90..9660ae2 100644 --- a/lib/tools/phantomas/phantomasWrapper.js +++ b/lib/tools/phantomas/phantomasWrapper.js @@ -46,6 +46,7 @@ var PhantomasWrapper = function() { 'javaScriptBottlenecks', // needs to be launched after custom module scopeYLT 'jQuery', // overridden 'jserrors', // overridden + 'lazyLoadableImages', //overriden 'pageSource', // not needed 'windowPerformance' // overriden ].join(','),