Speed Up Your JavaScript

31,068 views
30,623 views

Published on

Describes common JavaScript performance issues and how to work around them.

Published in: Technology
5 Comments
85 Likes
Statistics
Notes
  • Nicholas C.Zakas
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • You're welcome. I've actually been trying to figure out if there's a way to automatically detect stuff like this, but it would get a level of the JS engine that is way out of my realm of knowledge. :)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Gotcha. It's certainly hard to estimate how many scope chain hops you have in your entire application. :)

    Thanks for the detail.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • What we're talking about here is really orders of magnitude. My tests involved using a single variable for a single operation. Images statements that are using multiple variables at the same time in a large web application with millions of lines of code. If you do anything a small enough number of times, the performance impact gets minimized. It's when you multiply it out that you start to see issues.

    Another interesting note is that times have only gotten reasonable recently. I had to remove IE6 and FF2 from the graph because it distorted the rest of the data. This shows that browsers are going in the right direction, we're just not quite there yet.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • I've often wondered about scope chain traversing. It's mentioned in a number of javascript optimization recommendations, but I hadn't seen any data on it until here (slides 17-18).
    So if this data is over 200,000 iterations, and the worst delta is 20ms for 1 chain traverse, then we're looking at ~0.0001ms per. Right?

    And really only IE that has a measurable difference. I guess I'm not convinced yet that this has much impact. :/
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
31,068
On SlideShare
0
From Embeds
0
Number of Embeds
1,811
Actions
Shares
0
Downloads
1,012
Comments
5
Likes
85
Embeds 0
No embeds

No notes for slide

