fast apps and sites with javascript

60

Upload: ziazan

Post on 25-Feb-2016

42 views

Category:

Documents


0 download

DESCRIPTION

Fast Apps and Sites with JavaScript. Gaurav Seth Program Manager, JavaScript 4-313. Five principles to improve the raw JavaScript performance of your app Based on what modern JavaScript engines like Chakra do with your code…. High Five Yeah - Overview. Single Player Single Page - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Fast Apps and Sites with JavaScript
Page 2: Fast Apps and Sites with JavaScript

Fast Apps and Sites with JavaScriptGaurav SethProgram Manager, JavaScript4-313

Page 3: Fast Apps and Sites with JavaScript

Five principles to improvethe raw JavaScript performance of your appBased on what modern JavaScript engines like Chakra do with your code…

Page 4: Fast Apps and Sites with JavaScript

Single PlayerSingle PageCasual Game

High Five Yeah - Overview

Raw JS code: http://aka.ms/FastJS

Page 5: Fast Apps and Sites with JavaScript

Matrix of player(s)

Each Player has a set of directions

Generate list of

neighbors to rotate

Rotate the player

On Touch, select a player

Arrays Objects and properties Numbers Animation loop

Memory allocations

Repeat until neighbors list empty

Components and control flow

Page 6: Fast Apps and Sites with JavaScript

We’ve got a problem…

Page 7: Fast Apps and Sites with JavaScript

Low frame rate causes …

GLITCH

Page 8: Fast Apps and Sites with JavaScript

What impacts visual throughput?

http://aka.ms/IESubsystems

+ Code

Page 9: Fast Apps and Sites with JavaScript

What really matters?

t0(Launch)

tn(Close or navigate)

60 fps16.67ms 16.67ms 16.67ms

Paint

Paint

Paint

Page 10: Fast Apps and Sites with JavaScript

Let’s investigate …

Raw JS code: http://aka.ms/FastJS

Page 11: Fast Apps and Sites with JavaScript

Always start with a good profiler

Windows Performance Toolkithttp://aka.ms/WinPerfKit

F12 UI Responsiveness Tool

Page 12: Fast Apps and Sites with JavaScript

Is JavaScript the bottleneck?

Chakra(GC, etc.)

Your Code(Script, Execute, etc.)

Other Subsystems

Page 13: Fast Apps and Sites with JavaScript

Do we expect so much of GC to happen?

GC

Page 14: Fast Apps and Sites with JavaScript

Principle #1:Memory usage: Stay lean

Page 15: Fast Apps and Sites with JavaScript

Let’s fix…

Raw JS code: http://aka.ms/FastJS

Page 16: Fast Apps and Sites with JavaScript

Results

• Overall FG GC time reduced to 1/3rd • Raw JavaScript perf improved ~3x

Page 17: Fast Apps and Sites with JavaScript

Obj1 Obj1a Obj1b Root Obj2 Obj2a Obj2b Obj2c

Obj2d C-1 C-2 Obj2e Obj3 ... ... ...

... ... ... ... ... ... ... ...

... C-1a ... C-1b C-1c C-1a1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1 C-1b1

Garbage Collector: Flow Program ProgramInitialize

POOL #1 (SMALL OBJECTS

)

POOL #2 (LARGE

OBJECTS)

Zero outMark Sweep

Page 18: Fast Apps and Sites with JavaScript

What triggers a garbage collection?• Every call to new or implicit memory allocation reserves GC memory - Allocations are cheap until current pool is exhausted

• When the pool is exhausted, engines force a collection - Collections cause program pauses - Pauses could take milliseconds

• Be careful with object allocation patterns in your apps - Every allocation brings you closer to a GC pause

Page 19: Fast Apps and Sites with JavaScript

Concurrent Garbage Collection: AdvantagesUtilizing spare hardware capacity to reduce pauses

• Shorter pauses• Partial, time restricted collections

Program SetupSweep Program

Sweep Zero Pages

FOREGROUND THREAD

BACKGROUND THREAD

Initialize

Mark

Program Rescan Mark

Page 20: Fast Apps and Sites with JavaScript

Best practices for staying lean

