Se ha denunciado esta presentación.
Se está descargando tu SlideShare. ×

JavaScript performance patterns

Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Anuncio
Próximo SlideShare
Liking performance
Liking performance
Cargando en…3
×

Eche un vistazo a continuación

1 de 69 Anuncio

Más Contenido Relacionado

Presentaciones para usted (20)

A los espectadores también les gustó (20)

Anuncio

Similares a JavaScript performance patterns (20)

Más de Stoyan Stefanov (20)

Anuncio

Más reciente (20)

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/

×