博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript: Better and Faster
阅读量:5315 次
发布时间:2019-06-14

本文共 7708 字,大约阅读时间需要 25 分钟。

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.utilnot 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

other tools

  • JSLint (JavaScript syntax checker)
  • YSlow (Firebug extension)
  • Page Speed (Firebug extension)
  • Speed Tracer (Chrome extension)
  • dynaTrace AJAX (Windows program/IE plugin)

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
  • NCZOnline, by Nicholas Zakas
  • Douglas Crockford's JavaScript, by Doug Crockford
  • Perfection Kills, by @kangax (author of Prototype.js)
  • John Resig - Blog, by John Resig (creator of jQuery)
  • Software is Hard, by Jan Odvarko (Firebug developer)

this slideshow

was running in the browser, with JavaScript

  • source on GitHub at
  • available online at
  • built with ShowOff -

thanks for coming!

转载于:https://www.cnblogs.com/guopei/archive/2011/05/10/2041686.html

你可能感兴趣的文章
Python3 高阶函数
查看>>
初始面向对象
查看>>
leetcode Letter Combinations of a Phone Number
查看>>
Unity 5.4 测试版本新特性---因吹丝停
查看>>
7.5 文件操作
查看>>
MyEclipse中将普通Java项目convert(转化)为Maven项目
查看>>
node js 安装.node-gyp/8.9.4 权限 无法访问
查看>>
windows基本命令
查看>>
VMware中CentOS设置静态IP
查看>>
[poj1006]Biorhythms
查看>>
Hyper-V虚拟机上安装一个图形界面的Linux系统
查看>>
Hover功能
查看>>
js千分位处理
查看>>
Mac---------三指拖移
查看>>
字符串类型的相互转换
查看>>
HTTP状态码
查看>>
iOS如何过滤掉文本中特殊字符
查看>>
基础学习:C#中float的取值范围和精度
查看>>
MongoDB-CRUD
查看>>
javaagent 简介
查看>>