• Avoid unnecessary object creation• Use object pools, when possible• Be aware of allocation patterns - Setting closures to event handlers - Dynamically creating DOM (sub) trees - Implicit allocations in the engine

Page 21: Fast Apps and Sites with JavaScript

Principle #2Use fast objects and manipulations

Page 22: Fast Apps and Sites with JavaScript

Internal Type System: Fast Object Types

var p1;p1.north = 1;p1.south = 0;

var p2;p2.south = 0;p2.north = 1;

north 1south 0

north 1

north

south

south 0north 1

south 0

south

north

Base Type “{}”

Type “{north}” Type “{south}”

Base Type “{}”

Type “{south, north}”Type “{north, south}”

Page 23: Fast Apps and Sites with JavaScript

Create fast types and avoid type mismatchesDon’t add properties conditionally

function Player(direction) { if (direction = “NE”) { this.n = 1; this.e = 1; } else if (direction = “ES”) { this.e = 1; this.s = 1; } ...}

var p1 = new Player(“NE”); // p1 type {n,e}var p2 = new Player(“ES”); // p2 type {e,s}

function Player(north,east,south,west) { this.n = north; this.e = east; this.s = south; this.w = west;}

var p1 = new Player(1,1,0,0);//p1 type {n,e,s,w}var p2 = new Player(0,0,1,1);//p2 type {n,e,s,w}p1.type !=

p2.typep1.type == p2.type

Page 24: Fast Apps and Sites with JavaScript

Create fast types and avoid type mismatchesDon’t default properties on prototypes

function Player(name) { ...};

Player.prototype.n = null;Player.prototype.e = null;Player.prototype.s = null;Player.prototype.w = null;

var p1 = new Player("Jodi"); //p1 type{}var p2 = new Player("Mia"); //p2 type{}var p3 = new Player("Jodi"); //p3 type{}

p1.n = 1; //p1 type {n}p2.e = 1; //p2 type {e}

function Player(name) { this.n = null; this.e = null; this.s = null; this.w = null; ...}

var p1 = new Player("Jodi"); //p1 type{n,e,s,w}var p2 = new Player("Mia"); //p2 type{n,e,s,w}var p3 = new Player("Jodi"); //p3 type{n,e,s,w}

p1.n = 1; //p1 type{n,e,s,w}p2.e = 1; //p2 type{n,e,s,w}

p1.type != p2.type != p3.type

p1.type == p2.type == p3.type

Page 25: Fast Apps and Sites with JavaScript

Internal Type System: Slower Property Bags var p1 = new Player(); //prop

bagp1.north = 1;p1.south = 1;

var p2 = new Player(); //prop bagp2.north = 1;p2.south = 1;

always

Slower Bag “{p1}” Slower Bag “{p2}”

always

Page 26: Fast Apps and Sites with JavaScript

Avoid conversion from fast type to slower property bagsDeleting properties forces conversion

function Player(north,east,south,west) { this.n = north; this.e = east; this.s = south; this.w = west;}var p1 = new Player();

delete p1.n;

function Player(north,east,south,west) { this.n = north; this.e = east; this.s = south; this.w = west;}var p1 = new Player();

p1.n = 0; // or undefined

SLOW FAST

Page 27: Fast Apps and Sites with JavaScript

Avoid creating slower property bagsAdd properties in constructor, restrict total properties