Speed Up Your JavaScript

  1. 1. Speed Up Your JavaScript Nicholas C. Zakas Principal Front End Engineer, Yahoo! x Web E ponents – June 4, 2009
  2. 2. Who's this guy? • Principal Front End Engineer, Yahoo! Homepage • YUI Contributor • Author
  3. 3. Why slow?
  4. 4. Bad compilation?
  5. 5. No
  6. 6. No compilation!* * Humor me for now. It'll make this easier.
  7. 7. Browsers won't help your code!!!!
  8. 8. Who will help your code?
  9. 9. JavaScript Performance Issues • Scope management • Data access • Loops • DOM
  10. 10. Scope Chains
  11. 11. When a Function Executes • An execution context is created • The context's scope chain is initialized with the members of the function's [[Scope]] collection • An activation object is created containing all local variables • The activation object is pushed to the front of the context's scope chain
  12. 12. Execution Context Identifier Resolution • Start at scope chain position 0 • If not found go to position 1 • Rinse, repeat
  13. 13. Identifier Resolution • Local variables = fast! • The further into the chain, the slower the resolution
  14. 14. Identifier Resolution (Reads) 200 180 160 140 Firefox 3 Time (ms) per 200,000 reads Firefox 3.1 Beta 3 120 Chrome 1 Chrome 2 Beta Internet Explorer 7 100 Internet Explorer 8 Opera 9.64 80 Opera 10 Alpha Safari 3.2 Safari 4 Beta 60 40 20 0 1 2 3 4 5 6 Identifier Depth
  15. 15. Identifier Resolution (Writes) 200 180 160 140 Firefox 3 Time (ms) per 200,000 writes Firefox 3.1 Beta 3 120 Chrome 1 Chrome 2 Beta Internet Explorer 7 100 Internet Explorer 8 Opera 9.64 80 Opera 10 Alpha Safari 3.2 Safari 4 Beta 60 40 20 0 1 2 3 4 5 6 Identifier Depth
  16. 16. Scope Chain Augmentation • The with statement • The catch clause of try-catch • Both add an object to the front of the scope chain
  17. 17. Inside of Global Function
  18. 18. Inside of with/catch Statement • Local variables now in second slot • with variables now in first slot
  19. 19. “with statement considered harmful” -Douglas Crockford
  20. 20. Closures • The [[Scope]] property of closures begins with two objects • Calling the closure means three objects in the scope chain (minimum)
  21. 21. Closures
  22. 22. Inside of Closure
  23. 23. Recommendations • Store out-of-scope variables in local variables – Especially global variables • Avoid the with statement – Adds another object to the scope chain, so local function variables are now one step away – Use local variables instead • Be careful with try-catch – The catch clause also augments the scope chain • Use closures sparingly • Don't forget var when declaring variables
  24. 24. JavaScript Performance Issues • Scope management • Data access • Loops • DOM
  25. 25. Places to Access Data • Literal value • Variable • Object property • Array item
  26. 26. Data Access Performance • Accessing data from a literal or a local variable is fastest – The difference between literal and local variable is negligible in most cases • Accessing data from an object property or array item is more expensive – Which is more expensive depends on the browser
  27. 27. Data Access 100 90 80 70 Time (ms) per 200,000 reads 60 Literal Local Variable 50 Array Item Object Property 40 30 20 10 0 Firefox 3 Firefox 3.1 Chrome 1 Chrome 2 Internet Internet Opera 9.64 Opera 10 Safari 3.2 Safari 4 Beta 3 Beta Explorer 7 Explorer 8 Alpha Beta
  28. 28. Property Depth • object.name < object.name.name • The deeper the property, the longer it takes to retrieve
  29. 29. Property Depth 250 200 Firefox 3 Time (ms) per 200,000 reads Firefox 3.1 Beta 3 150 Chrome 1 Chrome 2 Beta Internet Explorer 7 Internet Explorer 8 Opera 9.64 100 Opera 10 Alpha Safari 3.2 Safari 4 Beta 50 0 1 2 3 4 Property Depth
  30. 30. Property Notation • Difference between object.name and object[“name”]? – Generally no – Exception: Dot notation is faster in Safari
  31. 31. Recommendations • Store these in a local variable: – Any object property accessed more than once – Any array item accessed more than once • Minimize deep object property/array item lookup
  32. 32. -5% -10% -33%
  33. 33. JavaScript Performance Issues • Scope management • Data Access • Loops • DOM
  34. 34. Loops • ECMA-262, 3rd Edition: – for – for-in – do-while – while • ECMA-357, 2nd Edition: – for each
  35. 35. Which loop?
  36. 36. It doesn't matter!
  37. 37. What Does Matter? • Amount of work done per iteration – Includes terminal condition evaluation and incrementing/decrementing • Number of iterations • These don't vary by loop type
  38. 38. Fixing Loops • Decrease amount of work per iteration • Decrease number of iterations
  39. 39. Easy Fixes • Eliminate object property/array item lookups
  40. 40. Easy Fixes • Eliminate object property/array item lookups • Combine control condition and control variable change – Work avoidance!
  41. 41. Two evaluations: j < len j < len == true
  42. 42. One evaluation j-- == true -50%
  43. 43. Easy Fixes • Eliminate object property/array item lookups • Combine control condition and control variable change – Work avoidance!
  44. 44. Things to Avoid for Speed • ECMA-262, 3rd Edition: – for-in nd • ECMA-357, 2 Edition: – for each • ECMA-262, 5th Edition: – array.forEach() • Function-based iteration: – jQuery.each() – Y.each() – $each – Enumerable.each()
  45. 45. • Introduces additional function • Function requires execution (execution context created, destroyed) • Function also creates additional object in scope chain 8x
  46. 46. JavaScript Performance Issues • Scope management • Data Access • Loops • DOM
  47. 47. DOM
  48. 48. HTMLCollection
  49. 49. HTMLCollection Objects • document.images, document.forms, etc. • getElementsByTagName() • getElementsByClassName()
  50. 50. Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
  51. 51. Infinite Loop!
  52. 52. HTMLCollection Objects • Look like arrays, but aren't – Bracket notation – length property • Represent the results of a specific query • The query is re-run each time the object is accessed – Include accessing length and specific items – Much slower than accessing the same on arrays – Exceptions: Opera, Safari
  53. 53. 15x 53x 68x
  54. 54. = = =
  55. 55. HTMLCollection Objects • Minimize property access – Store length, items in local variables if used frequently • If you need to access items in order frequently, copy into a regular array
  56. 56. function array(items){ try { return Array.prototype.slice.call(items); } catch (ex){ var i = 0, len = items.length, result = Array(len); while (i < len){ result[i] = items[i]; i++; } } return result; }
  57. 57. Reflow
  58. 58. Reflow is the process by which the geometry of the layout engine's formatting objects are computed. - Chris Waterson, Mozilla
  59. 59. When Reflow? • Initial page load • Browser window resize • DOM nodes added or removed • Layout styles applied • Layout information retrieved
  60. 60. Reflow!
  61. 61. DocumentFragment • A document-like object • Not visually represented • Considered a child of the document from which it was created • When passed to addChild(), appends all of its children rather than itself
  62. 62. No reflow! Reflow!
  63. 63. When Reflow? • Initial page load • Browser window resize • DOM nodes added or removed • Layout styles applied • Layout information retrieved
  64. 64. Reflow! Reflow! Reflow!
  65. 65. What to do? • Minimize changes on style property • Define CSS class with all changes and just change className property
  66. 66. Reflow!
  67. 67. When Reflow? • Initial page load • Browser window resize • DOM nodes added or removed • Layout styles applied • Layout information retrieved – Only if reflow is cached
  68. 68. Reflow? Reflow? Reflow?
  69. 69. What to do? • Minimize access to layout information • If a value is used more than once, store in local variable
  70. 70. Speed Up Your DOM • Be careful using HTMLCollection objects • Perform DOM manipulations off the document • Change CSS classes, not CSS styles • Be careful when accessing layout information
  71. 71. Will it be like this forever?
  72. 72. No
  73. 73. Browsers With Optimizing Engines • Chrome (V8) • Safari 4+ (Nitro) • Firefox 3.5+ (TraceMonkey) • Opera 10? 11? (Carakan) All use native code generation and JIT compiling to achieve faster JavaScript execution.
  74. 74. Hang in there!
  75. 75. Summary • Mind your scope • Local variables are your friends • Function execution comes at a cost • Keep loops small • Avoid doing work whenever possible • Minimize DOM interaction • Use a good browser and encourage others to do the same
  76. 76. Questions?
  77. 77. Etcetera • My blog: www.nczonline.net • My email: nzakas@yahoo-inc.com • Twitter: @slicknet
  78. 78. Creative Commons Images Used • http://www.flickr.com/photos/blackbutterfly/3051019058/ • http://www.flickr.com/photos/23816315@N07/2528296337/ • http://www.flickr.com/photos/37287477@N00/515178157/ • http://www.flickr.com/photos/ottoman42/455242/ • http://www.flickr.com/photos/crumbs/2702429363/ • http://flickr.com/photos/oberazzi/318947873/

×