Writing Efficient JavaScript
What makes JavaScript slow and what to do about it
Nicholas C. Zakas Principal Front End Engineer, Yahoo! Velocity – June 2009
Writing Efficient JavaScript What makes JavaScript slow and what to - - PowerPoint PPT Presentation
Writing Efficient JavaScript What makes JavaScript slow and what to do about it Nicholas C. Zakas Principal Front End Engineer, Yahoo! Velocity June 2009 Who's this guy? Principal Front End Engineer, Yahoo! Homepage YUI
Writing Efficient JavaScript
What makes JavaScript slow and what to do about it
Nicholas C. Zakas Principal Front End Engineer, Yahoo! Velocity – June 2009
Who's this guy?
In the Beginning
Now
* Humor me for now. It'll make this easier.
Browsers won't help your code!!!!
Didn't Matter Then
Didn't Matter Then
image hovers
– People expected to wait
Matters Now
Matters Now
– People have come to expect speed
– Gmail – Facebook
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
then apply the appropriate techniques to help your specific
avoided at all costs.
JavaScript Performance Issues
Scope Chains
When a Function Executes
members of the function's [[Scope]] collection
variables
context's scope chain
Execution Context
Identifier Resolution
Identifier Resolution
resolution
Identifier Resolution (Reads)
20 40 60 80 100 120 140 160 180 200 1 2 3 4 5 6 Identifier Depth Time (ms) per 200,000 reads Firefox 3 Firefox 3.5 Beta 4 Chrome 1 Chrome 2 Internet Explorer 7 Internet Explorer 8 Opera 9.64 Opera 10 Beta Safari 3.2 Safari 4Identifer Resolution (Writes)
20 40 60 80 100 120 140 160 180 200 1 2 3 4 5 6 Identifier Depth Time (ms) per 200,000 writes Firefox 3 Firefox 3.5 Beta 4 Chrome 1 Chrome 2 Internet Explorer 7 Internet Explorer 8 Opera 9.64 Opera 10 Beta Safari 3.2 Safari 4Scope Chain Augmentation
Inside of Global Function
Inside of with/catch Statement
“with statement considered harmful”
Closures
least two objects
scope chain (minimum)
Closures
Inside of Closure
Recommendations
– Especially global variables
– Adds another object to the scope chain, so local function variables are now one step away – Use local variables instead
– The catch clause also augments the scope chain
JavaScript Performance Issues
Places to Access Data
Data Access Performance
fastest
– The difference between literal and local variable is negligible in most cases
item is more expensive
– Which is more expensive depends on the browser
Data Access
10 20 30 40 50 60 70 80 90 100 Firefox 3 Firefox 3.5 Beta 4 Chrome 1 Chrome 2 Internet Explorer 7 Internet Explorer 8 Opera 9.64 Opera 10 Beta Safari 3.2 Safari 4 Time (ms) per 200,000 reads Literal Local Variable Array Item Object PropertyProperty Depth
retrieve
Property Depth (Reads)
50 100 150 200 250 1 2 3 4 Property Depth Time (ms) per 200,000 reads Firefox 3 Firefox 3.5 Beta 4 Chrome 1 Chrome 2 Internet Explorer 7 Internet Explorer 8 Opera 9.64 Opera 10 Beta Safari 3.2 Safari 4Property Notation
– Generally no – Exception: Dot notation is faster in Safari
Recommendations
– Any object property accessed more than once – Any array item accessed more than once
JavaScript Performance Issues
Loops
– for – for-in – do-while – while
– for each
What Does Matter?
– Includes terminal condition evaluation and incrementing/decrementing
Fixing Loops
Easy Fixes
Easy Fixes
change
– Work avoidance!
Two evaluations: j < len j < len == true
One evaluation j-- == true
Easy Fixes
change
– Work avoidance!
Things to Avoid for Speed
– for-in
– for each
– array.forEach()
– jQuery.each() – Y.each() – $each – Enumerable.each()
created, destroyed)
chain
8x
JavaScript Performance Issues
HTMLCollection
HTMLCollection Objects
etc.
Note: Collections in the HTML DOM are assumed to be live meaning that they are automatically updated when the underlying document is changed.
Infinite Loop!
HTMLCollection Objects
– Bracket notation – length property
accessed
– Include accessing length and specific items – Much slower than accessing the same on arrays – Exceptions: Opera, Safari
15x 68x 53x
= = =
HTMLCollection Objects
– Store length, items in local variables if used frequently
copy into a regular array
Repaint & Reflow
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.
When Repaint?
– Backgrounds – Borders – Colors – Anything that doesn't change the size, shape, or position of the element but does change its appearance
Reflow is the process by which the geometry of the layout engine's formatting
When Reflow?
Addressing Repaint & Reflow
Reflow!
Off-Document Operations
– 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
DocumentFragment
which it was created
its children rather than itself
Reflow! No reflow!
Addressing Repaint & Reflow
Repaint! Reflow! Reflow! Repaint!
What to do?
change className property
Reflow!
Reflow!
Addressing Repaint & Reflow
– Reflow may be cached
Reflow? Reflow? Reflow?
What to do?
variable
Speed Up Your DOM
JavaScript Performance Issues
Call Stack Runaway Timer
Call Stack
a single process
engine
Note: Internet Explorer changes call stack size based on available memory
Call Stack Overflow
– IE: “Stack overflow at line x” – Firefox: “Too much recursion” – Safari: “Maximum call stack size exceeded.” – Opera: “Abort (control stack overflow)” – Chrome: n/a
this occurs
– Exception: Opera just aborts the script
Runaway Script Timer
the operating system
execute
– Execution time – Number of statements
Internet Explorer
Firefox
Safari
Chrome
Runaway Script Timer Limits
control mechanism
The Browser UI Thread
Browser Limit Causes
– Repaint & reflow
Recursion Pattern #1
Recursion Pattern #2
Recursion Solutions
Recursion Solutions
Browser Limit Causes
– Repaint & reflow
– Too much per iteration – Too many iterations – Lock up the browser UI
setTimeout()
Loops galore!
Just do
Defer the rest
Avoiding Browser Limits
– Limit repaint/reflow
– Consider iteration or memoization
– Keep small, sprinkle setTimeout() liberally if needed
Will it be like this forever?
Browsers With Optimizing Engines
All use native code generation and JIT compiling to achieve faster JavaScript execution.
Questions?
Etcetera
www.nczonline.net
nzakas@yahoo-inc.com
@slicknet
Creative Commons Images Used