javascript: the good parts part six: ajax performance douglas crockford [email protected]

46
JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford [email protected]

Upload: samantha-mcgrath

Post on 26-Mar-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

JavaScript: The Good Parts

Part Six: Ajax Performance

Douglas Crockford

[email protected]

Page 2: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Memento

Page 3: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Sessionless Web

• Cookies for pseudosessions.

• Cookies enable CSRF attacks.

• Every action results in a page replacement.

• Pages are heavy, complicated, multipart things.

• The web is a big step backwards in individual productivity.

Page 4: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

“When your only tool is a hammer, every problem looks like a webpage.”

Page 5: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Ajax Revolution

The page is an application with a data connection to a

server.

Page 6: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

When the user does something, we send a JSON message to the server, and receive a JSON message as

the result.

Page 7: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

A JSON message is less work for the server to

generate, moves faster on the wire, and is less work for the browser to parse

and render than an HTML document.

Page 8: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Division of Labor

How is the application divided between the browser and the

server?

Page 9: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Pendulum of Despair

Server

The browser is a terminal.

Page 10: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Pendulum of Despair

Server Browser

The browser is a terminal

The server is a file system.

Page 11: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Seek the Middle Way.

A pleasant dialogue between specialized peers.

Page 12: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Ajaxify

• The client and server are in a dialog.

• Make the messages between them as small as possible.

• The client does not need a copy of the database. It just needs, at any moment, just enough information to serve the user.

• Don't rewrite the server application in JavaScript!

Page 13: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Poor Browser

• The browser is a very inefficient application platform.

• If your application becomes bloated, performance will be very bad.

• Try to keep the client programming light.

Page 14: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Amazingly, the browser works

• But it doesn't work well.

• It is a difficult platform to work with.

• There are significant security problems.

• There are significant performance problems.

• It was not designed to be an application delivery system.

• Ajax pushes the browser really hard.

Page 15: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Correctness First

• Do not worry about optimization until you have the application working correctly.

• If it isn’t right, it doesn’t matter that if it is fast.

• Test for performance early.

• Test in customer configurations: Slow networks, slow computers.

• Internal networks and developer-class machines can mask performance problems.

Page 16: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Premature optimization is the root of all evil. — Donald Knuth• Use YSlow to reduce startup time.

• Don't optimize until you need to, but find out as early as possible if you need to.

• Clean, correct code is easier to optimize.

• Tweaking is usually ineffective.

• Sometimes restructuring or redesign is required.

Page 17: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Example

var fibonacci = function (n) {

return n < 2 ? n :

fibonacci(n - 1) +

fibonacci(n - 2);

};

• fibonacci(40)

• Calls itself 331,160,280 times.

Page 18: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Memoizervar memoizer = function (memo, fundamental) {

var shell = function (n) {

var result = memo[n];

if (typeof result !== 'number') {

result = fundamental(shell, n);

memo[n] = result;

}

return result;

};

return shell;

};

Page 19: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Memoizer

var fibonacci =

memoizer([0, 1], function (recur, n) {

return recur(n - 1) + recur(n - 2);

});

• fibonacci(40)

• Calls itself 38 times.

• The key to optimization is work avoidance.

Page 20: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Code Quality

• High quality code is mostly likely to avoid platform problems.

• Code Conventions for the JavaScript Programming Language

• http://javascript.crockford.com/code.html

• Use JSLint.com. Pass with no warnings.

Page 21: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Have regular code readings.

• Don’t wait until release to do code reviews.

• Do team code reading regularly during development.

• Experienced developers can lead by example.

• Novice developers learn from the group.

• Problems can be discovered early.

• Good techniques can be shared early.

Page 22: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Two Kinds of Optimization

• Streamlining

Algorithm replacement

Work avoidance

Code removal

These things are always good to do

• Special Casing

Adds cruft, increases code size

Should only be done when proven necessary

Page 23: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Avoid unnecessary displays or animation.

• Everything costs.

• Wow costs.

• As the number of widgets on the page increases, overall ongoing performance gets worse.

