JavaScript: Better and Faster
2011-05-10 15:04
344 查看
Ben Cherry
Performance Engineer at Slide, Inc.
1.The JavaScript Language
just what you need to know to understand this talk
variables and functions
those are the only ways you should declare things
scope
JavaScript has function-level scope
hoisting
names are always hoisted to the top of their scope , and always initialized to
closure
functions have access to their original scope chain
2.Run-Time Performance common pitfalls
"namespaces"
Python
JavaScript
here's what happens
imagine that in a loop!
store that reference
this is much faster
scope chains
the slow way
faster
now
arrays
arrays
this means arrays are slower than you expect , but some browsers do optimize them
loops
for loops
for-in loops
these are slow, avoid them
this is much faster, and is preferred
arguments
much slower (up to 100x) than using parameters ,
3.Inheritance
don't use it , unless you have to , and that's all I have to say about that
modules
how to make
this a fast, reusable pattern
4.The DOM
it's absolutely terrible , but I have three simple rules to make it better
rule 1:never edit the live tree
you can detach sub-trees
or you can clone and replace
but be careful about event handlers , use
rule 2:build bottom-up
bottom-up construction
rule 3:minimize event handlers
memory leaks in IE
was that really that surprising?
unbind before removal
but that kind of sucks too
use event delegation
the new
avoid handlers in loops
this is slow!
faster
5.long-running operations
sometimes you can't avoid it
problem script
browser locks for 10s!
solution: timers
split into half-second chunks, with 20ms in between
minimum intervals
no browser really does 0ms ; Chrome is ~5ms, but IE is ~18ms ;others are ~10-12ms
6.page-load performance
getting your script running quickly
always at the bottom, so the page is not blocked
avoid inline scripts
these cannot be cached or minified , only put dynamic values here
minification
our build process does this for you , make sure you're using it!
7.Performance Tools
my JavaScript profiler
source at http://gist.github.com/322060
other tools
JSLint (JavaScript syntax checker) http://jslint.com/
YSlow (Firebug extension) http://developer.yahoo.com/yslow/
Page Speed (Firebug extension) http://code.google.com/speed/page-speed/
Speed Tracer (Chrome extension) http://code.google.com/webtoolkit/speedtracer/
dynaTrace AJAX (Windows program/IE plugin) http://ajax.dynatrace.com/pages/
8.random extras
somewhat important
never forget your radix
CSS expressions are evaluated right-to-left!
this starts by looking at every
then it looks for those whose parent is
then it checks to see if its parent is
Useful Resources
because this was not nearly exhaustive
dead trees
High Performance Web Sites, by Steve Souders (Yahoo!, at the time)
Even Faster Web Sites, by Steve Souders (Google, now)
JavaScript: The Good Parts, by Douglas Crockford (Yahoo!)
High Performance JavaScript, by Nicholas Zakas (Yahoo!) (coming soon)
Secrets of the JavaScript Ninja, by John Resig (Mozilla/jQuery) (coming soon)
blogs
High Performance Web Sites, by Steve Souders http://www.stevesouders.com/blog/
NCZOnline, by Nicholas Zakas http://www.nczonline.net/blog/
Douglas Crockford's JavaScript, by Doug Crockford http://javascript.crockford.com/
Perfection Kills, by @kangax http://perfectionkills.com/ (author of Prototype.js)
John Resig - Blog, by John Resig http://ejohn.org/blog/ (creator of jQuery)
Software is Hard, by Jan Odvarko http://www.softwareishard.com/blog/ (Firebug developer)
this slideshow
was running in the browser, with JavaScript
source on GitHub at http://github.com/bcherry/js-better-faster
available online at http://bcherry.net/talks/js-better-faster
built with ShowOff - http://github.com/schacon/showoff
Performance Engineer at Slide, Inc.
1.The JavaScript Language
just what you need to know to understand this talk
variables and functions
var foo = 1; // variable statement function bar() {} // function statement (function baz() {}); // function expression (function (spam) {}(1)); // function parameter
those are the only ways you should declare things
scope
var foo = 1; (function () { var baz = 2; foo = 3; }()); alert(foo); // 3 alert(baz); // ReferenceError
JavaScript has function-level scope
hoisting
var foo = 1; (function () { alert(foo); // undefined var foo = 2; }()); alert(foo); // 1
names are always hoisted to the top of their scope , and always initialized to
undefined
closure
var foo = (function () { var bar = 5; return function () { alert(bar); }; }()); foo(); // 5 setTimeout(foo, 10000); // 5, 10s later
functions have access to their original scope chain
2.Run-Time Performance common pitfalls
"namespaces"
Python
import bc.util bc.util.some_function() //# this is quite fast
JavaScript
BC.util.someFunction(); //but this is very slow
here's what happens
BC.util.someFunction(); // lookup BC // resolve property util // resolve property someFunction // execute function
imagine that in a loop!
store that reference
var some_function = BC.util.some_function,i; for (i = 0; i < 1000000; i += 1) { some_function(); }
this is much faster
scope chains
the slow way
var foo = 1; function bar() { var i; for (i = 0; i < 10000; i += 1) { alert(foo); } } bar();
foois one step down the chain
faster
var foo = 1; function bar() { var myFoo = foo, i; for (i = 0; i < 10000; i += 1) { alert(myFoo); } } bar();
now
myFoois on the end of the chain
arrays
arrays
var a = []; typeof a; // "object" a.length; // 0 a[10] = 1; a.length; // 11 a["something_else"] = 1; a.something_else; // 1 a.length; // 11
this means arrays are slower than you expect , but some browsers do optimize them
loops
for loops
// slow method var i; for (i = 0; i < someArray.length; i += 1) { // ... } // faster var i, l; for (i = 0, l = someArray.length; i < l; i += 1) { // ... }
for-in loops
var key; for (key in someObject) { // ... }
these are slow, avoid them
var keys = ["foo", "bar", "baz"], i, l, key; for (i = 0, l = keys.length; i < l; i += 1) { key = keys[key]; // ... someObject[key] ... }
this is much faster, and is preferred
arguments
function foo() { return arguments[0]; } foo(1); // 1
much slower (up to 100x) than using parameters ,
argumentsshould be avoided if possible
3.Inheritance
don't use it , unless you have to , and that's all I have to say about that
modules
how to make
BC.util? not the same as inheritance
BC.util = (function (BC) { var util = {},foo; // private variable // public util.someFunction = function(){}; // private function someOther(){} return util; }(BC));
this a fast, reusable pattern
4.The DOM
it's absolutely terrible , but I have three simple rules to make it better
rule 1:never edit the live tree
you can detach sub-trees
var elem = $("#myelem"), parent = elem.parent(); elem.detach(); // ... muck with elem and sub-elements ... parent.append(elem);
.detach()is new in jQuery 1.4
or you can clone and replace
var old = $("#myelem"), clone = old.clone(); // ... muck with the clone ... old.replaceWith(clone);
but be careful about event handlers , use
.clone(true)to preserve them
rule 2:build bottom-up
bottom-up construction
var child = document.createElement("div"), parent = document.createElement("div"), grand = document.createElement("div"); parent.appendChild(child); grand.appendChild(parent); document.body.appendChild(grand);
rule 3:minimize event handlers
memory leaks in IE
$(".myelems").bind("click", function () {/* ... */}); // ... $(".myelems").remove(); // aww snap, memory leak!
was that really that surprising?
unbind before removal
$(".myelems").unbind("click").remove(); // phew!
but that kind of sucks too
use event delegation
$(".myelems").live("click", function () {/* ... */}); $(".myelems").remove(); $("<div/>").addClass("myelems").appendTo($("body"))
the new
<div>gets the handler for free
avoid handlers in loops
function makeElem(id) { return $("<div/>").attr("id", id).click(function () { alert($(this).attr("id")); }); } var i; for (i = 0; i < 1000; i += 1) { someParent.append(makeElem(i)); }
this is slow!
faster
function handler() { alert(this.attr("id")); } function makeElem(id) { return $("<div/>").attr("id", i).click(handler); } var i; for (i = 0; i < 1000; i += 1) { someParent.append(makeElem(i)); }
5.long-running operations
sometimes you can't avoid it
problem script
var i; for (i = 0; i < 10000; i += 1) { oneMillisecondOperation(i); }
browser locks for 10s!
solution: timers
var i = 0; setTimeout(function iterate() { var stop = i + 500; for (; i < stop; i += 1) { oneMillisecondOperation(i); } setTimeout(iterate, 20); }, 0);
split into half-second chunks, with 20ms in between
minimum intervals
setTimeout(function () { alert("foo"); }, 0); // how long until "foo"?
no browser really does 0ms ; Chrome is ~5ms, but IE is ~18ms ;others are ~10-12ms
6.page-load performance
getting your script running quickly
<html> <head></head> <body> <!-- all scripts at the bottom of <body>--> <script></script> </body> </html>
always at the bottom, so the page is not blocked
avoid inline scripts
<script> function foo() { // ... } </script>
these cannot be cached or minified , only put dynamic values here
minification
function foo() { var bar = 1; return bar + 5; }
function foo(){var a=1;return a+5}
our build process does this for you , make sure you're using it!
7.Performance Tools
my JavaScript profiler
var profiler = performance.newProfiler(); function foo() { profiler.begin("body"); // ... some operations ... profiler.end("body"); } // ... repeated calls to foo() ... profiler.report(); // alerts time spent in "body
source at http://gist.github.com/322060
other tools
JSLint (JavaScript syntax checker) http://jslint.com/
YSlow (Firebug extension) http://developer.yahoo.com/yslow/
Page Speed (Firebug extension) http://code.google.com/speed/page-speed/
Speed Tracer (Chrome extension) http://code.google.com/webtoolkit/speedtracer/
dynaTrace AJAX (Windows program/IE plugin) http://ajax.dynatrace.com/pages/
8.random extras
somewhat important
parseIntneeds radix!
parseInt("123"); // 123 parseInt("10"); // 10 parseInt("010"); // 8 -> WTF? // with a radix parseInt("010", 10); // 10 -> crisis averted!
never forget your radix
sorthas issues
var a = [3,1,2]; a.sort(); // [1,2,3] a = [10,1,2]; a.sort(); // [1,10,2] - f**ing javascript! a.sort(betterComparison); // [1,2,10]
.sort()sorts alphabetically , write your own comparison function
CSS expressions are evaluated right-to-left!
#foo div a {/* ... */}
this starts by looking at every
<a>
then it looks for those whose parent is
<div>
then it checks to see if its parent is
#foo
Useful Resources
because this was not nearly exhaustive
dead trees
High Performance Web Sites, by Steve Souders (Yahoo!, at the time)
Even Faster Web Sites, by Steve Souders (Google, now)
JavaScript: The Good Parts, by Douglas Crockford (Yahoo!)
High Performance JavaScript, by Nicholas Zakas (Yahoo!) (coming soon)
Secrets of the JavaScript Ninja, by John Resig (Mozilla/jQuery) (coming soon)
blogs
High Performance Web Sites, by Steve Souders http://www.stevesouders.com/blog/
NCZOnline, by Nicholas Zakas http://www.nczonline.net/blog/
Douglas Crockford's JavaScript, by Doug Crockford http://javascript.crockford.com/
Perfection Kills, by @kangax http://perfectionkills.com/ (author of Prototype.js)
John Resig - Blog, by John Resig http://ejohn.org/blog/ (creator of jQuery)
Software is Hard, by Jan Odvarko http://www.softwareishard.com/blog/ (Firebug developer)
this slideshow
was running in the browser, with JavaScript
source on GitHub at http://github.com/bcherry/js-better-faster
available online at http://bcherry.net/talks/js-better-faster
built with ShowOff - http://github.com/schacon/showoff
thanks for coming!
相关文章推荐
- Web Design Toolbox: 130+ New Tools to Make You a Better and Faster Designer
- Learning JQuery: Better Interaction Design and Web Development with Simple Javascript Techniques
- vim进阶:better,faster and stronger
- Develop Better Software Faster with IBM Rational Systems Developer and IBM Rational PurifyPlus
- Make your pages load faster by combining and compressing javascript and css files
- Web Design Toolbox: 130+ New Tools to Make You a Better and Faster Designer
- How To Work Faster And Better
- Javascript Regexp match and replace
- 《JavaScript And DHTML Cookbook》学习笔记
- YOLO9000: Better, Faster, Stronger (项目主页) 的翻译
- JavaScript秘密花园 - scope, namespace, constructor, equality and comparisons
- [从jQuery看JavaScript]-匿名函数与闭包(Anonymous Function and Closure)
- 15 jQuery Plugins For A Better Photo Gallery And Slideshow
- ASYNCHRONOUS JAVASCRIPT AND XML
- Javascript and ASP.NET DETECT Browsers
- Object Detection -- 论文YOLO2(YOLO9000:Better, Faster, Stronger)解读
- javascript调试工具:Blackbird !say "hello" to Blackbird and "goodbye" to alert().
- notice: javascript's by value and by reference
- [Javascript] Understand Function Composition By Building Compose and ComposeAll Utility Functions
- javascript 学习笔记 《JavaScript And DHTML Cookbook》2