您的位置:首页 > Web前端 > JavaScript

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

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();


foo
is 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
myFoo
is 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 ,
arguments
should 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

parseInt
needs radix!

parseInt("123"); // 123
parseInt("10"); // 10
parseInt("010"); // 8 -> WTF?

// with a radix
parseInt("010", 10); // 10 -> crisis averted!


never forget your radix

sort
has 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!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: