High Performance JavaScript

Post on 31-Oct-2014

193 views 4 download

Tags:

description

Performance is a big topic, but this talk will at least touch on the areas that tend to slow down your application: Resource loading, libraries, DOM, CSS, memory, and the application itself. Then we will focus on getting maximum performance from JavaScript and your applications.

Transcript of High Performance JavaScript

HIGH PERFORMANCE JAVASCRIPT

by Mike Wilcox

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Before tuning the JavaScript...

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Libraries or Library Usage

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Libraries or Library Usage

Application Architecture

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Libraries or Library Usage

Application Architecture

DOM

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Libraries or Library Usage

Application Architecture

DOM

CSS

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Libraries or Library Usage

Application Architecture

DOM

CSS

Memory Management

Wednesday, September 3, 2014

WHAT NEEDS PERFORMANCE

Page and Resource Loading

Libraries or Library Usage

Application Architecture

DOM

CSS

Memory Management

JavaScript

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

The 50 jQuery plugin scripts is a no-no

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

The 50 jQuery plugin scripts is a no-no

Too few resources can be very slow

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

The 50 jQuery plugin scripts is a no-no

Too few resources can be very slow

Not uncommon for web apps to have 3+ megabytes of code

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

The 50 jQuery plugin scripts is a no-no

Too few resources can be very slow

Not uncommon for web apps to have 3+ megabytes of code

Solution:

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

The 50 jQuery plugin scripts is a no-no

Too few resources can be very slow

Not uncommon for web apps to have 3+ megabytes of code

Solution:

Load a main core file, enough to display the page, then lazy-load the rest, or as needed.

Wednesday, September 3, 2014

PAGE AND RESOURCE LOADING

Too many resources is very slow

Using requirejs in dev mode can mean 50 files

DNS lookup + only a few files load in parallel

The 50 jQuery plugin scripts is a no-no

Too few resources can be very slow

Not uncommon for web apps to have 3+ megabytes of code

Solution:

Load a main core file, enough to display the page, then lazy-load the rest, or as needed.

Learn (much) more: http://www.slideshare.net/anm8tr/faster-websites-kill-kill-4402077

Wednesday, September 3, 2014

LIBRARIES

Wednesday, September 3, 2014

LIBRARIES

Use the right library

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Use the library the way it was intended

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Use the library the way it was intended

The Dojo fallacy was making “everything a widget”

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Use the library the way it was intended

The Dojo fallacy was making “everything a widget”

Angular makes everything a component

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Use the library the way it was intended

The Dojo fallacy was making “everything a widget”

Angular makes everything a component

Knockout templates can get slow

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Use the library the way it was intended

The Dojo fallacy was making “everything a widget”

Angular makes everything a component

Knockout templates can get slow

No library can be the right library

Wednesday, September 3, 2014

LIBRARIES

Use the right library

jQuery is easy not fast

Angular needs to load a lot of boilerplate and polyfills

Use the library the way it was intended

The Dojo fallacy was making “everything a widget”

Angular makes everything a component

Knockout templates can get slow

No library can be the right library

No overhead to download - write exactly what the app needsWednesday, September 3, 2014

APPLICATION ARCHITECTURE

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Don’t download all the data at once

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Don’t download all the data at once

Display *something* as soon as possible

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Don’t download all the data at once

Display *something* as soon as possible

Know the limits of:

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Don’t download all the data at once

Display *something* as soon as possible

Know the limits of:

The browser

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Don’t download all the data at once

Display *something* as soon as possible

Know the limits of:

The browser

Your users

Wednesday, September 3, 2014

APPLICATION ARCHITECTURE

Don’t parse everything at once

Don’t download all the data at once

Display *something* as soon as possible

Know the limits of:

The browser

Your users

You

Wednesday, September 3, 2014

DOM

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Create your widget in a fragment first, then add it to the page

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Create your widget in a fragment first, then add it to the page

