high performance javascript - jquery conference sf bay area 2010

103
High Performance JavaScript Nicholas C. Zakas Principal Front End Engineer, Yahoo! jQuery Conference – SF Bay Area, April 24 2010

Upload: nicholas-zakas

Post on 27-Jan-2015

109 views

Category:

Technology


4 download

DESCRIPTION

Learn the inner workings of JavaScript to learn what makes things slow and how to speed them up. Heavily focused on DOM manipulation and UI updates.

TRANSCRIPT

Page 1: High Performance JavaScript - jQuery Conference SF Bay Area 2010

High Performance JavaScriptNicholas C. Zakas

Principal Front End Engineer, Yahoo!jQuery Conference – SF Bay Area, April 24 2010

Page 2: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 3: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Principal Front End Engineer

Page 4: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Contributor

Page 5: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Author

Page 6: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 7: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Things I Know About

jQuery

YUI

JavaScript

Professional Wrestling

Page 8: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 9: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 10: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 11: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Does this matter?

Page 12: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Old computers ran slow applications Small amounts of CPU power and memory

Page 13: High Performance JavaScript - jQuery Conference SF Bay Area 2010

New computers are generally faster butslow applications still exist

More CPU + more memory = less disciplined application development

Page 14: High Performance JavaScript - jQuery Conference SF Bay Area 2010

It's still possible to write slow JavaScript on the new, faster

JavaScript engines

Page 15: High Performance JavaScript - jQuery Conference SF Bay Area 2010

How can I improve JavaScript performance?

Page 16: High Performance JavaScript - jQuery Conference SF Bay Area 2010

How can I improve JavaScript performance?

How can I make this fast???

Page 17: High Performance JavaScript - jQuery Conference SF Bay Area 2010

How can I improve JavaScript performance?

How can I make this fast???

Why is this so slow?????

Page 18: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 19: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Many aspects conspire to make JavaScript slow Awareness is the first step to solution

Page 20: High Performance JavaScript - jQuery Conference SF Bay Area 2010

The UI ThreadThe brains of the operation

Page 21: High Performance JavaScript - jQuery Conference SF Bay Area 2010

The browser UI thread is responsible forboth UI updates and JavaScript execution

Only one can happen at a time

Page 22: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Jobs for UI updates and JavaScript execution areadded to a UI queue if the UI thread is busy

Each job must wait in line for its turn to execute

Page 23: High Performance JavaScript - jQuery Conference SF Bay Area 2010

<button id="btn" style="font-size: 30px; padding: 0.5em 1em">Click Me</button>