function Player(north,east,south,west) { this.n = north; this.e = east; this.s = south; this.w = west; ... // Restrict to few if possible}

var p1 = new Player();

function Player() { this.prop01 = 1; this.prop02 = 2; ... this.prop256 = 256; ... // Do you need an array?}

var p1 = new Player();

SLOW FAST

Page 28: Fast Apps and Sites with JavaScript

Avoid creating slower property bagsRestrict using getters, setters and property descriptors in perf critical paths

function Player(north, east, south, west) { Object.defineProperty(this, "n", { get : function() { return nVal; }, set : function(value) { nVal=value; }, enumerable: true, configurable: true }); Object.defineProperty(this, "e", { get : function() { return eVal; }, set : function(value) { eVal=value; }, enumerable: true, configurable: true }); ...}var p = new Player(1,1,0,0);var n = p.n;p.n = 0;...

function Player(north, east, south, west) { this.n = north; this.e = east; this.s = south; this.w = west; ...}

var p = new Player(1,1,0,0);var n = p.n;p.n = 0;...

SLOW FAST

Page 29: Fast Apps and Sites with JavaScript

Let’s fix…

Raw JS code: http://aka.ms/FastJS

Page 30: Fast Apps and Sites with JavaScript

Results

• Time in script execution reduced ~30%• Raw JS performance improved ~30%

3.8s

2.2s

Page 31: Fast Apps and Sites with JavaScript

Type mismatches may lead to inline cache missesKeep types same; distribute multiple types uniformlyfunction Player(n,e,s,w) {...} //type {1}

function rotate(p) { if (p.n == 1){...}//store slot# for n in type{1} ...}

for (var i = 0; i < boardSize; i++) { matrix[i] = new Player(1,1,0,0); // type {1} ...}

matrix[boardSize].last = true; // type {2}

for (var i=0;i < boardSize; i++){ rotate(matrix[i]);}

function Jodi(n,e,s,w){this.name = "Jodi"; ...}Jodi.prototype = new Player(); // type {1}

function Mia(n,e,s,w){...} // type {2} Mia.prototype = new Player();

function rotate(p){ if (p.n == 1){...} //store slot# for type{1}&{2}}

for (var i = 0; i < boardSize; i++) { if (i%2 == 0) matrix[i] = new Mia(1,1,0,0); // type {1} else matrix[j] = new Jodi(1,1,0,0); // type {2} ...for (var i=0;i < boardSize; i++){ rotate(matrix[i]);}

Inline cache miss for different types

Multiple (slower) caches for different types

Page 32: Fast Apps and Sites with JavaScript

Impact of inline caches

Caches provided 2x speedup

Page 33: Fast Apps and Sites with JavaScript

Best practices for fast objects and manipulations

• Create and use fast types• Keep shapes of objects consistent• Avoid type mismatches for fast types• Avoid inline cache misses

Page 34: Fast Apps and Sites with JavaScript

Principle #3Use fast arithmetic

Page 35: Fast Apps and Sites with JavaScript

Numbers in JavaScript• All numbers are IEEE 64-bit floating point

numbers - Great for flexibility - Performance and optimization challenge

31 bits31-bit (tagged) Integers

1 bit1

31 bitsObject pointer

1 bit0

32 bits

32 bits

Floats32-bit

Integers

STACK HEAPFIXED LENGTH, FASTER ACCESS VARIABLE LENGTH, SLOWER ACCESS

Boxed

Page 36: Fast Apps and Sites with JavaScript

Use 31-bit integers for faster arithmetic

var north = 1;

var east = "east";var south = 0.1;var west = 0x1;

function Player(north, south, east, west) { ...}

var p = new Player(north,south,east,west);

STACK0x00000003north:0x005e4148east:0x005e4160south:

String“east”

Number0.1

Number0x1

0x005e4170west:

HEAP

0x005e4148: 0…01001000 0x03 represents 1:  0…00000011

SLOW

SLOW

SLOW

Page 37: Fast Apps and Sites with JavaScript

Avoid creating floats if they are not neededFastest way to indicate integer math is |0

var r = 0;

function doMath(){ var a = 5; var b = 2; r = ((a + b) / 2) |0 ; // r = 3 r = Math.round((a + b) / 2); // r = 4 }

var r = 0;

function doMath(){ var a = 5; var b = 2; r = ((a + b) / 2); // r = 3.5}... var intR = Math.floor(r);

0x005e4148r: 0x00000007r:

0x00000009r:Number3.5

STACK HEAP STACK

SLOW FAST

SLOW

Page 38: Fast Apps and Sites with JavaScript

Take advantage of type-specialization for arithmeticCreate separate functions for ints and floats; use consistent argument types

function Distance(p1, p2) { var dx = p1.x - p2.x; var dy = p1.y - p2.y; var d2 = dx * dx + dy * dy; return Math.sqrt(d2);}

var point1 = {x:10, y:10};var point2 = {x:20, y:20};var point3 = {x:1.5, y:1.5}; var point4 = {x:0x0AB, y:0xBC};

Distance(point1, point3);Distance(point2, point4);

function DistanceFloat(p1, p2) { var dx = p1.x - p2.x; var dy = p1.y - p2.y; var d2 = dx * dx + dy * dy; return Math.sqrt(d2);}function DistanceInt(p1,p2) { var dx = p1.x - p2.x; var dy = p1.y - p2.y; var d2 = dx * dx + dy * dy; return (Math.sqrt(d2) | 0);}var point1 = {x:10, y:10};var point2 = {x:20, y:20};var point3 = {x:1.5, y:1.5}; var point4 = {x:0x0AB, y:0xBC};

DistanceInt(point1, point2);DistanceFloat(point3, point4);

SLOW FAST

Page 39: Fast Apps and Sites with JavaScript

Best practices for fast arithmetic

• Use 31-bit integer math when possible • Avoid floats if they are not needed• Design for type specialized arithmetic

Page 40: Fast Apps and Sites with JavaScript

Principle #4Use fast Arrays

Page 41: Fast Apps and Sites with JavaScript

Chakra: Array internals

01 var a = new Array();02 a[0] = 1;03 a[1] = 2.3;04 a[2] = “str”;

Type: Int Array

1

Type: Float Array

Type: Var Array

1 2.3 “str”

1 2.3

Page 42: Fast Apps and Sites with JavaScript

Pre-allocate arraysvar a = new Array(100);for (var i = 0; i < 100; i++) { a[i] = i + 2;}

var a = new Array();for (var i = 0; i < 100; i++) { a.push(i + 2);}

0 ?

?+1 ??…0 100

SLOW

FAST

Page 43: Fast Apps and Sites with JavaScript

var a = new Array(100000);

for (var i = 0; i < a.length; i++) { a[i] = i;}...//operations on the array...a[99] = “str”;

For mixed arrays, provide an early hintAvoid delayed type conversion and copy

var a = new Array(100000);

a[0] = “hint”;

for (var i = 0; i < a.length; i++) { a[i] = i;}...//operations on the array...a[99] = “str”;

SLOW

FAST

Page 44: Fast Apps and Sites with JavaScript

Use Typed Arrays when possibleAvoids tagging of integers and allocating heap space for floats

var value = 5;

var a = new Array(100);a[0] = value; // 5 - taggeda[1] = value / 2; // 2.5 - boxeda[2] = "text"; // "text" – var array

var value = 5;

var a = new Float64Array(100);a[0] = value; // 5 - no tagging requireda[1] = value / 2; // 2.5 - no boxing requireda[2] = "text"; // 0

var a = new Int32Array(100);a[0] = value; // 5 - no tagging requireda[1] = value / 2; // 2 - no tagging requireda[2] = "text"; // 0

SLOW

FAST

Page 45: Fast Apps and Sites with JavaScript

Keep values in arrays consistent Numeric arrays treated like Typed Arrays internally

var a = [1,0x2,99.1,5]; //mixed arrayvar b = [0x10,8,9]; //mixed array

function add(a,i,b,j){ return a[i] + b[j];}

add(a,0,b,0);add(a,1,b,1);

var a = [1,5,8,9]; //int arrayvar b = [0x02,0x10,99.1]; //float array

function add(a,i,b,j){ return a[i] + b[j];}

add(a,0,b,0);add(a,1,b,1);SLO

WFAST

Page 46: Fast Apps and Sites with JavaScript

Keep arrays denseDeleting elements can force type change and de-optimization

var a = new Array(1000); //type int...for (var i = 0; i < boardSize; i++) { matrix[i] = [1,1,0,0];}

//operating on the array...delete matrix[23];...//operating on the array

var a = new Array(1000); //type int...for (var i = 0; i < boardSize; i++) { matrix[i] = [1,1,0,0];}

//operating on the array...matrix[23] = 0;...//operating on the array

SLOW

FAST

Page 47: Fast Apps and Sites with JavaScript

Enumerate arrays efficientlyExplicit caching of length avoids repetitive property accesses

var a = new Array(100);var total = 0;

for (var item in a) { total += item;};

a.forEach(function(item){ total += item; });

for (var i = 0; i < a.length; i++) { total += a[i];}

var a = new Array(100);var total = 0;

cachedLength = a.length;

for (var i = 0; i < cachedLength; i++) { total += a[i];}

SLOW

FAST

Page 48: Fast Apps and Sites with JavaScript

Best practices for using arrays efficiently

• Pre-allocate arrays• Keep array type consistent• Use typed arrays when possible• Keep arrays dense• Enumerate arrays efficiently

Page 49: Fast Apps and Sites with JavaScript

Principle #5Do less (cross-subsystem) work

Page 50: Fast Apps and Sites with JavaScript

Avoid chattiness with the DOM

...//for each rotationdocument.body.game.getElementById(elID).classList.remove(oldClass)document.body.game.getElementById(elID).classList.add(newClass)...

var element = document.getElementById(elID).classList;

//for each rotationelement.remove(oldClass)element.add(newClass)...

JavaScript

DOM

JavaScript

DOM

Page 51: Fast Apps and Sites with JavaScript

Avoid automatic conversions of DOM valuesValues from DOM are strings by defaultthis.boardSize = document.getElementById("benchmarkBox").value;

for (var i = 0; i < this.boardSize; i++) { //this.boardSize is “25” for (var j = 0; j < this.boardSize; j++) { //this.boardSize is “25” ... }}

this.boardSize = parseInt(document.getElementById("benchmarkBox").value);

for (var i = 0; i < this.boardSize; i++) { //this.boardSize is 25 for (var j = 0; j < this.boardSize; j++) { //this.boardSize is 25 ... }}

FAST(25% marshalling cost reduction in init function)

SLOW

Page 52: Fast Apps and Sites with JavaScript

Paint as much as your users can seeAlign timers to display frames

setInterval(animate, 0);setTimeout(animate, 0);

requestAnimationFrame(animate);

setInterval(animate, 1000 / 60);setTimeout(animate, 1000 / 60);

MORE WORK

LESS WORK

Page 53: Fast Apps and Sites with JavaScript

Let’s fix…

Raw JS code: http://aka.ms/FastJS

Page 54: Fast Apps and Sites with JavaScript

ResultsSave CPU cycles

75% 65

%

setTimeout(animate, 0); requestAnimationFrame(animate);

Page 55: Fast Apps and Sites with JavaScript

Problem solved…Why performance matters?

• Great user experience• Longer battery life• Make your apps richer

Optimized JS code: http://aka.ms/FasterJS

Page 56: Fast Apps and Sites with JavaScript

In-review: Writing fast sites & apps with JavaScriptUnderstand and target modern engines• Principle#1: Stay lean – use less memory

• Principle#2: Use fast objects and do fast manipulations

• Principle#3: Write fast arithmetic

• Principle#4: Use fast arrays

• Principle#5: Do less (cross-subsystem) work

Page 57: Fast Apps and Sites with JavaScript

DEV-314: TypeScript: Application-Scale JavaScript, Anders Hejlsberg

WCL-066: New IE Developer Tools, Jonathan Carter and Carl Edlund

WCL-067: New Platform Capabilities for Advancing Web Development, Israel Hilerio

WCL-068: Web Runtime Performance, Tobin Titus WCL-071: Lighting up your site on Windows 8.1, Jacob Rossi WCL-072: Hyper-fast web graphics with WebGL, Frank Oliver DEV-312:Diagnosing issues in JavaScript Windows Store

Apps with Visual Studio, Andrew Hall WCL-073: Inspecting & Debugging Using IE’s New F12

Developer Tools, Andy Sterland and Will Kennedy DEV-316: Developing high performance websites and

modern apps with JavaScript performance tools, Jonathan Carter

IE Blog: http://blogs.msdn.com/ie

Go forth and code it … !!!

Page 58: Fast Apps and Sites with JavaScript

Q&AThanks for

attending/watching!!!

Page 59: Fast Apps and Sites with JavaScript

Evaluate this session

Scan this QR code to evaluate this session and be automatically entered in a drawing to win a prize!

Page 60: Fast Apps and Sites with JavaScript

© 2012 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.