domHiddenYLT.js 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /**
  2. * Analyzes DOM hidden content
  3. */
  4. /* global document: true, Node: true, window: true */
  5. exports.version = '1.0.a';
  6. exports.module = function(phantomas) {
  7. 'use strict';
  8. // total length of HTML of hidden elements (i.e. display: none)
  9. phantomas.setMetric('hiddenContentSize'); // @desc the size of content of hidden elements on the page (with CSS display: none) @offenders
  10. phantomas.setMetric('hiddenImages'); // @desc number of hidden images that can be lazy-loaded @offenders
  11. // HTML size
  12. phantomas.on('report', function() {
  13. phantomas.evaluate(function() {
  14. (function(phantomas) {
  15. var runner = new phantomas.nodeRunner(),
  16. lazyLoadableImages = {};
  17. phantomas.spyEnabled(false, 'analyzing hidden content');
  18. runner.walk(document.body, function(node, depth) {
  19. switch (node.nodeType) {
  20. case Node.ELEMENT_NODE:
  21. // @see https://developer.mozilla.org/en/DOM%3awindow.getComputedStyle
  22. var styles = window.getComputedStyle(node);
  23. if (styles && styles.getPropertyValue('display') === 'none') {
  24. if (typeof node.innerHTML === 'string') {
  25. var size = node.innerHTML.length;
  26. phantomas.incrMetric('hiddenContentSize', size);
  27. // log hidden containers bigger than 1 kB
  28. if (size > 1024) {
  29. phantomas.addOffender('hiddenContentSize', phantomas.getDOMPath(node) + ' (' + size + ' characters)');
  30. }
  31. }
  32. // count hidden images that can be lazy loaded (issue #524)
  33. var images = [];
  34. if (node.tagName === 'IMG') {
  35. images = [node];
  36. } else if (typeof node.querySelectorAll === 'function') {
  37. images = node.querySelectorAll('img') || [];
  38. }
  39. for (var i = 0, len = images.length; i < len; i++) {
  40. var src = images[i].src,
  41. path;
  42. if (src === '' || src.indexOf('data:image') === 0) continue;
  43. if (images[i].width === 1 && images[i].height === 1) continue;
  44. if (!lazyLoadableImages[src]) {
  45. path = phantomas.getDOMPath(images[i]);
  46. lazyLoadableImages[src] = {
  47. path: path
  48. };
  49. }
  50. }
  51. // don't run for child nodes as they're hidden as well
  52. return false;
  53. }
  54. break;
  55. }
  56. });
  57. Object.keys(lazyLoadableImages).forEach(function(img) {
  58. var entry = lazyLoadableImages[img];
  59. phantomas.incrMetric('hiddenImages');
  60. phantomas.addOffender('hiddenImages', img);
  61. phantomas.log('hiddenImages: <%s> image (%s) is hidden and can be lazy-loaded', img, entry.path);
  62. });
  63. phantomas.spyEnabled(true);
  64. }(window.__phantomas));
  65. });
  66. });
  67. };