Title: JavaScript:%20The%20Good%20Parts%20Part%20Six:%20Ajax%20Performance
1JavaScript The Good PartsPart Six Ajax
Performance
- Douglas Crockford
- douglas_at_crockford.com
2Memento
3The 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.
4When your only tool is a hammer, every problem
looks like a webpage.
5The Ajax Revolution
- The page is an application with a data connection
to a server.
6When the user does something, we send a JSON
message to the server, and receive a JSON message
as the result.
7A 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.
8Division of Labor
- How is the application divided between the
browser and the server?
9Pendulum of Despair
- Server
- The browser is a terminal.
10Pendulum of Despair
- Server Browser
- The browser is a terminal
- The server is a file system.
11Seek the Middle Way.
- A pleasant dialogue between specialized peers.
12Ajaxify
- 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!
13The 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.
14Amazingly, 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.
15Correctness First
- Do not worry about optimization until you have
the application working correctly. - If it isnt right, it doesnt 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.
16Premature 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.
17Example
- var fibonacci function (n)
- return n lt 2 ? n
- fibonacci(n - 1)
- fibonacci(n - 2)
-
- fibonacci(40)
- Calls itself 331,160,280 times.
18Memoizer
- var memoizer function (memo, fundamental)
- var shell function (n)
- var result memon
- if (typeof result ! 'number')
- result fundamental(shell, n)
- memon result
-
- return result
-
- return shell
19Memoizer
- 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.
20Code 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.
21Have regular code readings.
- Dont 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.
22Two 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
23Avoid unnecessary displays or animation.
- Everything costs.
- Wow costs.
- As the number of widgets on the page increases,
overall ongoing performance gets worse.
24Only speed up things that take a lot of time.
- Speeding up things that take very little time
will yield very little improvement.
25Only 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.
26Improving 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.
27Touch 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.
28Make good use of Ajax Libraries
- Effective code reuse will make widgets more
effective.
29How IE8 Spends Its Time
- Average time allocation of the Alexa 100
30How IE8 Spends Its Time
- Opening a thread in GMail
31Coding Efficiency
- Common subexpression removal.
- Loop invariant removal.
- Most compilers in most programming languages do
these optimizations for you. - But not JavaScript.
32Before
- var i
- for (i 0 i lt divs.length i 1)
- divsi.style.color "black"
- divsi.style.border thickness
- 'px solid blue'
- divsi.style.backgroundColor "white"
-
33After
- var border thickness 'px solid blue',
- nrDivs divs.length,
- ds, i
- for (i 0 i lt nrDivs i 1)
- ds divsi.style
- ds.color "black"
- ds.border border
- ds.backgroundColor "white"
-
34Strings
- 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('')
35Don'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.
36Don'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.
37O (1)
- An operation that is performed only once is not
worth optimizing.
38O (n)
- An operation that is performed many times may be
worth optimizing.
Slope Time per Iteration
Time
Fixed time Startup and cleanup
n
39The Axis of Error
Inefficiency
Time
n
40The Axis of Error
Frustration
Time
n
41The Axis of Error
Failure
Time
n
42O (n)
Slope Time per Iteration
Time
Fixed time Startup and cleanup
n
43O (n log n)
Time
n
44O (n2)
- Generally not suitable for browser applications
except when n is very small.
Time
n
45The most effective way to make programs faster is
to make n smaller.
- Ajax allows for just-in-time data delivery.
46The Wall.