Image resizing is extra work for the browser

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Create your widget in a fragment first, then add it to the page

Image resizing is extra work for the browser

Like in CSS, setting and getting sizes and positions, and scroll causes a reflow

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Create your widget in a fragment first, then add it to the page

Image resizing is extra work for the browser

Like in CSS, setting and getting sizes and positions, and scroll causes a reflow

addEventListener is not free

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Create your widget in a fragment first, then add it to the page

Image resizing is extra work for the browser

Like in CSS, setting and getting sizes and positions, and scroll causes a reflow

addEventListener is not free

Add listeners to the parent and check the clicked node via event.target

Wednesday, September 3, 2014

DOM

Most of the time, creating nodes is faster than a big innerHTML

createTextNode can be many times faster than innerHTML

Create your widget in a fragment first, then add it to the page

Image resizing is extra work for the browser

Like in CSS, setting and getting sizes and positions, and scroll causes a reflow

addEventListener is not free

Add listeners to the parent and check the clicked node via event.target

Do NOT add a listener to hundreds of child nodes

Wednesday, September 3, 2014

CSS

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Don’t use JavaScript when it’s a job for CSS

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Don’t use JavaScript when it’s a job for CSS

Use element.style as little as possible

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Don’t use JavaScript when it’s a job for CSS

Use element.style as little as possible

Set classNames (or better, use classList)

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Don’t use JavaScript when it’s a job for CSS

Use element.style as little as possible

Set classNames (or better, use classList)

Use transitions or animations, not jQuery

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Don’t use JavaScript when it’s a job for CSS

Use element.style as little as possible

Set classNames (or better, use classList)

Use transitions or animations, not jQuery

Know what styles affect a page reflow and affect performance

Wednesday, September 3, 2014

CSS

Use as few stylesheets as reasonable

Keep them clean and maintained, so time is wasted downloading unused definitions

Don’t use JavaScript when it’s a job for CSS

Use element.style as little as possible

Set classNames (or better, use classList)

Use transitions or animations, not jQuery

Know what styles affect a page reflow and affect performance

Namely anything to do with sizes: setting as well as getting

Wednesday, September 3, 2014

MEMORY MANAGEMENT

Value Graph

Root Node Object Node

Scalar Node

How Garbage Collection Works

Wednesday, September 3, 2014

MEMORY MANAGEMENTObject is dereferenced, and it and its descendants are slated for GC

Value GraphWednesday, September 3, 2014

MEMORY MANAGEMENTHowever, if there is a reference to any object in the tree, it can’t be released

Value GraphWednesday, September 3, 2014

MEMORY MANAGEMENTValue graph example shown in code

var app = {! registry: {},! getWidget: function(id){! ! var widget = {};! ! this.registry[id] = widget;! ! return widget;! }};var widget = app.getWidget('mine');widget = null; // will not release

Wednesday, September 3, 2014

MEMORY MANAGEMENTValue graph example shown in code

var app = {! registry: {},! getWidget: function(id){! ! var widget = {};! ! this.registry[id] = widget;! ! return widget;! }};var widget = app.getWidget('mine');widget = null; // will not release

Moral: Clean up after yourself. Suggest a dispose(); method on the widget that removes itself from the registry

Wednesday, September 3, 2014

Before tuning the JavaScript...

WHEN TO OPTIMIZE

Wednesday, September 3, 2014

Wednesday, September 3, 2014

“Premature optimization is the root of all evil”

~ Donald Knuth

Wednesday, September 3, 2014

“Premature optimization is the root of all evil”

~ Donald Knuth

“Except when you should be planning ahead.”

~ Mike Wilcox

Wednesday, September 3, 2014

PLANNING AHEAD

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Unbind event listeners that aren't needed any more

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Unbind event listeners that aren't needed any more

Careful with scope

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Unbind event listeners that aren't needed any more

Careful with scope

