Slide 1
JavaScript Performance Optimization
Ezra Parker
Online ColdFusion Meetup
December 8, 2011
no notes exist for this slide
Slide 2
Who am I?
ColdFusion developer since 2000
Independent Consultant/Contractor
Associate Director of the Model-Glue framework
Co-organizer of the ColdFusion
Unconference at Adobe MAX
cf.Objective() 2012 CAB member
no notes exist for this slide
Slide 3
Two Types of Optimization
Execution
Loading
no notes exist for this slide
Slide 4
How to Make Your JS Run Faster
To optimize or not to optimize
Profiling to detect bottlenecks
no notes exist for this slide
Slide 5
What should you optimize?
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil"
-- Donald Knuth
no notes exist for this slide
Slide 6
Profiling
Firebug, Chrome Developer Tools, etc.
Home-grown timers
www.jsperf.com
no notes exist for this slide
Slide 7
General JavaScript Optimization
Variable assignments & lookups
Looping considerations
DOM manipulation
no notes exist for this slide
Slide 8
Variable Assignments & Lookups
Local variables are fast
Object properties, array indexes, function calls etc. are slower
This is often a micro-optimization
no notes exist for this slide
Slide 9
Looping
How is not likely to be important
Focus on what the loop is doing
no notes exist for this slide
Slide 10
DOM Manipulation
Repaints and reflows
Hide containing element or detach from the DOM
Use a document fragment
Style with classes
no notes exist for this slide
Slide 11
Optimizing for jQuery
More efficient selectors
How to handle events
General tips
no notes exist for this slide
Slide 12
Selectors
Use an id where possible
Don't use classes alone
âCommonâ wisdom: descend from an id
Using find() or a context is the way to go
no notes exist for this slide
Slide 13
Select by id when possible
$('#someId')
Uses getElementById(), thus very fast
Don't use a tag prefix: $('p#someId')
no notes exist for this slide
Slide 14
Don't use just a class selector
$('.someClass')
This requires a scan of the entire DOM to find elements
Better to add a tag if possible: $('p.someClass')
Allows for filtering with getElementsByTagName()
no notes exist for this slide
Slide 15
Isn't descending from an id helpful?
$('#someId p.someClass')
DOMElement.querySelectorAll in modern browsers
Sizzle selector library
Both parse right-to-left
More specific inner selectors
$('.class1 p.class2') is better than
$('p.class2 .class1')
No point to intermediate selectors:
$('.class1 .class2 .class3')
no notes exist for this slide
Slide 16
What are contexts?
$('.someClass', context)
Implicit context is the document root
Don't use a jQuery selector or object as the context, use a DOM node instead:
var context = $('#someId')[0];
var selected = $('p', context);
Selectors can have implicit contexts:
$(':text') == $('*:text')
$('input:text') is better
no notes exist for this slide
Slide 17
Using find() instead of a context
This selector:
var context = $('#someId')[0];
var selector = $('p', context);
Is the same as this:
var selector = $('#someId').find('p');
find() is less verbose and more
readable (IMO)
no notes exist for this slide
Slide 18
Events
Favor bind() and trigger() over convenience methods
Even better: live(), particularly with a context
Better still: delegate()
As of jQuery 1.7: on()
no notes exist for this slide
Slide 19
Use bind() and trigger()
These are equivalent:
$('#id').click(someFunction);
$('#id').bind('click', someFunction);
So are these:
$('#id').click();
$('#id').trigger('click');
Convenience methods require an
additional internal function call
no notes exist for this slide
Slide 20
Using live() can be more efficient
Instead of this:
$('#id').bind('click', someFunction);
Do this:
$('#id').live('click', someFunction);
More performant when used
with a context:
var context = $('#id')[0];
$('p', context).live('click', someFunction);
no notes exist for this slide
Slide 21
Advantages and drawbacks to live()
Will bind to dynamically-created elements
Cannot be used in conjunction with DOM traversal â this won't work:
$('#id').children().live('click', someFunction);
Implicit context is document root
no notes exist for this slide
Slide 22
delegate() fixes these issues
This statement:
$('#id').delegate('p', 'click', someFunction);
Is the same as this:
var context = $('#id')[0];
$('p', context).live('click', someFunction);
Less verbose, and can be chained
after DOM traversal
no notes exist for this slide
Slide 23
General Tips
Cache jQuery objects
Test for existence
each() can be expensive
no notes exist for this slide
Slide 24
Cache jQuery objects
If you're going to use something more than once, don't select it again â do this instead:
var element = $('#id');
element.css('color', 'red');
element.show();
Not this:
$('#id').css('color', 'red');
$('#id').show();
no notes exist for this slide
Slide 25
Test for an element's existence
If your JavaScript is included on multiple pages, test for the existence of an element before acting on it:
$(function() {
var element = $('#id');
if (element.length) {
element.show();
}
});
no notes exist for this slide
Slide 26
each()
each() is convenient, but it comes at a price
If this is a bottleneck, use native JavaScript looping instead
no notes exist for this slide
Slide 27
Improving Load Times
Implementing the ySlow Guidelines
Compression: Minification & Obfuscation
Script Loading Strategies
no notes exist for this slide
Slide 28
Script loading
A complex issue â every situation is different
<script> tags block rendering
Asynchronous loading
no notes exist for this slide
Slide 29
LABjs
Simple API for asynchronous script loading:
$LAB.script('path/to/script.js');
$LAB.wait();
$LAB.wait(function() { alert('test'); });
no notes exist for this slide
Slide 30
LABjs chaining
Chaining:
$LAB.script('js/jquery.js')
.wait()
.script('js/jquery-ui.js')
.wait(function() {
$('#myButton').button();
});
no notes exist for this slide
Slide 31
Resources
jQuery Anti-Patterns for Performance by Paul Irish:
http://paulirish.com/2009/perf/
8 jQuery Micro Optimization Tips:
http://www.codenothing.com/archives/2010/8-jquery-micro-optimization-tips/
LABjs:
http://labjs.com/
Why not just concat?
http://blog.getify.com/2009/11/labjs-why-not-just-concat/
no notes exist for this slide
Slide 32
Questions?
Contact me:
Blog
www.cfgrok.com
Email
ezra@cfgrok.com
GTalk
ezra@cfgrok.com
no notes exist for this slide