domHiddenYLT.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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 (!lazyLoadableImages[src]) {
  44. path = phantomas.getDOMPath(images[i]);
  45. lazyLoadableImages[src] = {
  46. path: path
  47. };
  48. }
  49. }
  50. // don't run for child nodes as they're hidden as well
  51. return false;
  52. }
  53. break;
  54. }
  55. });
  56. Object.keys(lazyLoadableImages).forEach(function(img) {
  57. var entry = lazyLoadableImages[img];
  58. phantomas.incrMetric('hiddenImages');
  59. phantomas.addOffender('hiddenImages', img);
  60. phantomas.log('hiddenImages: <%s> image (%s) is hidden and can be lazy-loaded', img, entry.path);
  61. });
  62. phantomas.spyEnabled(true);
  63. }(window.__phantomas));
  64. });
  65. });
  66. };