Browsers are actually really good at GC

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Unbind event listeners that aren't needed any more

Careful with scope

Browsers are actually really good at GC

But know when you are capturing in your closures

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Unbind event listeners that aren't needed any more

Careful with scope

Browsers are actually really good at GC

But know when you are capturing in your closures

Use JSHint in your IDE

Wednesday, September 3, 2014

PLANNING AHEAD

Clean up after yourself

Implement or use a widget life cycle system

Unbind event listeners that aren't needed any more

Careful with scope

Browsers are actually really good at GC

But know when you are capturing in your closures

Use JSHint in your IDE

It will warn against bad practices that can slow your code

Wednesday, September 3, 2014

DON’T WORRY

Wednesday, September 3, 2014

DON’T WORRY

Maintainability trumps performance 98.6% of the time

Wednesday, September 3, 2014

DON’T WORRY

Maintainability trumps performance 98.6% of the time

90% of the time, the only performance you'll need is rendering DOM

Wednesday, September 3, 2014

DON’T WORRY

Maintainability trumps performance 98.6% of the time

90% of the time, the only performance you'll need is rendering DOM

Code that is async, or immediately after is not performance critical

Wednesday, September 3, 2014

DON’T WORRY

Maintainability trumps performance 98.6% of the time

90% of the time, the only performance you'll need is rendering DOM

Code that is async, or immediately after is not performance critical

Size matters

Wednesday, September 3, 2014

DON’T WORRY

Maintainability trumps performance 98.6% of the time

90% of the time, the only performance you'll need is rendering DOM

Code that is async, or immediately after is not performance critical

Size matters

A loop of 20 items will be fine in a forEach, suffering a few measly milliseconds

Wednesday, September 3, 2014

CRITICAL AREAS

Wednesday, September 3, 2014

CRITICAL AREAS

Memory is always critical - it can give you the scrolling “janks”

Wednesday, September 3, 2014

CRITICAL AREAS

Memory is always critical - it can give you the scrolling “janks”

Template parsing; especially many widgets on page load

Wednesday, September 3, 2014

CRITICAL AREAS

Memory is always critical - it can give you the scrolling “janks”

Template parsing; especially many widgets on page load

Canvas rendering; especially animation

Wednesday, September 3, 2014

CRITICAL AREAS

Memory is always critical - it can give you the scrolling “janks”

Template parsing; especially many widgets on page load

Canvas rendering; especially animation

Oft-triggered actions, like on page resize or mousemove

Wednesday, September 3, 2014

CRITICAL AREAS

Memory is always critical - it can give you the scrolling “janks”

Template parsing; especially many widgets on page load

Canvas rendering; especially animation

Oft-triggered actions, like on page resize or mousemove

Millions of items of grid data

Wednesday, September 3, 2014

CRITICAL AREAS

Memory is always critical - it can give you the scrolling “janks”

Template parsing; especially many widgets on page load

Canvas rendering; especially animation

Oft-triggered actions, like on page resize or mousemove

Millions of items of grid data

Just kidding. You should never do this.

Wednesday, September 3, 2014

JAVASCRIPT PERFORMANCE

Now you’re ready improve your...

Wednesday, September 3, 2014

AVOID EVAL

Wednesday, September 3, 2014

AVOID EVAL

As well as new Function(...) or a string in setTimeout()

Wednesday, September 3, 2014

AVOID EVAL

As well as new Function(...) or a string in setTimeout()

Expensive operations as each time they are called, the script engine must convert source to executable code

Wednesday, September 3, 2014

AVOID EVAL

As well as new Function(...) or a string in setTimeout()

Expensive operations as each time they are called, the script engine must convert source to executable code

Has to be interpreted at runtime - #NOJIT

Wednesday, September 3, 2014

AVOID EVAL

As well as new Function(...) or a string in setTimeout()

Expensive operations as each time they are called, the script engine must convert source to executable code

