Successfully reported this slideshow.

How DRY impacts JavaScript performance // Faster JavaScript execution for the lazy developer

8

Share

Loading in …3
×
1 of 74
1 of 74

More Related Content

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

How DRY impacts JavaScript performance // Faster JavaScript execution for the lazy developer

  1. 1. How DRY impacts JavaScript performance // Faster JavaScript execution for the lazy developer Mathias Bynens – Velocity Europe, November 2011
  2. 2. @mathias
  3. 3. JavaScript & performance Rule #1: nothing to do with JS
  4. 4. JavaScript & performance
  5. 5. JavaScript & performance What about the actual run-time performance on the client side?
  6. 6. DRY flic.kr/p/2ZGCT
  7. 7. WET flic.kr/p/5Jnj7Q
  8. 8. “DRY leads to readable, maintainable code”
  9. 9. DRY JavaScript improves performance …if you do it right
  10. 10. So, where to avoid repetition?
  11. 11. What’s slow in JavaScript?
  12. 12. What’s slow in JavaScript? 1. The DOM
  13. 13. What’s slow in JavaScript? 1. The DOM 2. Function calls
  14. 14. What’s slow in JavaScript? 1. The DOM 2. Function calls 3. Lookups
  15. 15. DOM manipulation // Create the element in memory var el = document.createElement('p'); // Insert the element into the DOM document.body.appendChild(el);
  16. 16. DOM manipulation <body> … <div> <p></p> </div> </body>
  17. 17. DOM manipulation var div = document.createElement('div'), p = document.createElement('p'); // Bad document.body.appendChild(div); div.appendChild(p);
  18. 18. DOM manipulation var div = document.createElement('div'), p = document.createElement('p'); // Better div.appendChild(p); document.body.appendChild(div);
  19. 19. DOM manipulation <body> … <p></p> <p></p> <p></p> <p></p> </body>
  20. 20. DOM manipulation var p = document.createElement('p'), i = 4; while (i--) { // Add four <p> elements document.body.appendChild(p.cloneNode(false)); }
  21. 21. DOM manipulation var frag = document.createDocumentFragment(), p = document.createElement('p'), i = 4; while (i--) { // Add four <p> elements frag.appendChild(p.cloneNode(false)); } document.body.appendChild(frag);
  22. 22. Function calls // Function declaration function foo(bar) { return bar; } // Function call foo('something');
  23. 23. Function calls alert('foo'); document.getElementById('foo'); $('#foo');
  24. 24. Function calls $('.foo').show(); // other stuff… $('.foo').hide();
  25. 25. Function calls var $foo = $('.foo'); $foo.show(); // other stuff… $foo.hide();
  26. 26. Function calls var $foo = $('.foo').show(); // other stuff… $foo.hide();
  27. 27. Property lookups var obj = { 'x': 42, 'y': { 'foo': 'bar' } }; obj.x; // 42 obj.y.foo; // 'bar'
  28. 28. Property lookups document.title dojo.query(…) YAHOO.util.Dom.get(…)
  29. 29. Property lookups var foo = YAHOO.util.Dom.get('foo'), bar = YAHOO.util.Dom.get('bar'), baz = YAHOO.util.Dom.get('baz'), qux = YAHOO.util.Dom.get('qux');
  30. 30. Property lookups var get = YAHOO.util.Dom.get, foo = get('foo'), bar = get('bar'), baz = get('baz'), qux = get('qux');
  31. 31. Array item lookups var elems = document.getElementsByTagName('p'), length = elems.length; while (length--) { if (elems[length].className == 'foo') { // do something with elems[length] elems[length].innerHTML = 'LOLWAT'; } }
  32. 32. Array item lookups var elems = document.getElementsByTagName('p'), length = elems.length, elem; while (length--) { elem = elems[length]; if (elem.className == 'foo') { // do something with elem elem.innerHTML = 'LOLWAT'; } }
  33. 33. Scope lookups var foo = 42; foo; // no scope lookup
  34. 34. Scope lookups var foo = 42; (function() { foo; // one scope lookup }()); // IIFE – see http://mths.be/iife
  35. 35. Scope lookups var foo = 42; (function() { (function() { foo; // two scope lookups }()); }());
  36. 36. Scope lookups
  37. 37. Scope lookups var foo = 42; (function(foo) { (function(foo) { foo; // ZOMG, no scope lookups!!1 }(foo)); }(foo));
  38. 38. Scope lookups
  39. 39. Scope lookups (function() { // every time you use `window` // or `document` here // that’s a scope lookup }());
  40. 40. Scope lookups (function() { var doc = document, win = window; // lookup once, then cache }());
  41. 41. Scope lookups (function(win, doc) { // use `win` and `doc` here // no scope lookups // no performance penalty! }(this, document));
  42. 42. Recap: what’s slow in JavaScript?
  43. 43. Recap: what’s slow in JavaScript? 1. The DOM
  44. 44. Recap: what’s slow in JavaScript? 1. The DOM 2. Function calls
  45. 45. Recap: what’s slow in JavaScript? 1. The DOM 2. Function calls 3. Lookups
  46. 46. Especially when used inside…
  47. 47. Especially when used inside… • Loops
  48. 48. Especially when used inside… • Loops • Intervals
  49. 49. Especially when used inside… • Loops • Intervals • Handlers for events that fire frequently
  50. 50. It happens to the best! // Don’t do this: $(window).scroll(function() { $('.foo').something(); });
  51. 51. It happens to the best! // Don’t do this: $(window).scroll(function() { $('.foo').something(); });
  52. 52. It happens to the best! // Don’t do this: $(window).scroll(function() { $('.foo').something(); }); // See http://mths.be/azs
  53. 53. typeof performance != 'the whole story'
  54. 54. tips & tricks (not really)
  55. 55. New objects var obj = new Object(); obj.x = 42; obj.y = 'foo'; obj.z = false;
  56. 56. New objects var obj = { 'x': 42, 'y': 'foo', 'z': false };
  57. 57. New arrays var arr = new Array(); arr.push(42); arr.push('foo'); arr.push(false);
  58. 58. New arrays var arr = [ 42, 'foo', false ];
  59. 59. Avoid switch switch(foo) { case 'alpha': // do X break; case 'beta': // do Y break; default: // do Z break; }
  60. 60. Avoid switch var switchObj = { 'alpha': function() { // do X }, 'beta': function() { // do Y }, '_default': function() { // do Z } }; (switchObj.hasOwnProperty(foo) && switchObj[foo] || switchObj._default)(args);
  61. 61. Don’t use jQuery for everything $('.foo').click(function() { $(this).prop('id'); // same as this, before jQuery 1.6: // $(this).attr('id'); // also `href`, `checked`, `value`… });
  62. 62. Don’t use jQuery for everything $('.foo').click(function() { this.id; this.href; this.checked; this.value; // etc. });
  63. 63. jQuery document ready $(document).ready(function() { // teh coads });
  64. 64. jQuery document ready $().ready(function() { // heh });
  65. 65. jQuery document ready $.fn.ready(function() { // not pretty, but fastest solution });
  66. 66. jQuery document ready $(function() { // moar sexy, but slower });
  67. 67. jQuery document ready (function() { // move <script>s to the bottom // and just use an IIFE* }()); // * unless you use .appendChild() / .innerHTML on document.documentElement or document.body: http://mths.be/ieoa
  68. 68. jQuery collection size $('.foo').size(); // NO.
  69. 69. jQuery collection size // jQuery source: $.fn.size = function() { return this.length; }; // …so, just use: $('.foo').length;
  70. 70. Use context $('#foo .bar').addClass('baz'); $('#foo .qux').hide(); $('#foo input').removeClass('wut');
  71. 71. Use context var $foo = $('#foo'); $('.bar', $foo).addClass('baz'); $('.qux', $foo).hide(); $('input', $foo).removeClass('wut');
  72. 72. this.location = 'http://jsperf.com/'
  73. 73. http://jsperf.com/browse/mathias-bynens
  74. 74. Questions? @mathias

×