Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

JavaScript performance patterns

Ad

JavaScript Performance Patterns

         @stoyanstefanov
         frontendconf.ch
           Sept 6, 2012

Ad

JavaScript Performance Patterns

Ad

Importance of Performance




                    http://bookofspeed.com

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Ad

Nächste SlideShare
Liking performance
Liking performance
Wird geladen in …3
×

Hier ansehen

1 von 69 Anzeige
1 von 69 Anzeige
Anzeige

Weitere Verwandte Inhalte

Andere mochten auch (20)

Anzeige
Anzeige

JavaScript performance patterns

  1. 1. JavaScript Performance Patterns @stoyanstefanov frontendconf.ch Sept 6, 2012
  2. 2. JavaScript Performance Patterns
  3. 3. Importance of Performance http://bookofspeed.com
  4. 4. Importance of JavaScript Performance http://httparchive.org
  5. 5. // todo 1. Loading JavaScript 2. Runtime / UI / DOM + benchmarks + shims
  6. 6. Loading
  7. 7. First things first • reduce # of script files • gzip, shave 70% off • minify, extra 40-50% • Expires headers • CDN http://yslow.org PageSpeed http://webpagetest.org
  8. 8. <script src="http://…">
  9. 9. SPOF • Single point of failure • JS blocks http://phpied.com/3po-fail SPOF-O-Matic: https://chrome.google.com/webstore/detail/plikhggfbplemddobondkeogomgoodeg
  10. 10. Off the critical path
  11. 11. Asynchronous JS • <script defer> • <script async> • until then…
  12. 12. Dynamic script node var js = document.createElement('script'); js.src = 'http://cdn.com/my.js'; document.getElementsByTagName('head')[0].appendChild(js); http://calendar.perfplanet.com/2011/t he-art-and-craft-of-the-async-snippet/
  13. 13. But…, butt…, button? Q: <button onclick="…"? A: To hell with it Q: Dependencies? A: onload event and js.onreadystatechange load('jquery.js', 'mystuff.js', function () { mystuff.go(); });
  14. 14. Unblocking onload • Async JS blocks window.onload in !IE • May or may not be a problem • There's a solution: FIF
  15. 15. <fif> frame-in-frame aka friendly frames aka this Meebo thing
  16. 16. FIF 1) create iframe src="js:false" 2) in the frame doc.write a <body onload … 3) …that loads JS
  17. 17. FIF (snippet) var iframe = document.createElement('iframe'); document.body.appendChild(iframe); var doc = iframe.contentWindow.document; doc.open().write('<body onload="'+ 'var js = document.createElement('script');'+ 'js.src = 'http://example.org/js.js';'+ 'document.body.appendChild(js);">'); doc.close();
  18. 18. FIF • unblocks onload, but… • more complex • requires JS changes
  19. 19. your script (before) // fun with window // and document
  20. 20. your script (before) (function() { // fun with window // and document }());
  21. 21. FIF (after) (function(window) { var document = window.document; // fun with window // and document }(parent.window));
  22. 22. FIF in the wild • experimental support in FB JS SDK • http://jsbin.com/axibow/1/edit
  23. 23. </fif>
  24. 24. Load JS but not execute • Use cases: – preload in anticipation – lazy
  25. 25. Preload, then eventually execute 1. fetch the script, but don’t run it 2. run it at some point (same as async JS)
  26. 26. Fetching • IE: dynamic script node, not in the DOM • All others: CORS (XHR2) – your CDN should let you specify Access-Control-Allow-Origin header or else!
  27. 27. Preload, then execute // preload var js = document.createElement('script'); if (!js.readyState || js.readyState !== 'uninitialized') { // non IE var xhr = new XMLHttpRequest(); if ('withCredentials' in xhr) { // XHR2 xhr.open('GET', url, false); xhr.send(null); } } js.src = url; // IE preloads! Thanks @getify // execute document.getElementsByTagName('head')[0].appendChild(js);
  28. 28. // todo 1. Loading JavaScript 2. Runtime / UI / DOM + benchmarks + shims
  29. 29. Benchmarks • Lies, damn lies and performance advice • Test the wrong thing • Measure the wrong thing • Even if not, still draw the wrong conclusions
  30. 30. Your first benchmark var start = new Date(); // loop 100000 times var took = new Date() – start;
  31. 31. Benchmark.js • by John-David Dalton • used in http://jsperf.com – calibrating the test – end time (ops/second) – statistical significance – margin of error
  32. 32. http://calendar.perfplanet.com/2010/bulletpro of-javascript-benchmarks/
  33. 33. Benchmarking browsers? No, thanks
  34. 34. Let's test!
  35. 35. String concat var text = ""; text += "moar"; vs. var parts = []; parts.push('moar'); var text = push.join(''); http://jsperf.com/join-concat/
  36. 36. String concat
  37. 37. The pen is mightier than the sword! * * Only if the sword is very small and the pen very sharp
  38. 38. "Don't A, B is so much faster!" You should check it again
  39. 39. Profiling
  40. 40. Picking battles
  41. 41. DOM
  42. 42. DOM • DOM is slow • How slow? • http://jsperf.com/touching/4
  43. 43. DOM // DOM div.innerHTML += 'a'; div.innerHTML += 'b'; // string var html = ''; html += 'a'; html += 'b'; div.innerHTML = html;
  44. 44. DOM
  45. 45. DOM + string concat • put things in perspective http://jsperf.com/touching/5
  46. 46. ECMAland DOMland
  47. 47. DOM • caching DOM references • caching length in collection loops • "offline" changes in document fragment • batch style changes • reducing reflows and repaints
  48. 48. reflows getComputedStyle(), or currentStyle in IE bodystyle.color = 'red'; tmp = computed.backgroundColor; bodystyle.color = 'white'; tmp = computed.backgroundImage; bodystyle.color = 'green'; tmp = computed.backgroundAttachment; bodystyle.color = 'red'; bodystyle.color = 'white'; bodystyle.color = 'green'; tmp = computed.backgroundColor; tmp = computed.backgroundImage; tmp = computed.backgroundAttachment;
  49. 49. data attributes <div data-stuff="convenient"></div> • div.dataset.stuff • div.getAttribute('data-stuff') • Data.get(div).stuff // DIY
  50. 50. data attributes DIY var Data = function() { var warehouse = {}; var count = 1; return { set: function (dom, data) { if (!dom.__data) { dom.__data = "hello" + count++; } warehouse[dom.__data] = data; }, get: function(dom) { return warehouse[dom.__data]; } }; }();
  51. 51. data attributes
  52. 52. data attributes http://jsperf.com/data-dataset
  53. 53. Shims and polyfills
  54. 54. Shims • pick the smaller/optimized one • one that uses native where available * • load conditionally e.g. JSON is non-native only for 8% of users *, why load shim 100% of the time * http://html5please.us
  55. 55. Fast ECMAScript5 natives? • JDD: "browsers optimize loops because of benchmarks" • http://jsperf.com/native-for-loop-vs-array- foreach-and-array-map-vs-lodas/2
  56. 56. jQuery: the most popular polyfill • not free (perf-wise) • do you need it?
  57. 57. Cost of parsing and evaluating http://calendar.perfplanet.com/2011/laz y-evaluation-of-commonjs-modules/
  58. 58. Cost of parsing and evaluating
  59. 59. Experiment: jQuery vs. Zepto What’s the cost of just dropping it on the page?
  60. 60. jsperf.com/zepto-jq-eval […]
  61. 61. jsperf.com/zepto-jq-eval
  62. 62. jsperf.com/zepto-jq-eval
  63. 63. In closure… • JS off the critical path (async, lazy, preload) • Practice writing jsperf.com tests ("jsperf URL or it didn't happen!") • Don't touch the DOM (remember the bridge) • Use the tools (Timeline, CPU/heap profiler, SpeedTracer, Dynatrace) • Think of poor mobile (easy with the shims)
  64. 64. Thank you! http://slideshare.net/stoyan/

×