Has to be interpreted at runtime - #NOJIT

Better:

Wednesday, September 3, 2014

AVOID EVAL

As well as new Function(...) or a string in setTimeout()

Expensive operations as each time they are called, the script engine must convert source to executable code

Has to be interpreted at runtime - #NOJIT

Better:

Use JSON

Wednesday, September 3, 2014

AVOID EVAL

As well as new Function(...) or a string in setTimeout()

Expensive operations as each time they are called, the script engine must convert source to executable code

Has to be interpreted at runtime - #NOJIT

Better:

Use JSON

Parse function with a predetermined convention

Wednesday, September 3, 2014

Slow:with (test.object) { foo = 'Value of foo property of object'; bar = 'Value of bar property of object';}

Faster:var myObj = test.object;myObj.foo = 'Value of foo property of object';myObj.bar = 'Value of bar property of object';

Hopefully you weren’t doing this...

AVOID WITH

Wednesday, September 3, 2014

Slow:with (test.object) { foo = 'Value of foo property of object'; bar = 'Value of bar property of object';}

Faster:var myObj = test.object;myObj.foo = 'Value of foo property of object';myObj.bar = 'Value of bar property of object';

Hopefully you weren’t doing this...

AVOID WITH

Wednesday, September 3, 2014

Slow: for (i = 0; i < object.length; i++) { try { // do something that throws an exception } catch (e) { // handle exception }}

Faster:try { for (i = 0; i < object.length; i++) { // do something }} catch (e) { // handle exception}

#NOJIT

TRY-CATCH

Wednesday, September 3, 2014

Slow: for (i = 0; i < object.length; i++) { try { // do something that throws an exception } catch (e) { // handle exception }}

Faster:try { for (i = 0; i < object.length; i++) { // do something }} catch (e) { // handle exception}

#NOJIT

TRY-CATCH

Wednesday, September 3, 2014

Slow:window.str = '';function globalScope() { for (var i=0; i < 100; i++) { str += i; }}

Faster:window.str = '';function localScope() { var tempstr = ''; for (var i=0; i < 100; i++) { tempstr += i; } str = tempstr;}

Slow lookup; Bad GC

AVOID GLOBAL SCOPE

Wednesday, September 3, 2014

Slow:window.str = '';function globalScope() { for (var i=0; i < 100; i++) { str += i; }}

Faster:window.str = '';function localScope() { var tempstr = ''; for (var i=0; i < 100; i++) { tempstr += i; } str = tempstr;}

Slow lookup; Bad GC

AVOID GLOBAL SCOPE

Wednesday, September 3, 2014

// always the same! Get the variable firstvar a = 0;for(var i = 0; i < array.length; i++){

a += Math.sin(1);}

// creating a new function every time #NOJITvar a = 0, b = [1,2,3];for(var i = 0; i < array.length; i++){

b.forEach(function(num){a += num;

}); }

Functions take time, creating them is worse

UNNECESSARY FUNCTIONS

Wednesday, September 3, 2014

// always the same! Get the variable firstvar a = 0;for(var i = 0; i < array.length; i++){

a += Math.sin(1);}

// creating a new function every time #NOJITvar a = 0, b = [1,2,3];for(var i = 0; i < array.length; i++){

b.forEach(function(num){a += num;

}); }

Functions take time, creating them is worse

UNNECESSARY FUNCTIONS

Wednesday, September 3, 2014

// always the same! Get the variable firstvar a = 0;for(var i = 0; i < array.length; i++){

a += Math.sin(1);}

// creating a new function every time #NOJITvar a = 0, b = [1,2,3];for(var i = 0; i < array.length; i++){

b.forEach(function(num){a += num;

}); }

Functions take time, creating them is worse

UNNECESSARY FUNCTIONS

Wednesday, September 3, 2014

// Problem: for large arrays, this can get slowvar items = [{id:'a'}, {id:'b'}, {id:'c'}];function getItemById(id){! for(var i = 0; i < items.length; i++){! ! if(items[i].id === id){! ! ! return items[i];! ! }! }}

// Solution: use a hash map insteadvar items = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};function getItemById(id){! return items[id];}

Unnecessary Array lookups

LIST VS MAPS

Wednesday, September 3, 2014

// Problem: for large arrays, this can get slowvar items = [{id:'a'}, {id:'b'}, {id:'c'}];function getItemById(id){! for(var i = 0; i < items.length; i++){! ! if(items[i].id === id){! ! ! return items[i];! ! }! }}

// Solution: use a hash map insteadvar items = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};function getItemById(id){! return items[id];}

Unnecessary Array lookups

LIST VS MAPS

Wednesday, September 3, 2014

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

function getItemById(id){

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

function getItemById(id){! return itemMap[id];

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

function getItemById(id){! return itemMap[id];}

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

function getItemById(id){! return itemMap[id];}

// Could also get tricky:

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

function getItemById(id){! return itemMap[id];}

// Could also get tricky: itemList.map = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Solution: Why not use both?var! itemList = [{id:'a'}, {id:'b'}, {id:'c'}],! itemMap = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};!function addItem(item){! itemList.push(item);! itemMap[item.id] = item;}function getItemByIndex(index){! return itemList[index];}

function getItemById(id){! return itemMap[id];}

// Could also get tricky: itemList.map = {a:{id:'a'}, b:{id:'b'}, c:{id:'c'}};

Problem: you need an “ordered hash map”

LIST VS MAPS

Wednesday, September 3, 2014

// Fastestfor(var i = 0; i < array.length; i++){

this.doThing(i); }

// Fast(ish)array.forEach(function(){

doThing(i); });

// Slowvar self = this;array.forEach(function(i){ self.doThing(i); });

// Slowestarray.forEach(function(i){ this.doThing(i); }, this);

Changing context on a function is costly

THIS

Wednesday, September 3, 2014

OBJECTS VS ARRAYS

http://www.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/Wednesday, September 3, 2014

OBJECTS VS ARRAYS

Properties on objects are quite complex: they can be created with setters, and with differing enumerability and writability.

http://www.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/Wednesday, September 3, 2014

OBJECTS VS ARRAYS

Properties on objects are quite complex: they can be created with setters, and with differing enumerability and writability.

Items in arrays aren’t able to be customized as heavily — they either exist or they don’t. At an engine level, this allows for more optimization.

http://www.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/Wednesday, September 3, 2014

OBJECTS VS ARRAYS

Properties on objects are quite complex: they can be created with setters, and with differing enumerability and writability.

Items in arrays aren’t able to be customized as heavily — they either exist or they don’t. At an engine level, this allows for more optimization.

This is particularly beneficial when the array contains numbers. For example, when you need vectors, don’t define a class with properties x, y, z; use an array instead.

http://www.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/Wednesday, September 3, 2014

Memoryhttps://speakerdeck.com/addyosmani/javascript-memory-management-masterclass

Loopshttp://jsperf.com/fastest-array-loops-in-javascript/32

http://jsperf.com/add-a-property-to-an-array/2http://jsperf.com/array-vs-uint32array

Functionshttp://jsperf.com/iifes-vs-nested-functions/2

Performancehttps://github.com/sq/JSIL/wiki/JavaScript-Performance-For-Madmen

https://gist.github.com/khoomeister/4985691 (make js faster)http://www.html5rocks.com/en/tutorials/speed/v8/

http://www.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/http://developer.nokia.com/community/wiki/JavaScript_Performance_Best_Practices

http://code.mendhak.com/angular-performance/

Librarieshttp://xepler.com/blog/2014/03/19/the-good-the-bad-and-the-ugly-a-jquery-tale

References

Wednesday, September 3, 2014

Wednesday, September 3, 2014