Page 24: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Only speed up things that take a lot of time.

Speeding up things that take very little time will yield very

little improvement.

Page 25: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Only speed up things that take a lot of time.

• If profiling shows that you are spending most of your time in A, don't bother optimizing C.

A B C D

Page 26: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Improving performance

• If JavaScript were infinitely fast, most pages would run at about the same speed.

• The bottleneck tends to be the DOM interface.

• There is a significant cost every time you touch the DOM tree.

• Each touch can result in a reflow computation, which is expensive.

Page 27: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Touch lightly

• It is faster to manipulate new nodes before they are attached to the tree.

• Touching unattached nodes avoids the reflow cost.

• Setting innerHTML does an enormous amount of work, but browsers are really good at it, and it only touches the DOM once.

Page 28: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Make good use of Ajax Libraries

Effective code reuse will make widgets more effective.

Page 29: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

How IE8 Spends Its Time

• Average time allocation of the Alexa 100:

Layout 43.16% Rendering 27.25%

HTM

L 2

.81

%

Mars

halli

ng

7.3

4%

DO

M 5

.05%

Form

at

8.6

6%

JScr

ipt

3.2

3%

Oth

er

2.5

%

Page 30: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

How IE8 Spends Its Time

• Opening a thread in GMail:

Layou

t 9.4

1%

Ren

deri

ng

9.2

1%

HTM

L 1

.57

%

Mars

halli

ng

7.8

5%

DO

M 1

2.4

7%

Format 38.97%

JScr

ipt

14

.43

%

Oth

er

3.7

2%

Page 31: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Coding Efficiency

• Common subexpression removal.

• Loop invariant removal.

• Most compilers in most programming languages do these optimizations for you.

• But not JavaScript.

Page 32: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Before

var i;

for (i = 0; i < divs.length; i += 1) {

divs[i].style.color = "black";

divs[i].style.border = thickness +

'px solid blue';

divs[i].style.backgroundColor = "white";

}

Page 33: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

After

var border = thickness + 'px solid blue',

nrDivs = divs.length,

ds, i;

for (i = 0; i < nrDivs; i += 1) {

ds = divs[i].style;

ds.color = "black";

ds.border = border;

ds.backgroundColor = "white";

}

Page 34: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Strings

• Concatenation with +

Each operation allocates memory

foo = a + b;

• Concatenate with array.join('')

The contents of an array are concatenated into a single string

foo = [a, b].join('');

Page 35: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Don't Tune For Quirks

• Some browsers have surprising inefficiencies.

• A trick that is faster on Browser A might be slower on Browser B.

• The performance characteristics of the next generation may be significantly different.

• Avoid short-term optimizations.

Page 36: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

Don't Optimize Without Measuring

• Intuitions are often wrong. start_time = new Date().valueOf();

code_to_measured();

end_time = new Date().valueOf();

elapsed_time = end_time - start_time;

• A single trial is unreliable. Timers can be off by as much as 15 msec.

• Even accurate measurements can lead to wrong conclusions.

Page 37: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

O (1)

• An operation that is performed only once is not worth optimizing.

Page 38: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

O (n)

• An operation that is performed many times may be worth optimizing.

Tim

e

n

Slope: Time per Iteration

Fixed time: Startup and cleanup

Page 39: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Axis of Error

• Inefficiency

Tim

e

n

Inefficiency

Page 40: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Axis of Error

• Frustration

Tim

e

n

Frustration

Page 41: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Axis of Error

• Failure

Tim

e

n

Failure

Page 42: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

O (n)Tim

e

n

Slope: Time per Iteration

Fixed time: Startup and cleanup

Page 43: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

O (n log n)Tim

e

n

Page 44: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

O (n2)

Generally not suitable for browser applications except when n is very small.

Tim

e

n

Page 45: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The most effective way to make programs faster is to

make n smaller.Ajax allows for just-in-time

data delivery.

Page 46: JavaScript: The Good Parts Part Six: Ajax Performance Douglas Crockford douglas@crockford.com

The Wall.