Writing Efficient JavaScript
  What makes JavaScript slow and what to do about it




Nicholas C. Zakas
Principal Front En...
Who's this guy?
• Principal Front End Engineer, Yahoo! Homepage
• YUI Contributor
• Author
Why slow?
We grew up
Browsers didn't
In the Beginning
Now
What's the
problem?
No compilation!*

* Humor me for now. It'll make this easier.
Browsers
won't
help
your
code!!!!
Didn't Matter Then
Didn't Matter Then
• JavaScript used for simple form validation or
  image hovers
• Slow Internet connections
   – People ...
Matters Now
Matters Now
• Ajax and Web 2.0
• More JavaScript code than ever before
• Fast Internet connections
   – People have come t...
Who will help
 your code?
Disclaimer
What follows are graphic depictions of the parts of JavaScript that
are slow. Where appropriate, the names of t...
JavaScript Performance Issues
•   Scope management
•   Data access
•   Loops
•   DOM
•   Browser limits
Scope Chains
When a Function Executes
• An execution context is created
• The context's scope chain is initialized with the
  members o...
Execution Context




Identifier Resolution
• Start at scope chain position 0
• If not found go to position 1
• Rinse, rep...
Identifier Resolution
• Local variables = fast!
• The further into the chain, the slower the
  resolution
Identifier Resolution (Reads)
                              200


                              180


                    ...
Identifer Resolution (Writes)
                               200


                               180


                  ...
Scope Chain Augmentation
• The with statement
• The catch clause of try-catch
• Both add an object to the front of the sco...
Inside of Global Function
Inside of with/catch Statement




• Local variables now in second slot
• with/catch variables now in first slot
“with statement
considered harmful”
-Douglas Crockford
Closures
• The [[Scope]] property of closures begins with at
  least two objects
• Calling the closure means three objects...
Closures
Inside of Closure
Recommendations
• Store out-of-scope variables in local variables
   – Especially global variables
• Avoid the with statem...
JavaScript Performance Issues
•   Scope management
•   Data access
•   Loops
•   DOM
•   Browser limits
Places to Access Data
•   Literal value
•   Variable
•   Object property
•   Array item
Data Access Performance
• Accessing data from a literal or a local variable is
  fastest
   – The difference between liter...
Data Access
                              100


                              90


                              80


    ...
Property Depth
• object.name < object.name.name
• The deeper the property, the longer it takes to
  retrieve
Property Depth (Reads)
                              250




                              200


                         ...
Property Notation
• Difference between object.name and
  object[“name”]?
  – Generally no
  – Exception: Dot notation is f...
Recommendations
• Store these in a local variable:
   – Any object property accessed more than once
   – Any array item ac...
-5%   -10%   -33%
JavaScript Performance Issues
•   Scope management
•   Data Access
•   Loops
•   DOM
•   Browser limits
Loops
• ECMA-262, 3rd Edition:
  –   for
  –   for-in
  –   do-while
  –   while
• ECMA-357, 2nd Edition:
  – for each
Which loop?
It doesn't matter!
What Does Matter?
• Amount of work done per iteration
   – Includes terminal condition evaluation and
     incrementing/de...
Fixing Loops
• Decrease amount of work per iteration
• Decrease number of iterations
Easy Fixes
• Eliminate object property/array item lookups
Easy Fixes
• Eliminate object property/array item lookups
• Combine control condition and control variable
  change
   – W...
Two evaluations:
j < len
j < len == true
One evaluation
j-- == true




                 -50%
Easy Fixes
• Eliminate object property/array item lookups
• Combine control condition and control variable
  change
   – W...
Things to Avoid for Speed
• ECMA-262, 3rd Edition:
   – for-in
               nd
• ECMA-357, 2 Edition:
   – for each
• EC...
• Introduces additional function
• Function requires execution (execution context
  created, destroyed)
• Function also cr...
JavaScript Performance Issues
•   Scope management
•   Data Access
•   Loops
•   DOM
•   Browser limits
DOM
HTMLCollection
HTMLCollection Objects
• document.images, document.forms,
  etc.
