lazyLoadableYLT.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /**
  2. * Analyzes images and detects which one can be lazy-loaded (are below the fold)
  3. *
  4. * @see https://github.com/macbre/phantomas/issues/494
  5. */
  6. /* global document: true, window: true */
  7. exports.version = '1.0.a';
  8. exports.module = function(phantomas) {
  9. 'use strict';
  10. phantomas.setMetric('lazyLoadableImagesBelowTheFold'); // @desc number of images displayed below the fold that can be lazy-loaded
  11. phantomas.on('report', function() {
  12. phantomas.log('lazyLoadableImages: analyzing which images can be lazy-loaded...');
  13. phantomas.evaluate(function() {
  14. (function(phantomas) {
  15. phantomas.spyEnabled(false, 'analyzing which images can be lazy-loaded');
  16. var images = document.body.getElementsByTagName('img'),
  17. i,
  18. len = images.length,
  19. offset,
  20. path,
  21. processedImages = {},
  22. src,
  23. viewportHeight = window.innerHeight,
  24. // Add an offset of 100px under the height of the screen
  25. LAZYLOAD_OFFSET = 100;
  26. phantomas.log('lazyLoadableImages: %d image(s) found, assuming %dpx offset to be the fold', len, viewportHeight);
  27. for (i = 0; i < len; i++) {
  28. // @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
  29. offset = images[i].getBoundingClientRect().top;
  30. src = images[i].src;
  31. // ignore base64-encoded images
  32. if (src === '' || /^data:/.test(src)) {
  33. continue;
  34. }
  35. path = phantomas.getDOMPath(images[i]);
  36. // get the most top position for a given image (deduplicate by src)
  37. if (typeof processedImages[src] === 'undefined') {
  38. processedImages[src] = {
  39. offset: offset,
  40. path: path
  41. };
  42. }
  43. // maybe there's the same image loaded above the fold?
  44. if (offset < processedImages[src].offset) {
  45. processedImages[src] = {
  46. offset: offset,
  47. path: path
  48. };
  49. }
  50. }
  51. phantomas.log('lazyLoadableImages: checking %d unique image(s)', Object.keys(processedImages).length);
  52. Object.keys(processedImages).forEach(function(src) {
  53. var img = processedImages[src];
  54. if (img.offset > viewportHeight + LAZYLOAD_OFFSET) {
  55. phantomas.log('lazyLoadableImages: <%s> image (%s) is below the fold (at %dpx)', src, img.path, img.offset);
  56. phantomas.incrMetric('lazyLoadableImagesBelowTheFold');
  57. phantomas.addOffender('lazyLoadableImagesBelowTheFold', src);
  58. }
  59. });
  60. phantomas.spyEnabled(true);
  61. })(window.__phantomas);
  62. });
  63. });
  64. };