How DRY impacts JavaScript performance //Faster JavaScript execution for the lazy developerMathias Bynens – Velocity Europ...
@mathias
JavaScript & performance          Rule #1: nothing to do with JS
JavaScript & performance
JavaScript & performance                  What about        the actual run-time performance              on the client side?
DRY      flic.kr/p/2ZGCT
WET      flic.kr/p/5Jnj7Q
“DRY leads to readable,  maintainable code”
DRY JavaScript  improves performance     …if you do it right
So, where to avoid    repetition?
What’s slow in JavaScript?
What’s slow in JavaScript?1. The DOM
What’s slow in JavaScript?1. The DOM2. Function calls
What’s slow in JavaScript?1. The DOM2. Function calls3. Lookups
DOM manipulation// Create the element in memoryvar el = document.createElement(p);// Insert the element into the DOMdocume...
DOM manipulation<body>  …  <div>      <p></p>  </div></body>
DOM manipulationvar div = document.createElement(div),    p = document.createElement(p);// Baddocument.body.appendChild(di...
DOM manipulationvar div = document.createElement(div),    p = document.createElement(p);// Betterdiv.appendChild(p);docume...
DOM manipulation<body>  …  <p></p>  <p></p>  <p></p>  <p></p></body>
DOM manipulationvar p = document.createElement(p),      i = 4;while (i--) { // Add four <p> elements    document.body.appe...
DOM manipulationvar frag = document.createDocumentFragment(),      p = document.createElement(p),      i = 4;while (i--) {...
Function calls// Function declarationfunction foo(bar) {    return bar;}// Function callfoo(something);
Function callsalert(foo);document.getElementById(foo);$(#foo);
Function calls$(.foo).show();// other stuff…$(.foo).hide();
Function callsvar $foo = $(.foo);$foo.show();// other stuff…$foo.hide();
Function callsvar $foo = $(.foo).show();// other stuff…$foo.hide();
Property lookupsvar obj = {     x: 42,     y: {         foo: bar     }};obj.x; // 42obj.y.foo; // bar
Property lookupsdocument.titledojo.query(…)YAHOO.util.Dom.get(…)
Property lookupsvar foo = YAHOO.util.Dom.get(foo),    bar = YAHOO.util.Dom.get(bar),    baz = YAHOO.util.Dom.get(baz),    ...
Property lookupsvar get = YAHOO.util.Dom.get,    foo = get(foo),    bar = get(bar),    baz = get(baz),    qux = get(qux);
Array item lookupsvar elems = document.getElementsByTagName(p),        length = elems.length;while (length--) {    if (ele...
Array item lookupsvar elems = document.getElementsByTagName(p),    length = elems.length,    elem;while (length--) {  elem...
Scope lookupsvar foo = 42;foo; // no scope lookup
Scope lookupsvar foo = 42;(function() {  foo; // one scope lookup}());// IIFE – see http://mths.be/iife
Scope lookupsvar foo = 42;(function() {  (function() {    foo; // two scope lookups  }());}());
Scope lookups
Scope lookupsvar foo = 42;(function(foo) {  (function(foo) {    foo; // ZOMG, no scope lookups!!1  }(foo));}(foo));
Scope lookups
Scope lookups(function() {  // every time you use `window`  // or `document` here  // that’s a scope lookup}());
Scope lookups(function() {  var doc = document,        win = window;  // lookup once, then cache}());
Scope lookups(function(win, doc) {  // use `win` and `doc` here  // no scope lookups  // no performance penalty!}(this, do...
Recap: what’s slow in JavaScript?
Recap: what’s slow in JavaScript?1. The DOM
Recap: what’s slow in JavaScript?1. The DOM2. Function calls
Recap: what’s slow in JavaScript?1. The DOM2. Function calls3. Lookups
Especially when used inside…
Especially when used inside…• Loops
Especially when used inside…• Loops• Intervals
Especially when used inside…• Loops• Intervals• Handlers for events that fire frequently
It happens to the best!// Don’t do this:$(window).scroll(function() {  $(.foo).something();});
It happens to the best!// Don’t do this:$(window).scroll(function() {  $(.foo).something();});
It happens to the best!// Don’t do this:$(window).scroll(function() {  $(.foo).something();});// See http://mths.be/azs
typeof performance != the whole story
tips & tricks   (not really)
New objectsvar obj = new Object();obj.x = 42;obj.y = foo;obj.z = false;
New objectsvar obj = {     x: 42,     y: foo,     z: false};
New arraysvar arr = new Array();arr.push(42);arr.push(foo);arr.push(false);
New arraysvar arr = [     42,     foo,     false];
Avoid switchswitch(foo) {  case alpha:    // do X    break;  case beta:    // do Y    break;  default:    // do Z    break;}
Avoid switchvar switchObj = {     alpha: function() {       // do X     },     beta: function() {          // do Y     }, ...
Don’t use jQuery for everything$(.foo).click(function() {  $(this).prop(id);  // same as this, before jQuery 1.6:  // $(th...
Don’t use jQuery for everything$(.foo).click(function() {  this.id;  this.href;  this.checked;  this.value;  // etc.});
jQuery document ready$(document).ready(function() {  // teh coads});
jQuery document ready$().ready(function() {  // heh});
jQuery document ready$.fn.ready(function() {  // not pretty, but fastest solution});
jQuery document ready$(function() {  // moar sexy, but slower});
jQuery document ready(function() {    // move <script>s to the bottom    // and just use an IIFE*}());// * unless you use ...
jQuery collection size$(.foo).size(); // NO.
jQuery collection size// jQuery source:$.fn.size = function() {     return this.length;};// …so, just use:$(.foo).length;
Use context$(#foo .bar).addClass(baz);$(#foo .qux).hide();$(#foo input).removeClass(wut);
Use contextvar $foo = $(#foo);$(.bar, $foo).addClass(baz);$(.qux, $foo).hide();$(input, $foo).removeClass(wut);
this.location = http://jsperf.com/
http://jsperf.com/browse/mathias-bynens
Questions?   @mathias
Upcoming SlideShare
Loading in …5
×

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

7,244 views
7,029 views

Published on

The slides for my Velocity Europe 2011 talk.

Published in: Technology
1 Comment
8 Likes
Statistics
Notes
No Downloads
Views
Total views
7,244
On SlideShare
0
From Embeds
0
Number of Embeds
110
Actions
Shares
0
Downloads
46
Comments
1
Likes
8
Embeds 0
No embeds

No notes for slide

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 developerMathias 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 DOM2. Function calls
  14. 14. What’s slow in JavaScript?1. The DOM2. Function calls3. Lookups
  15. 15. DOM manipulation// Create the element in memoryvar el = document.createElement(p);// Insert the element into the DOMdocument.body.appendChild(el);
  16. 16. DOM manipulation<body> … <div> <p></p> </div></body>
  17. 17. DOM manipulationvar div = document.createElement(div), p = document.createElement(p);// Baddocument.body.appendChild(div);div.appendChild(p);
  18. 18. DOM manipulationvar div = document.createElement(div), p = document.createElement(p);// Betterdiv.appendChild(p);document.body.appendChild(div);
  19. 19. DOM manipulation<body> … <p></p> <p></p> <p></p> <p></p></body>
  20. 20. DOM manipulationvar p = document.createElement(p), i = 4;while (i--) { // Add four <p> elements document.body.appendChild(p.cloneNode(false));}
  21. 21. DOM manipulationvar 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 declarationfunction foo(bar) { return bar;}// Function callfoo(something);
  23. 23. Function callsalert(foo);document.getElementById(foo);$(#foo);
  24. 24. Function calls$(.foo).show();// other stuff…$(.foo).hide();
  25. 25. Function callsvar $foo = $(.foo);$foo.show();// other stuff…$foo.hide();
  26. 26. Function callsvar $foo = $(.foo).show();// other stuff…$foo.hide();
  27. 27. Property lookupsvar obj = { x: 42, y: { foo: bar }};obj.x; // 42obj.y.foo; // bar
  28. 28. Property lookupsdocument.titledojo.query(…)YAHOO.util.Dom.get(…)
  29. 29. Property lookupsvar 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 lookupsvar get = YAHOO.util.Dom.get, foo = get(foo), bar = get(bar), baz = get(baz), qux = get(qux);
  31. 31. Array item lookupsvar 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 lookupsvar 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 lookupsvar foo = 42;foo; // no scope lookup
  34. 34. Scope lookupsvar foo = 42;(function() { foo; // one scope lookup}());// IIFE – see http://mths.be/iife
  35. 35. Scope lookupsvar foo = 42;(function() { (function() { foo; // two scope lookups }());}());
  36. 36. Scope lookups
  37. 37. Scope lookupsvar 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 DOM2. Function calls
  45. 45. Recap: what’s slow in JavaScript?1. The DOM2. Function calls3. 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 objectsvar obj = new Object();obj.x = 42;obj.y = foo;obj.z = false;
  56. 56. New objectsvar obj = { x: 42, y: foo, z: false};
  57. 57. New arraysvar arr = new Array();arr.push(42);arr.push(foo);arr.push(false);
  58. 58. New arraysvar arr = [ 42, foo, false];
  59. 59. Avoid switchswitch(foo) { case alpha: // do X break; case beta: // do Y break; default: // do Z break;}
  60. 60. Avoid switchvar 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 contextvar $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

×