• getElementsByTagName()
• getElementsByClassName()
Note: Collections in the HTML DOM are assumed to be live
meaning that they are automatically updated when the underlying
 ...
Infinite Loop!
HTMLCollection Objects
• Look like arrays, but aren't
   – Bracket notation
   – length property
• Represent the results o...
15x   53x   68x
=   =   =
HTMLCollection Objects
• Minimize property access
   – Store length, items in local variables if used frequently
• If you ...
function array(items){
    try {
        return Array.prototype.slice.call(items);
    } catch (ex){
        var i      = ...
Repaint & Reflow
Repaint...is what happens
whenever something is made
visible when it was not
previously visible, or vice
versa, without al...
When Repaint?
• Change to visibility
• Formatting styles changed
  –   Backgrounds
  –   Borders
  –   Colors
  –   Anythi...
Reflow is the process by
which the geometry of the
layout engine's formatting
objects are computed.
           - Chris Wat...
When Reflow?
•   Initial page load
•   Browser window resize
•   DOM nodes added or removed
•   Layout styles applied
•   ...
Addressing Repaint & Reflow
• Perform DOM changes off-document
• Groups style changes
• Cache retrieved layout information
Reflow!
Off-Document Operations
• Fast because there's no repaint/reflow
• Techniques:
   – Remove element from the document, make...
DocumentFragment
• A document-like object
• Not visually represented
• Considered to be owned by the document from
  which...
No
      reflow!


Reflow!
Addressing Repaint & Reflow
• Perform DOM changes off-document
• Group style changes
• Cache retrieved layout information
Repaint!      Reflow!


                        Reflow!




           Repaint!
What to do?
• Minimize changes on style property
• Define CSS class with all changes and just
  change className property
...
Reflow!
Reflow!
Addressing Repaint & Reflow
• Perform DOM changes off-document
• Group style changes
• Cache retrieved layout information
...
Reflow?
              Reflow?




    Reflow?
What to do?
• Minimize access to layout information
• If a value is used more than once, store in local
  variable
Speed Up Your DOM
•   Be careful using HTMLCollection objects
•   Perform DOM manipulations off the document
•   Group CSS...
JavaScript Performance Issues
•   Scope management
•   Data Access
•   Loops
•   DOM
•   Browser limits
Call Stack   Runaway Timer
Call Stack
• Controls how many functions can be executed in
  a single process
• Varies depending on browser and JavaScrip...
Note: Internet Explorer changes call stack size based on available memory
Call Stack Overflow
• Error messages
  –   IE: “Stack overflow at line x”
  –   Firefox: “Too much recursion”
  –   Safari...
Runaway Script Timer
• Designed to prevent the browser from affecting
  the operating system
• Limits the amount of time a...
Internet Explorer
Firefox
Safari
Chrome
Runaway Script Timer Limits
• Internet Explorer: 5 million statements
• Firefox: 10 seconds
• Safari: 5 seconds
• Chrome: ...
The Browser UI Thread
• Shared between JavaScript and UI updates
• Only one can happen at a time
• Page UI frozen while Ja...
Browser Limit Causes
• Too much DOM interaction
  – Repaint & reflow
• Too much recursion
• Long-running loops
Recursion Pattern #1
Recursion Pattern #2
Recursion Solutions
• Iteration
Recursion Solutions
• Iteration
• Memoization
Browser Limit Causes
• Too much DOM interaction
  – Repaint & reflow
• Too much recursion
• Long-running loops
  – Too muc...
setTimeout()
• Schedules a task to be added to the UI queue later
• Can be used to yield the UI thread
• Timer functions b...
Loops
galore!
Just do
      one pass




 Defer
the rest
Avoiding Browser Limits
• Mind your DOM
  – Limit repaint/reflow
• Mind your recursion
  – Consider iteration or memoizati...
Will it be like this forever?
No
Browsers With Optimizing Engines
•   Chrome (V8)
•   Safari 4+ (Nitro)
•   Firefox 3.5+ (TraceMonkey)
•   Opera 10? 11? (C...
Summary
Questions?
Etcetera
• My blog:    www.nczonline.net
• My email:   nzakas@yahoo-inc.com
• Twitter:    @slicknet
Creative Commons Images Used
•   http://www.flickr.com/photos/neogabox/3367815587/
•   http://www.flickr.com/photos/lydz/3...
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Writing Efficient JavaScript
Upcoming SlideShare
Loading in...5
×

Writing Efficient JavaScript

61,071

Published on

JavaScript is filled with things that make it slow. Learn what they are and how to deal with them.

Published in: Technology
6 Comments
183 Likes
Statistics
Notes
No Downloads
Views
Total Views
61,071
On Slideshare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
2,010
Comments
6
Likes
183
Embeds 0
No embeds

No notes for slide

Writing Efficient JavaScript

  1. 1. Writing Efficient JavaScript What makes JavaScript slow and what to do about it Nicholas C. Zakas Principal Front End Engineer, Yahoo! Velocity – June 2009
  2. 2. Who's this guy? • Principal Front End Engineer, Yahoo! Homepage • YUI Contributor • Author
  3. 3. Why slow?
  4. 4. We grew up
  5. 5. Browsers didn't
  6. 6. In the Beginning
  7. 7. Now
  8. 8. What's the problem?
  9. 9. No compilation!* * Humor me for now. It'll make this easier.
  10. 10. Browsers won't help your code!!!!
  11. 11. Didn't Matter Then
  12. 12. Didn't Matter Then • JavaScript used for simple form validation or image hovers • Slow Internet connections – People expected to wait • Click-and-go model • Each page contained very little code
  13. 13. Matters Now
  14. 14. Matters Now • Ajax and Web 2.0 • More JavaScript code than ever before • Fast Internet connections – People have come to expect speed • Applications that stay open for a long time – Gmail – Facebook • Download and execute more code as you interact
  15. 15. Who will help your code?
  16. 16. Disclaimer What follows are graphic depictions of the parts of JavaScript that are slow. Where appropriate, the names of the offenders have been changed to protect their identities. All of the data, unless otherwise noted, is for the browsers that are being used by the majority of web users right now, in 2009. The techniques presented herein will remain valid at least for the next 2-3 years. None of the techniques will have to be reversed once browsers with super powers are the norm and handle all optimizations for us. You should not take the techniques addressed in this presentation as things you should do all of the time. Measure your performance first, find the bottlenecks, then apply the appropriate techniques to help your specific bottlenecks. Premature optimization is fruitless and should be avoided at all costs.
  17. 17. JavaScript Performance Issues • Scope management • Data access • Loops • DOM • Browser limits
  18. 18. Scope Chains
  19. 19. 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
  20. 20. Execution Context Identifier Resolution • Start at scope chain position 0 • If not found go to position 1 • Rinse, repeat
  21. 21. Identifier Resolution • Local variables = fast! • The further into the chain, the slower the resolution
  22. 22. Identifier Resolution (Reads) 200 180 160 140 Firefox 3 Time (ms) per 200,000 reads Firefox 3.5 Beta 4 120 Chrome 1 Chrome 2 Internet Explorer 7 100 Internet Explorer 8 Opera 9.64 80 Opera 10 Beta Safari 3.2 Safari 4 60 40 20 0 1 2 3 4 5 6 Identifier Depth
  23. 23. Identifer Resolution (Writes) 200 180 160 140 Firefox 3 Time (ms) per 200,000 writes Firefox 3.5 Beta 4 120 Chrome 1 Chrome 2 Internet Explorer 7 100 Internet Explorer 8 Opera 9.64 80 Opera 10 Beta Safari 3.2 Safari 4 60 40 20 0 1 2 3 4 5 6 Identifier Depth
  24. 24. Scope Chain Augmentation • The with statement • The catch clause of try-catch • Both add an object to the front of the scope chain
  25. 25. Inside of Global Function
  26. 26. Inside of with/catch Statement • Local variables now in second slot • with/catch variables now in first slot
  27. 27. “with statement considered harmful” -Douglas Crockford
  28. 28. Closures • The [[Scope]] property of closures begins with at least two objects • Calling the closure means three objects in the scope chain (minimum)
  29. 29. Closures
  30. 30. Inside of Closure
  31. 31. 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
  32. 32. JavaScript Performance Issues • Scope management • Data access • Loops • DOM • Browser limits
  33. 33. Places to Access Data • Literal value • Variable • Object property • Array item
  34. 34. 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
  35. 35. 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.5 Chrome 1 Chrome 2 Internet Internet Opera 9.64 Opera 10 Safari 3.2 Safari 4 Beta 4 Explorer 7 Explorer 8 Beta
  36. 36. Property Depth • object.name < object.name.name • The deeper the property, the longer it takes to retrieve
  37. 37. Property Depth (Reads) 250 200 Firefox 3 Time (ms) per 200,000 reads Firefox 3.5 Beta 4 150 Chrome 1 Chrome 2 Internet Explorer 7 Internet Explorer 8 Opera 9.64 100 Opera 10 Beta Safari 3.2 Safari 4 50 0 1 2 3 4 Property Depth
  38. 38. Property Notation • Difference between object.name and object[“name”]? – Generally no – Exception: Dot notation is faster in Safari
  39. 39. 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
  40. 40. -5% -10% -33%
  41. 41. JavaScript Performance Issues • Scope management • Data Access • Loops • DOM • Browser limits
  42. 42. Loops • ECMA-262, 3rd Edition: – for – for-in – do-while – while • ECMA-357, 2nd Edition: – for each
  43. 43. Which loop?
  44. 44. It doesn't matter!
  45. 45. 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
  46. 46. Fixing Loops • Decrease amount of work per iteration • Decrease number of iterations
  47. 47. Easy Fixes • Eliminate object property/array item lookups
  48. 48. Easy Fixes • Eliminate object property/array item lookups • Combine control condition and control variable change – Work avoidance!
  49. 49. Two evaluations: j < len j < len == true
  50. 50. One evaluation j-- == true -50%
  51. 51. Easy Fixes • Eliminate object property/array item lookups • Combine control condition and control variable change – Work avoidance!
  52. 52. 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()
  53. 53. • Introduces additional function • Function requires execution (execution context created, destroyed) • Function also creates additional object in scope chain 8x
  54. 54. JavaScript Performance Issues • Scope management • Data Access • Loops • DOM • Browser limits
  55. 55. DOM
  56. 56. HTMLCollection
  57. 57. HTMLCollection Objects • document.images, document.forms, etc. • getElementsByTagName() • getElementsByClassName()
  58. 58. Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
  59. 59. Infinite Loop!
  60. 60. 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
  61. 61. 15x 53x 68x
  62. 62. = = =
  63. 63. 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
  64. 64. 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; }
  65. 65. Repaint & Reflow
  66. 66. Repaint...is what happens whenever something is made visible when it was not previously visible, or vice versa, without altering the layout of the document. - Mark 'Tarquin' Wilton-Jones, Opera
  67. 67. When Repaint? • Change to visibility • Formatting styles changed – Backgrounds – Borders – Colors – Anything that doesn't change the size, shape, or position of the element but does change its appearance • When a reflow occurs
  68. 68. Reflow is the process by which the geometry of the layout engine's formatting objects are computed. - Chris Waterson, Mozilla
  69. 69. When Reflow? • Initial page load • Browser window resize • DOM nodes added or removed • Layout styles applied • Layout information retrieved
  70. 70. Addressing Repaint & Reflow • Perform DOM changes off-document • Groups style changes • Cache retrieved layout information
  71. 71. Reflow!
  72. 72. Off-Document Operations • Fast because there's no repaint/reflow • Techniques: – Remove element from the document, make changes, insert back into document – Set element's display to “none”, make changes, set display back to default – Build up DOM changes on a DocumentFragment then apply all at once
  73. 73. DocumentFragment • A document-like object • Not visually represented • Considered to be owned by the document from which it was created • When passed to appendChild(), appends all of its children rather than itself
  74. 74. No reflow! Reflow!
  75. 75. Addressing Repaint & Reflow • Perform DOM changes off-document • Group style changes • Cache retrieved layout information
  76. 76. Repaint! Reflow! Reflow! Repaint!
  77. 77. What to do? • Minimize changes on style property • Define CSS class with all changes and just change className property • Set cssText on the element directly
  78. 78. Reflow!
  79. 79. Reflow!
  80. 80. Addressing Repaint & Reflow • Perform DOM changes off-document • Group style changes • Cache retrieved layout information – Reflow may be cached
  81. 81. Reflow? Reflow? Reflow?
  82. 82. What to do? • Minimize access to layout information • If a value is used more than once, store in local variable
  83. 83. Speed Up Your DOM • Be careful using HTMLCollection objects • Perform DOM manipulations off the document • Group CSS changes to minimize repaint/reflow • Be careful when accessing layout information
  84. 84. JavaScript Performance Issues • Scope management • Data Access • Loops • DOM • Browser limits
  85. 85. Call Stack Runaway Timer
  86. 86. Call Stack • Controls how many functions can be executed in a single process • Varies depending on browser and JavaScript engine • Errors occur when call stack size is exceeded
  87. 87. Note: Internet Explorer changes call stack size based on available memory
  88. 88. Call Stack Overflow • Error messages – IE: “Stack overflow at line x” – Firefox: “Too much recursion” – Safari: “Maximum call stack size exceeded.” – Opera: “Abort (control stack overflow)” – Chrome: n/a • Browsers throw a regular JavaScript error when this occurs – Exception: Opera just aborts the script
  89. 89. Runaway Script Timer • Designed to prevent the browser from affecting the operating system • Limits the amount of time a script is allowed to execute • Two types of limits: – Execution time – Number of statements • Always pops up a scary dialog to the user • Exception: Opera has no runaway timer
  90. 90. Internet Explorer
  91. 91. Firefox
  92. 92. Safari
  93. 93. Chrome
  94. 94. Runaway Script Timer Limits • Internet Explorer: 5 million statements • Firefox: 10 seconds • Safari: 5 seconds • Chrome: Unknown, hooks into normal crash control mechanism • Opera: none
  95. 95. The Browser UI Thread • Shared between JavaScript and UI updates • Only one can happen at a time • Page UI frozen while JavaScript is executing • A queue of actions is kept containing what to do next
  96. 96. Browser Limit Causes • Too much DOM interaction – Repaint & reflow • Too much recursion • Long-running loops
  97. 97. Recursion Pattern #1
  98. 98. Recursion Pattern #2
  99. 99. Recursion Solutions • Iteration
  100. 100. Recursion Solutions • Iteration • Memoization
  101. 101. Browser Limit Causes • Too much DOM interaction – Repaint & reflow • Too much recursion • Long-running loops – Too much per iteration – Too many iterations – Lock up the browser UI
  102. 102. setTimeout() • Schedules a task to be added to the UI queue later • Can be used to yield the UI thread • Timer functions begin with a new call stack • Extremely useful for avoiding browser limits
  103. 103. Loops galore!
  104. 104. Just do one pass Defer the rest
  105. 105. Avoiding Browser Limits • Mind your DOM – Limit repaint/reflow • Mind your recursion – Consider iteration or memoization • Mind your loops – Keep small, sprinkle setTimeout() liberally if needed
  106. 106. Will it be like this forever?
  107. 107. No
  108. 108. 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.
  109. 109. Summary
  110. 110. Questions?
  111. 111. Etcetera • My blog: www.nczonline.net • My email: nzakas@yahoo-inc.com • Twitter: @slicknet
  112. 112. Creative Commons Images Used • http://www.flickr.com/photos/neogabox/3367815587/ • http://www.flickr.com/photos/lydz/3355198458/ • http://www.flickr.com/photos/37287477@N00/515178157/ • http://www.flickr.com/photos/ottoman42/455242/ • http://www.flickr.com/photos/hippie/2406411610/ • http://www.flickr.com/photos/flightsaber/2204113449/ • http://www.flickr.com/photos/crumbs/2702429363/ • http://www.flickr.com/photos/oberazzi/318947873/ • http://www.flickr.com/photos/vox_efx/2912195591/ • http://www.flickr.com/photos/fornal/385054886/ • http://www.flickr.com/photos/29505605@N08/3198765320/ • http://www.flickr.com/photos/torley/2361164281/ • http://www.flickr.com/photos/rwp-roger/171490824/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×