<script type="text/javascript">$(document).ready(function(){ $("#btn").bind("click",function(){ //do something });});</script>

Page 24: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Before Click

UI Thread

UI Queue

time

Page 25: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 26: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Draw down state

Page 27: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 28: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick UI UpdateUI Update

Draw up state

Page 29: High Performance JavaScript - jQuery Conference SF Bay Area 2010

No UI updates while JavaScript is executing!

Page 30: High Performance JavaScript - jQuery Conference SF Bay Area 2010

JavaScript May Cause UI Update

<button id="btn" style="font-size: 30px; padding: 0.5em 1em">Click Me</button>

<script type="text/javascript">$(document).ready(function(){ $("#btn").bind("click",function(){ $("body").append("<div class=\"tip\">You " +

"clicked me!</div>”); });});</script>

Page 31: High Performance JavaScript - jQuery Conference SF Bay Area 2010

A UI update must use the latest info available

Page 32: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Long-running JavaScript=

Unresponsive UI

Page 33: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Responsive UI

UI Thread

time

JavaScript UI UpdateUI Update

Page 34: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Unresponsive UI

UI Thread

time

JavaScript UI UpdateUI Update

Page 35: High Performance JavaScript - jQuery Conference SF Bay Area 2010

The runaway script timer prevents JavaScriptfrom running for too long

Each browser imposes its own limit (except Opera)

Page 36: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Internet Explorer

Page 37: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Firefox

Page 38: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Safari

Page 39: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Chrome

Page 40: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Runaway Script Timer Limits• Internet Explorer: 5 million statements• Firefox: 10 seconds• Safari: 5 seconds• Chrome: Unknown, hooks into normal crash

control mechanism• Opera: none

Page 41: High Performance JavaScript - jQuery Conference SF Bay Area 2010

How Long Is Too Long?

“0.1 second [100ms] is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.”

- Jakob Nielsen

Page 42: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Translation:No single JavaScript job should execute for more than 100ms to

ensure a responsive UI

Page 43: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Recommendation:Limit JavaScript execution to no more

than 50ms

Page 44: High Performance JavaScript - jQuery Conference SF Bay Area 2010

function processArray(items, process, callback){ for (var i=0,len=items.length; i < len; i++){ process(items[i]); } callback();}

Page 45: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Timers to the rescue!

Page 46: High Performance JavaScript - jQuery Conference SF Bay Area 2010

JavaScript Timers

• Created using setTimeout()• Schedules a new JavaScript execution job for

some time in the future• When the delay is up, the job is added to the

UI queue– Note: This does not guarantee execution

after the delay, just that the job is added to the UI queue and will be executed when appropriate

Page 47: High Performance JavaScript - jQuery Conference SF Bay Area 2010

JavaScript Timers

• For complex processing, split up into timed functionality

• Use timers to delay some processing for later

Page 48: High Performance JavaScript - jQuery Conference SF Bay Area 2010

function timedProcessArray(items, process, callback){ //create a clone of the original

var todo = items.concat(); setTimeout(function(){ var start = +new Date(); do { process(todo.shift()); } while (todo.length > 0 && (+new Date() - start < 50)); if (todo.length > 0){ setTimeout(arguments.callee, 25); } else { callback(items); } }, 25);}

Page 49: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 50: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 51: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 52: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

UI UpdateUI Update onclick

Page 53: High Performance JavaScript - jQuery Conference SF Bay Area 2010

After 25ms

UI Thread

UI Queue

time

UI UpdateUI Update onclick

JavaScript

Page 54: High Performance JavaScript - jQuery Conference SF Bay Area 2010

After 25ms

UI Thread

UI Queue

time

UI UpdateUI Update onclick JavaScript

Page 55: High Performance JavaScript - jQuery Conference SF Bay Area 2010

After Another 25ms

UI Thread

UI Queue

time

UI UpdateUI Update onclick JavaScript

JavaScript

Page 56: High Performance JavaScript - jQuery Conference SF Bay Area 2010

After Another 25ms

UI Thread

UI Queue

time

UI UpdateUI Update onclick JavaScript JavaScript

Page 57: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Web Workers to the rescue!

Page 58: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 59: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Web Workers

• Asynchronous JavaScript execution• Execution happens in a separate process

– Not on the UI thread = no UI delays• Data-driven API

– Data is serialized when sending data into or out of Worker

– No access to DOM, BOM– Completely separate execution

environment

Page 60: High Performance JavaScript - jQuery Conference SF Bay Area 2010

//in pagevar worker = new Worker("process.js");worker.onmessage = function(event){ useData(event.data);};worker.postMessage(values);

//in process.jsself.onmessage = function(event){ var items = event.data; for (var i=0,len=items.length; i < len; i++){ process(items[i]); } self.postMessage(items);};

Page 61: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 62: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 63: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Page 64: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

onclick

UI Update

UI Update

Worker Thread

Page 65: High Performance JavaScript - jQuery Conference SF Bay Area 2010

When Clicked

UI Thread

UI Queue

time

UI UpdateUI Update onclick

Worker Thread

JavaScript

Page 66: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Worker Thread Complete

UI Thread

UI Queue

time

UI UpdateUI Update onclick

onmessage

Page 67: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Worker Thread Complete

UI Thread

UI Queue

time

UI UpdateUI Update onclick onmessage

Page 68: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Web Workers Support

4.04.03.53.5 4.04.0

Page 69: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Repaint and ReflowUI update jobs

Page 70: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Long UI updates=

Unresponsive UI

Page 71: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Unresponsive UI

UI Thread

time

JavaScript UI UpdateUI Update

Page 72: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Long UI updates=

Unresponsive UI=

Frustrated users

Page 73: High Performance JavaScript - jQuery Conference SF Bay Area 2010

JavaScript can cause long UI updates

Page 74: High Performance JavaScript - jQuery Conference SF Bay Area 2010

A repaint occurs when a visual change doesn't require recalculation of layout

Changes to visibility, colors (text/background), background images, etc.

Page 75: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Repaint

<button id="btn" style="font-size: 30px; padding: 0.5em 1em">Click Me</button>

<script type="text/javascript">$(document).ready(function(){ $("#btn").bind("click",function(){ $(this).css({ color: "#f00" }); });});</script> Repaint!

Page 76: High Performance JavaScript - jQuery Conference SF Bay Area 2010

A reflow occurs when a visual change requires a change in layout

Initial page load ▪ browser resize ▪ DOM structure change ▪ layout style changelayout information retrieved

Page 77: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Reflow

<button id="btn" style="font-size: 30px; padding: 0.5em 1em">Click Me</button>

<script type="text/javascript">$(document).ready(function(){ $("#btn").bind("click",function(){ $("body").append("<div class=\"tip\">You " +

"clicked me!</div>”); });});</script> Reflow!

Page 78: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Repaints and reflows are queued up as JavaScript executes

Page 79: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Reflow

var list = $("ul.items");

for (var i=0; i < 10; i++){ list.append("<li>Item #" + i + "</li>");}

Reflow x 10!

Page 80: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Limiting repaints/reflows improves overall performance

Page 81: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Solution #1Perform DOM manipulations

off-document

Page 82: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Off-Document Operations

• Fast because there's no repaint/reflow• Techniques:

– Remove element from the document, make changes, insert back into document

– Set element's display to “none”, make changes, set display back to default

– Build up DOM changes on a DocumentFragment then apply all at once

Page 83: High Performance JavaScript - jQuery Conference SF Bay Area 2010

DocumentFragment• A document-like object• Not visually represented• Considered to be owned by the document from

which it was created• When passed to appendChild(), appends all

of its children rather than itself

Page 84: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Reflow!

No reflow!

Page 85: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Solution #2Group Style Changes

Page 86: High Performance JavaScript - jQuery Conference SF Bay Area 2010

$("span.example").css({ color: "red" });$("span.example").css({ height: "100px" });$("span.example").css({ fontSize: "25px" });$("span.example").css({ backgroundColor: "white" });

Repaint! Reflow!

Reflow!

Repaint!

Page 87: High Performance JavaScript - jQuery Conference SF Bay Area 2010

.active { color: red; height: 100px; fontSize: 25px; background-color: white;}

$("span.example").addClass("active");

Reflow!

Grouping Style Changes

Page 88: High Performance JavaScript - jQuery Conference SF Bay Area 2010

var item = document.getElementById("myItem");item.style.cssText = "color:red;height:100px;" + "font-size:25px;background-color: white");

Reflow!

Grouping Style Changes

Page 89: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Solution #3Avoid Accidental Reflow

Page 90: High Performance JavaScript - jQuery Conference SF Bay Area 2010

$("div.example").css({ width: "100px"});

var width = $("div.example").width();

Reflow!

Accidental Reflow

Page 91: High Performance JavaScript - jQuery Conference SF Bay Area 2010

What to do?• Minimize access to layout information

– offsetTop, offsetLeft, offsetWidth, offsetHeight– scrollTop, scrollLeft, scrollWidth, scrollHeight– clientTop, clientLeft, clientWidth, clientHeight– Most computed styles

• If a value is used more than once, store in local variable

Page 92: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Recap

Page 93: High Performance JavaScript - jQuery Conference SF Bay Area 2010
Page 94: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Things I Know About

jQuery

YUI

JavaScript

Professional Wrestling

Page 95: High Performance JavaScript - jQuery Conference SF Bay Area 2010

The browser UI thread is responsible forboth UI updates and JavaScript execution

Only one can happen at a time

Page 96: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Responsive UI

UI Thread

time

JavaScript UI UpdateUI Update

Page 97: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Unresponsive UI

UI Thread

time

JavaScript UI UpdateUI Update

Page 98: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Unresponsive UI

UI Thread

time

JavaScript UI UpdateUI Update

Page 99: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Avoid Slow JavaScript• Don't allow JavaScript to execute for more

than 50ms• Break up long JavaScript processes using:

– Timers– Web Workers

Page 100: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Avoid Long UI Updates• Be careful of repaint and reflow• Perform complex DOM operations off-

document– Remove elements and re-add them– Use DocumentFragment objects

• Group style changes together• Avoid accidental reflow

Page 101: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Questions?

Page 102: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Etcetera• My blog: www.nczonline.net• My email: [email protected]• Twitter: @slicknet

Page 103: High Performance JavaScript - jQuery Conference SF Bay Area 2010

Creative Commons Images Used• http://www.flickr.com/photos/lrargerich/3115367361/

• http://www.flickr.com/photos/photomonkey/93277011/

• http://www.flickr.com/photos/hippie/2406411610/

• http://www.flickr.com/photos/55733754@N00/3325000738/

• http://www.flickr.com/photos/eurleif/255241547/

• http://www.flickr.com/photos/off_the_wall/3444915939/

• http://www.flickr.com/photos/wwarby/3296379139/

• http://www.flickr.com/photos/derekgavey/4358797365/

• http://www.flickr.com/photos/mulad/286641998/