SlideShare a Scribd company logo
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
PAGE 2

Who am I?

 Developer Evangelist at Microsoft based in Silicon Valley, CA
 Blog: http://blogs.msdn.com/b/dorischen/
 Twitter @doristchen
 Email: doris.chen@microsoft.com
 Office Hours http://ohours.org/dorischen
 Has over 15 years of experience in the software industry focusing
on web technologies
 Spoke and published widely at JavaOne, O'Reilly, Silicon Valley
Code Camp, SD West, SD Forum and worldwide User Groups
meetings
 Doris received her Ph.D. from the University of California at Los
Angeles (UCLA)
Blog http://blogs.msdn.com/dorischen
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Tips & tricks that still work

http://channel9.msdn.com/Events/Build/2012/3-132
User innerHTML to Create your DOM
Use DOM Efficiently

function InsertUsername()
{
document.getElementById('user').innerHTML =
userName;
}
Avoid Inline JavaScript
Efficiently Structure Markup

<html>
<head>
<script type="text/javascript">
function helloWorld() {
alert('Hello World!') ;
}
</script>
</head>
<body>
…
</body>
</html>
JSON Always Faster than XML for Data
XML Representation

<!DOCTYPE glossary PUBLIC "DocBook V3.1">
<glossary><title>example glossary</title>
<GlossDiv><title>S</title>
<GlossList>
<GlossEntry ID="SGML" SortAs="SGML">
<GlossTerm>Markup Language</GlossTerm>
<Acronym>SGML</Acronym>
<Abbrev>ISO 8879:1986</Abbrev>
<GlossDef>
<para>meta-markup language</para>
<GlossSeeAlso OtherTerm="GML">
<GlossSeeAlso OtherTerm="XML">
</GlossDef>
<GlossSee OtherTerm="markup">
</GlossEntry>
</GlossList>
</GlossDiv>
</glossary>

JSON Representation
"glossary":{
"title": "example glossary", "GlossDiv":{
"title": "S", "GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "meta-markup language",
"GlossSeeAlso": ["GML", "XML"] },
"GlossSee": "markup" }
}
}
}
Use Native JSON Methods
Write Fast JavaScript

Native JSON Methods
var jsObjStringParsed = JSON.parse(jsObjString);
var jsObjStringBack = JSON.stringify(jsObjStringParsed);
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Raw JS code: http://aka.ms/FastJS
Demo
High Five
Components and control flow

Repeat until neighbors list empty

Arrays

Objects and
properties

Numbers

Memory allocations

Animation loop
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Always start with a good profiler

F12 UI Responsiveness Tool

Windows Performance Toolkit
http://aka.ms/WinPerfKit
IE (Pipeline)
DMANIP
Hit Testing
Data
&State

Input

DOM
Tree
1
Networking

Display Tree
1

2

Parsers

3

7
4

5

8

Formatting

9

6

DOM API
& Capabilities

JavaScript

Layout

2
3

7
4

5

8
6

9

Painting

Compositing
Do we expect so much of GC to happen?
GC
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
What triggers a garbage collection?
•

Every call to new or implicit memory allocation reserves GC memory

•

When the pool is exhausted, engines force a collection

•

Be careful with object allocation patterns in your apps

- Allocations are cheap until current pool is exhausted

- Collections cause program pauses
- Pauses could take milliseconds

- Every allocation brings you closer to a GC pause
demo
Results

•
•

Overall FG GC time reduced to 1/3rd
Raw JavaScript perf improved ~3x
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
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Internal Type System: Fast Object Types
var p1;
p1.north = 1;
p1.south = 0;

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

Base Type “{}”

Type “{north}”

Type “{north, south}”

Base Type “{}”

north

1

south

0

north

1

south

0

south

0

north

1

Type “{south}”

Type “{south, north}”
Create fast types and avoid type mismatches
Don’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;
}
...
}

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

var p1 = new Player(“NE”);
var p2 = new Player(“ES”);

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 {n,e}
// p2 type {e,s}

p1.type != p2.type

p1.type == p2.type
Create fast types and avoid type mismatches
Don’t default properties on prototypes
function Player(name) {
...
};

Player.prototype.n
Player.prototype.e
Player.prototype.s
Player.prototype.w

=
=
=
=

function
this.n
this.e
this.s
this.w
...
}

null;
null;
null;
null;

Player(name) {
= null;
= null;
= null;
= null;

var p1 = new Player("Jodi");
var p2 = new Player("Mia");
var p3 = new Player("Jodi");

//p1 type{}
//p2 type{}
//p3 type{}

var p1 = new Player("Jodi");
var p2 = new Player("Mia");
var p3 = new Player("Jodi");

//p1 type{n,e,s,w}
//p2 type{n,e,s,w}
//p3 type{n,e,s,w}

p1.n = 1;
p2.e = 1;

//p1 type {n}
//p2 type {e}

p1.n = 1;
p2.e = 1;

//p1 type{n,e,s,w}
//p2 type{n,e,s,w}

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

p1.type == p2.type == p3.type
Internal Type System: Slower Property Bags
var p1 = new Player(); //prop
bag
p1.north = 1;
p1.south = 1;

Slower Bag “{p1}”

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

Slower Bag “{p2}”
Avoid conversion from fast type to slower property bags
Deleting properties forces conversion

function
this.n
this.e
this.s
this.w
}
var p1 =

Player(north,east,south,west) {
= north;
= east;
= south;
= west;
new Player();

delete p1.n;

function
this.n
this.e
this.s
this.w
}
var p1 =

Player(north,east,south,west) {
= north;
= east;
= south;
= west;

p1.n = 0;

SLOW

new Player();

// or undefined

FAST
Avoid creating slower property bags
Add properties in constructor, restrict total properties

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

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();

var p1 = new Player();

SLOW

FAST
Avoid creating slower property bags

Restrict 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;
...

SLOW

function
this.n
this.e
this.s
this.w
...
}

Player(north, east, south, west) {
= north;
= east;
= south;
= west;

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

FAST
demo
Results
3.8s

•
•

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

2.2s
Best practices for fast objects and manipulations

• Create and use fast types
• Keep shapes of objects consistent
• Avoid type mismatches for fast types
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Numbers in JavaScript
• All numbers are IEEE 64-bit floating point numbers
- Great for flexibility
- Performance and optimization challenge
31 bits

Object pointer
31 bits

31-bit (tagged) Integers
STACK
FIXED LENGTH, FASTER ACCESS

1 bit

0

1 bit

Boxed

32 bits

Floats
32-bit Integers

32 bits

1

HEAP
VARIABLE LENGTH, SLOWER ACCESS
Use 31-bit integers for faster arithmetic
STACK
var north = 1;

north:
east:

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

0x005e4148

south:

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

0x00000003

0x005e4160

west:

0x005e4170

HEAP
SLOW

String
“east”

SLOW

Number
SLOW

0.1

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

Number

0x005e4148:
0x03 represents 1:

0…01001000
0…00000011

0x1
Avoid creating floats if they are not needed
Fastest way to indicate integer math is |0
var r = 0;

var r = 0;

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

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

// r = 3.5

SLOW
STACK
r:

0x005e4148

SLOW

FAST
STACK

HEAP
Number

r:

0x00000007

3.5

r:

0x00000009

// r = 3
// r = 4
Take advantage of type-specialization for arithmetic
Create separate functions for ints and floats; use consistent argument types
function
var dx
var dy
var d2
return
}

var
var
var
var

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

point1
point2
point3
point4

=
=
=
=

{x:10, y:10};
{x:20, y:20};
{x:1.5, y:1.5};
{x:0x0AB, y:0xBC};

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

SLOW

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);

FAST
Best practices for fast arithmetic
• Use 31-bit integer math when possible
• Avoid floats if they are not needed
• Design for type specialized arithmetic
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Chakra: Array internals
Type: Int Array

01
02
03
04

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

1

Type: Float
Array

1

2.3

Type: Var Array

1

2.3

“str”
Pre-allocate arrays
var a = new Array();
for (var i = 0; i < 100; i++) {
a.push(i + 2);
}

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

FAST

SLOW

0

?
0

?+1

??

…

100
For mixed arrays, provide an early hint
Avoid delayed type conversion and copy

var a = new Array(100000);

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

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

FAST
Use Typed Arrays when possible

Avoids tagging of integers and allocating heap space for floats

var value = 5;

var value = 5;

var a = new Array(100);
a[0] = value;
a[1] = value / 2;
a[2] = "text";

// 5
- tagged
// 2.5
- boxed
// "text" – var array

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

SLOW

FAST
Keep values in arrays consistent
Numeric arrays treated like Typed Arrays internally
var a = [1,0x2,99.1,5];
var b = [0x10,8,9];
function add(a,i,b,j)
{
return a[i] + b[j];
}
add(a,0,b,0);
add(a,1,b,1);

SLOW

//mixed array
//mixed array

var a = [1,5,8,9];
var b = [0x02,0x10,99.1];
array
function add(a,i,b,j)
{
return a[i] + b[j];
}
add(a,0,b,0);
add(a,1,b,1);

FAST

//int array
//float
Keep arrays dense

Deleting 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];
}

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

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

SLOW

FAST
Enumerate arrays efficiently

Explicit caching of length avoids repetitive property accesses
var a = new Array(100);
var total = 0;

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

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

cachedLength = a.length;

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

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

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

SLOW

FAST
Best practices for using arrays efficiently

•
•
•
•
•

Pre-allocate arrays
Keep array type consistent
Use typed arrays when possible
Keep arrays dense
Enumerate arrays efficiently
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Avoid chattiness with the DOM
...
//for each rotation
document.body.game.getElementById(elID).classList.remove(oldClass)
document.body.game.getElementById(elID).classList.add(newClass)
...

JavaScript

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

JavaScript

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

DOM

DOM
Avoid automatic conversions of DOM values
Values from DOM are strings by default

this.boardSize = document.getElementById("benchmarkBox").value;
for (var i = 0; i < this.boardSize; i++) {
“25”
for (var j = 0; j < this.boardSize; j++) {
“25”
...
}
}

//this.boardSize is

SLOW

//this.boardSize is

this.boardSize = parseInt(document.getElementById("benchmarkBox").value);
for (var i = 0; i < this.boardSize; i++) {
for (var j = 0; j < this.boardSize; j++) {
...
}
}

//this.boardSize is 25
//this.boardSize is 25

FAST

(25% marshalling cost
reduction in init function)
Paint as much as your users can see
Align timers to display frames

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

MORE WORK

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

LESS WORK
demo
Results

Save CPU cycles
setTimeout(animate,

75%

0);

requestAnimationFrame(animate);

65%
Optimized JS code: http://aka.ms/FasterJS
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
PAGE 61
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Splash screen

New host
process

App visible

Loading and
parsing
of
HTML, JS, CSS

Ready for
user

Windows Runtime
"activated" event
"DOMContentLoaded" event
Navigation
Tile click
Splash screen

App visible

App ready to use
• Can I eliminate work entirely?
• Can I optimize existing work?
• Can I defer work, or perform it in parallel?
Splash screen

App visible

App ready to use
Loading and Parsing: Package Locally
Optimize your landing Page: Use Local Data
MIME Type: text/cache-manifest
PAGE 80

twitter #devcamp

lab setup: http://bit.ly/html5setup

Blog http://blogs.msdn.com/dorischen
Optimize landing page: Load only what you need
 <script type="text/javascript" src='file1.js'

defer='defer'></script>
Further optimizations
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Join us for this Free, hands-on event and learn how to build a Windows 8.1
and/or Windows Phone game in record time. We’ll cover everything you need
to create, upload and publish an amazing game. Expert developers will outline
different game frameworks and give you the tools you need to start building.
They’ll also explain how to add graphics, level and sound to game starter kits,
while sharing other cool ways to make the game your own. In one jam-packed
day of learning and coding, you can turn your idea into reality!
Register today for a local Game On event.
December 4, 2013

December 5, 2013

San Francisco, CA

Mountain View, CA

http://aka.ms/gameonsf

http://aka.ms/gameonsvc
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
Developing High Performance Websites and Modern Apps with JavaScript and HTML5
http://bit.ly/win8OnePage

http://bit.ly/HTML5Wins8Camp
http://msdn.microsoft.com/en-us/library/windows/apps/hh465194.aspx

http://Aka.ms/brockschmidtbook
 http:/dev.windows.com
PAGE
• Responsive Web Design and CSS3
• http://bit.ly/CSS3Intro
• HTML5, CSS3 Free 1 Day Training
• http://bit.ly/HTML5DevCampDownload
• Using Blend to Design HTML5 Windows 8 Application (Part II): Style,
Layout and Grid
• http://bit.ly/HTML5onBlend2
• Using Blend to Design HTML5 Windows 8 Application (Part III): Style
Game Board, Cards, Support Different Device, View States
• http://bit.ly/HTML5onBlend3

• Feature-specific demos

• http://ie.microsoft.com/testdrive/

• Real-world demos

PAGE

• http://www.beautyoftheweb.com/
Developing High Performance Websites and Modern Apps with JavaScript and HTML5

More Related Content

What's hot (20)

PDF
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
PDF
Haskell in the Real World
osfameron
 
PDF
PHP Performance Trivia
Nikita Popov
 
PDF
Scala introduction
vito jeng
 
PDF
Typed Properties and more: What's coming in PHP 7.4?
Nikita Popov
 
PDF
Nikita Popov "What’s new in PHP 8.0?"
Fwdays
 
PPTX
EcmaScript unchained
Eduard Tomàs
 
ODP
Learn JavaScript by modeling Rubik Cube
Manoj Kumar
 
KEY
Indexing thousands of writes per second with redis
pauldix
 
PDF
Building fast interpreters in Rust
Ingvar Stepanyan
 
PPTX
The Challenge of Bringing FEZ to PlayStation Platforms
Miguel Angel Horna
 
KEY
Exhibition of Atrocity
Michael Pirnat
 
PDF
Scala vs Java 8 in a Java 8 World
BTI360
 
PDF
How to write code you won't hate tomorrow
Pete McFarlane
 
PDF
What's new in PHP 8.0?
Nikita Popov
 
PDF
Opaque Pointers Are Coming
Nikita Popov
 
PPTX
Joy of scala
Maxim Novak
 
PDF
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
Doris Chen
 
PDF
Swift internals
Jung Kim
 
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
Haskell in the Real World
osfameron
 
PHP Performance Trivia
Nikita Popov
 
Scala introduction
vito jeng
 
Typed Properties and more: What's coming in PHP 7.4?
Nikita Popov
 
Nikita Popov "What’s new in PHP 8.0?"
Fwdays
 
EcmaScript unchained
Eduard Tomàs
 
Learn JavaScript by modeling Rubik Cube
Manoj Kumar
 
Indexing thousands of writes per second with redis
pauldix
 
Building fast interpreters in Rust
Ingvar Stepanyan
 
The Challenge of Bringing FEZ to PlayStation Platforms
Miguel Angel Horna
 
Exhibition of Atrocity
Michael Pirnat
 
Scala vs Java 8 in a Java 8 World
BTI360
 
How to write code you won't hate tomorrow
Pete McFarlane
 
What's new in PHP 8.0?
Nikita Popov
 
Opaque Pointers Are Coming
Nikita Popov
 
Joy of scala
Maxim Novak
 
OSCON Presentation: Developing High Performance Websites and Modern Apps with...
Doris Chen
 
Swift internals
Jung Kim
 

Similar to Developing High Performance Websites and Modern Apps with JavaScript and HTML5 (20)

PDF
Say It With Javascript
Giovanni Scerra ☃
 
PDF
Js objects
anubavam-techkt
 
PDF
The Future of JavaScript (Ajax Exp '07)
jeresig
 
PPTX
Advanced JavaScript
Zsolt Mészárovics
 
PDF
Introduction to web programming for java and c# programmers by @drpicox
David Rodenas
 
PDF
JavaScript: enter the dragon
Dmitry Baranovskiy
 
PPTX
IWT presentation121232112122222225556+556.pptx
dgfs55437
 
PPTX
Object Oriented JavaScript
Julie Iskander
 
PPT
JavaScript Needn't Hurt!
Thomas Kjeldahl Nilsson
 
PPTX
ES6: Features + Rails
Santosh Wadghule
 
PPTX
JavaScript (without DOM)
Piyush Katariya
 
PPTX
JavaScript front end performance optimizations
Chris Love
 
PPT
Beginning Object-Oriented JavaScript
Stoyan Stefanov
 
PDF
ECMAScript2015
qmmr
 
PDF
How much performance can you get out of Javascript? - Massimiliano Mantione -...
Codemotion
 
PPTX
Object oriented javascript
Shah Jalal
 
PPTX
TypeScript by Howard
LearningTech
 
PPTX
Howard type script
LearningTech
 
PDF
Stuff you didn't know about action script
Christophe Herreman
 
Say It With Javascript
Giovanni Scerra ☃
 
Js objects
anubavam-techkt
 
The Future of JavaScript (Ajax Exp '07)
jeresig
 
Advanced JavaScript
Zsolt Mészárovics
 
Introduction to web programming for java and c# programmers by @drpicox
David Rodenas
 
JavaScript: enter the dragon
Dmitry Baranovskiy
 
IWT presentation121232112122222225556+556.pptx
dgfs55437
 
Object Oriented JavaScript
Julie Iskander
 
JavaScript Needn't Hurt!
Thomas Kjeldahl Nilsson
 
ES6: Features + Rails
Santosh Wadghule
 
JavaScript (without DOM)
Piyush Katariya
 
JavaScript front end performance optimizations
Chris Love
 
Beginning Object-Oriented JavaScript
Stoyan Stefanov
 
ECMAScript2015
qmmr
 
How much performance can you get out of Javascript? - Massimiliano Mantione -...
Codemotion
 
Object oriented javascript
Shah Jalal
 
TypeScript by Howard
LearningTech
 
Howard type script
LearningTech
 
Stuff you didn't know about action script
Christophe Herreman
 
Ad

More from Doris Chen (20)

PDF
Practical tipsmakemobilefaster oscon2016
Doris Chen
 
PDF
Building Web Sites that Work Everywhere
Doris Chen
 
PDF
Angular mobile angular_u
Doris Chen
 
PDF
Lastest Trends in Web Development
Doris Chen
 
PDF
Angular or Backbone: Go Mobile!
Doris Chen
 
PDF
Practical Performance Tips and Tricks to Make Your HTML/JavaScript Apps Faster
Doris Chen
 
PDF
What Web Developers Need to Know to Develop Native HTML5/JS Apps
Doris Chen
 
PDF
Windows 8 Opportunity
Doris Chen
 
PDF
Wins8 appfoforweb fluent
Doris Chen
 
PDF
Develop High Performance Windows 8 Application with HTML5 and JavaScriptHigh ...
Doris Chen
 
PDF
What Web Developers Need to Know to Develop Windows 8 Apps
Doris Chen
 
PDF
Building Beautiful and Interactive Metro apps with JavaScript, HTML5 & CSS3
Doris Chen
 
PDF
Building Beautiful and Interactive Windows 8 apps with JavaScript, HTML5 & CSS3
Doris Chen
 
PDF
Introduction to CSS3
Doris Chen
 
PDF
Building Beautiful and Interactive Metro apps with JavaScript, HTML5 & CSS3
Doris Chen
 
PDF
Practical HTML5: Using It Today
Doris Chen
 
PDF
Dive Into HTML5
Doris Chen
 
PDF
Practical HTML5: Using It Today
Doris Chen
 
PDF
HTML 5 Development for Windows Phone and Desktop
Doris Chen
 
PDF
Dive into HTML5: SVG and Canvas
Doris Chen
 
Practical tipsmakemobilefaster oscon2016
Doris Chen
 
Building Web Sites that Work Everywhere
Doris Chen
 
Angular mobile angular_u
Doris Chen
 
Lastest Trends in Web Development
Doris Chen
 
Angular or Backbone: Go Mobile!
Doris Chen
 
Practical Performance Tips and Tricks to Make Your HTML/JavaScript Apps Faster
Doris Chen
 
What Web Developers Need to Know to Develop Native HTML5/JS Apps
Doris Chen
 
Windows 8 Opportunity
Doris Chen
 
Wins8 appfoforweb fluent
Doris Chen
 
Develop High Performance Windows 8 Application with HTML5 and JavaScriptHigh ...
Doris Chen
 
What Web Developers Need to Know to Develop Windows 8 Apps
Doris Chen
 
Building Beautiful and Interactive Metro apps with JavaScript, HTML5 & CSS3
Doris Chen
 
Building Beautiful and Interactive Windows 8 apps with JavaScript, HTML5 & CSS3
Doris Chen
 
Introduction to CSS3
Doris Chen
 
Building Beautiful and Interactive Metro apps with JavaScript, HTML5 & CSS3
Doris Chen
 
Practical HTML5: Using It Today
Doris Chen
 
Dive Into HTML5
Doris Chen
 
Practical HTML5: Using It Today
Doris Chen
 
HTML 5 Development for Windows Phone and Desktop
Doris Chen
 
Dive into HTML5: SVG and Canvas
Doris Chen
 
Ad

Recently uploaded (20)

PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
Designing_the_Future_AI_Driven_Product_Experiences_Across_Devices.pptx
presentifyai
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PPTX
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
PDF
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PPTX
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PDF
“Computer Vision at Sea: Automated Fish Tracking for Sustainable Fishing,” a ...
Edge AI and Vision Alliance
 
PPTX
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
PPT
Ericsson LTE presentation SEMINAR 2010.ppt
npat3
 
PDF
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
PDF
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
PDF
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
 
PDF
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Designing_the_Future_AI_Driven_Product_Experiences_Across_Devices.pptx
presentifyai
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
MuleSoft MCP Support (Model Context Protocol) and Use Case Demo
shyamraj55
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
“Computer Vision at Sea: Automated Fish Tracking for Sustainable Fishing,” a ...
Edge AI and Vision Alliance
 
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
Ericsson LTE presentation SEMINAR 2010.ppt
npat3
 
Kit-Works Team Study_20250627_한달만에만든사내서비스키링(양다윗).pdf
Wonjun Hwang
 
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
UiPath DevConnect 2025: Agentic Automation Community User Group Meeting
DianaGray10
 
The 2025 InfraRed Report - Redpoint Ventures
Razin Mustafiz
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 

Developing High Performance Websites and Modern Apps with JavaScript and HTML5

  • 2. PAGE 2 Who am I?  Developer Evangelist at Microsoft based in Silicon Valley, CA  Blog: http://blogs.msdn.com/b/dorischen/  Twitter @doristchen  Email: [email protected]  Office Hours http://ohours.org/dorischen  Has over 15 years of experience in the software industry focusing on web technologies  Spoke and published widely at JavaOne, O'Reilly, Silicon Valley Code Camp, SD West, SD Forum and worldwide User Groups meetings  Doris received her Ph.D. from the University of California at Los Angeles (UCLA) Blog http://blogs.msdn.com/dorischen
  • 5. Tips & tricks that still work http://channel9.msdn.com/Events/Build/2012/3-132
  • 6. User innerHTML to Create your DOM Use DOM Efficiently function InsertUsername() { document.getElementById('user').innerHTML = userName; }
  • 7. Avoid Inline JavaScript Efficiently Structure Markup <html> <head> <script type="text/javascript"> function helloWorld() { alert('Hello World!') ; } </script> </head> <body> … </body> </html>
  • 8. JSON Always Faster than XML for Data XML Representation <!DOCTYPE glossary PUBLIC "DocBook V3.1"> <glossary><title>example glossary</title> <GlossDiv><title>S</title> <GlossList> <GlossEntry ID="SGML" SortAs="SGML"> <GlossTerm>Markup Language</GlossTerm> <Acronym>SGML</Acronym> <Abbrev>ISO 8879:1986</Abbrev> <GlossDef> <para>meta-markup language</para> <GlossSeeAlso OtherTerm="GML"> <GlossSeeAlso OtherTerm="XML"> </GlossDef> <GlossSee OtherTerm="markup"> </GlossEntry> </GlossList> </GlossDiv> </glossary> JSON Representation "glossary":{ "title": "example glossary", "GlossDiv":{ "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "meta-markup language", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } }
  • 9. Use Native JSON Methods Write Fast JavaScript Native JSON Methods var jsObjStringParsed = JSON.parse(jsObjString); var jsObjStringBack = JSON.stringify(jsObjStringParsed);
  • 11. Raw JS code: http://aka.ms/FastJS
  • 13. Components and control flow Repeat until neighbors list empty Arrays Objects and properties Numbers Memory allocations Animation loop
  • 15. Always start with a good profiler F12 UI Responsiveness Tool Windows Performance Toolkit http://aka.ms/WinPerfKit
  • 16. IE (Pipeline) DMANIP Hit Testing Data &State Input DOM Tree 1 Networking Display Tree 1 2 Parsers 3 7 4 5 8 Formatting 9 6 DOM API & Capabilities JavaScript Layout 2 3 7 4 5 8 6 9 Painting Compositing
  • 17. Do we expect so much of GC to happen? GC
  • 19. What triggers a garbage collection? • Every call to new or implicit memory allocation reserves GC memory • When the pool is exhausted, engines force a collection • Be careful with object allocation patterns in your apps - Allocations are cheap until current pool is exhausted - Collections cause program pauses - Pauses could take milliseconds - Every allocation brings you closer to a GC pause
  • 20. demo
  • 21. Results • • Overall FG GC time reduced to 1/3rd Raw JavaScript perf improved ~3x
  • 22. 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
  • 24. Internal Type System: Fast Object Types var p1; p1.north = 1; p1.south = 0; var p2; p2.south = 0; p2.north = 1; Base Type “{}” Type “{north}” Type “{north, south}” Base Type “{}” north 1 south 0 north 1 south 0 south 0 north 1 Type “{south}” Type “{south, north}”
  • 25. Create fast types and avoid type mismatches Don’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; } ... } function Player(north,east,south,west) { this.n = north; this.e = east; this.s = south; this.w = west; } var p1 = new Player(“NE”); var p2 = new Player(“ES”); 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 {n,e} // p2 type {e,s} p1.type != p2.type p1.type == p2.type
  • 26. Create fast types and avoid type mismatches Don’t default properties on prototypes function Player(name) { ... }; Player.prototype.n Player.prototype.e Player.prototype.s Player.prototype.w = = = = function this.n this.e this.s this.w ... } null; null; null; null; Player(name) { = null; = null; = null; = null; var p1 = new Player("Jodi"); var p2 = new Player("Mia"); var p3 = new Player("Jodi"); //p1 type{} //p2 type{} //p3 type{} var p1 = new Player("Jodi"); var p2 = new Player("Mia"); var p3 = new Player("Jodi"); //p1 type{n,e,s,w} //p2 type{n,e,s,w} //p3 type{n,e,s,w} p1.n = 1; p2.e = 1; //p1 type {n} //p2 type {e} p1.n = 1; p2.e = 1; //p1 type{n,e,s,w} //p2 type{n,e,s,w} p1.type != p2.type != p3.type p1.type == p2.type == p3.type
  • 27. Internal Type System: Slower Property Bags var p1 = new Player(); //prop bag p1.north = 1; p1.south = 1; Slower Bag “{p1}” var p2 = new Player(); //prop bag p2.north = 1; p2.south = 1; Slower Bag “{p2}”
  • 28. Avoid conversion from fast type to slower property bags Deleting properties forces conversion function this.n this.e this.s this.w } var p1 = Player(north,east,south,west) { = north; = east; = south; = west; new Player(); delete p1.n; function this.n this.e this.s this.w } var p1 = Player(north,east,south,west) { = north; = east; = south; = west; p1.n = 0; SLOW new Player(); // or undefined FAST
  • 29. Avoid creating slower property bags Add properties in constructor, restrict total properties function Player() { this.prop01 = 1; this.prop02 = 2; ... this.prop256 = 256; ... // Do you need an array? } 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(); var p1 = new Player(); SLOW FAST
  • 30. Avoid creating slower property bags Restrict 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; ... SLOW function this.n this.e this.s this.w ... } Player(north, east, south, west) { = north; = east; = south; = west; var p = new Player(1,1,0,0); var n = p.n; p.n = 0; ... FAST
  • 31. demo
  • 32. Results 3.8s • • Time in script execution reduced ~30% Raw JS performance improved ~30% 2.2s
  • 33. Best practices for fast objects and manipulations • Create and use fast types • Keep shapes of objects consistent • Avoid type mismatches for fast types
  • 35. Numbers in JavaScript • All numbers are IEEE 64-bit floating point numbers - Great for flexibility - Performance and optimization challenge 31 bits Object pointer 31 bits 31-bit (tagged) Integers STACK FIXED LENGTH, FASTER ACCESS 1 bit 0 1 bit Boxed 32 bits Floats 32-bit Integers 32 bits 1 HEAP VARIABLE LENGTH, SLOWER ACCESS
  • 36. Use 31-bit integers for faster arithmetic STACK var north = 1; north: east: function Player(north, south, east, west) { ... } 0x005e4148 south: var east = "east"; var south = 0.1; var west = 0x1; 0x00000003 0x005e4160 west: 0x005e4170 HEAP SLOW String “east” SLOW Number SLOW 0.1 var p = new Player(north,south,east,west); Number 0x005e4148: 0x03 represents 1: 0…01001000 0…00000011 0x1
  • 37. Avoid creating floats if they are not needed Fastest way to indicate integer math is |0 var r = 0; var r = 0; function doMath(){ var a = 5; var b = 2; r = ((a + b) / 2); } ... var intR = Math.floor(r); function doMath(){ var a = 5; var b = 2; r = ((a + b) / 2) |0 ; r = Math.round((a + b) / 2); } // r = 3.5 SLOW STACK r: 0x005e4148 SLOW FAST STACK HEAP Number r: 0x00000007 3.5 r: 0x00000009 // r = 3 // r = 4
  • 38. Take advantage of type-specialization for arithmetic Create separate functions for ints and floats; use consistent argument types function var dx var dy var d2 return } var var var var Distance(p1, p2) { = p1.x - p2.x; = p1.y - p2.y; = dx * dx + dy * dy; Math.sqrt(d2); point1 point2 point3 point4 = = = = {x:10, y:10}; {x:20, y:20}; {x:1.5, y:1.5}; {x:0x0AB, y:0xBC}; Distance(point1, point3); Distance(point2, point4); SLOW 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); FAST
  • 39. Best practices for fast arithmetic • Use 31-bit integer math when possible • Avoid floats if they are not needed • Design for type specialized arithmetic
  • 41. Chakra: Array internals Type: Int Array 01 02 03 04 var a = new Array(); a[0] = 1; a[1] = 2.3; a[2] = “str”; 1 Type: Float Array 1 2.3 Type: Var Array 1 2.3 “str”
  • 42. Pre-allocate arrays var a = new Array(); for (var i = 0; i < 100; i++) { a.push(i + 2); } var a = new Array(100); for (var i = 0; i < 100; i++) { a[i] = i + 2; } FAST SLOW 0 ? 0 ?+1 ?? … 100
  • 43. For mixed arrays, provide an early hint Avoid delayed type conversion and copy var a = new Array(100000); 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 for (var i = 0; i < a.length; i++) { a[i] = i; } ... //operations on the array ... a[99] = “str”; FAST
  • 44. Use Typed Arrays when possible Avoids tagging of integers and allocating heap space for floats var value = 5; var value = 5; var a = new Array(100); a[0] = value; a[1] = value / 2; a[2] = "text"; // 5 - tagged // 2.5 - boxed // "text" – var array var a = new Float64Array(100); a[0] = value; // 5 - no tagging required a[1] = value / 2; // 2.5 - no boxing required a[2] = "text"; // 0 var a = new Int32Array(100); a[0] = value; // 5 - no tagging required a[1] = value / 2; // 2 - no tagging required a[2] = "text"; // 0 SLOW FAST
  • 45. Keep values in arrays consistent Numeric arrays treated like Typed Arrays internally var a = [1,0x2,99.1,5]; var b = [0x10,8,9]; function add(a,i,b,j) { return a[i] + b[j]; } add(a,0,b,0); add(a,1,b,1); SLOW //mixed array //mixed array var a = [1,5,8,9]; var b = [0x02,0x10,99.1]; array function add(a,i,b,j) { return a[i] + b[j]; } add(a,0,b,0); add(a,1,b,1); FAST //int array //float
  • 46. Keep arrays dense Deleting 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]; } 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 //operating on the array ... matrix[23] = 0; ... //operating on the array SLOW FAST
  • 47. Enumerate arrays efficiently Explicit caching of length avoids repetitive property accesses var a = new Array(100); var total = 0; var a = new Array(100); var total = 0; for (var item in a) { total += item; }; cachedLength = a.length; a.forEach(function(item){ total += item; }); for (var i = 0; i < cachedLength; i++) { total += a[i]; } for (var i = 0; i < a.length; i++) { total += a[i]; } SLOW FAST
  • 48. Best practices for using arrays efficiently • • • • • Pre-allocate arrays Keep array type consistent Use typed arrays when possible Keep arrays dense Enumerate arrays efficiently
  • 50. Avoid chattiness with the DOM ... //for each rotation document.body.game.getElementById(elID).classList.remove(oldClass) document.body.game.getElementById(elID).classList.add(newClass) ... JavaScript var element = document.getElementById(elID).classList; JavaScript //for each rotation element.remove(oldClass) element.add(newClass) ... DOM DOM
  • 51. Avoid automatic conversions of DOM values Values from DOM are strings by default this.boardSize = document.getElementById("benchmarkBox").value; for (var i = 0; i < this.boardSize; i++) { “25” for (var j = 0; j < this.boardSize; j++) { “25” ... } } //this.boardSize is SLOW //this.boardSize is this.boardSize = parseInt(document.getElementById("benchmarkBox").value); for (var i = 0; i < this.boardSize; i++) { for (var j = 0; j < this.boardSize; j++) { ... } } //this.boardSize is 25 //this.boardSize is 25 FAST (25% marshalling cost reduction in init function)
  • 52. Paint as much as your users can see Align timers to display frames requestAnimationFrame(animate); setInterval(animate, 0); setTimeout(animate, 0); MORE WORK setInterval(animate, 1000 / 60); setTimeout(animate, 1000 / 60); LESS WORK
  • 53. demo
  • 55. Optimized JS code: http://aka.ms/FasterJS
  • 61. Splash screen New host process App visible Loading and parsing of HTML, JS, CSS Ready for user Windows Runtime "activated" event "DOMContentLoaded" event Navigation Tile click
  • 63. • Can I eliminate work entirely? • Can I optimize existing work? • Can I defer work, or perform it in parallel?
  • 65. Loading and Parsing: Package Locally
  • 66. Optimize your landing Page: Use Local Data
  • 68. PAGE 80 twitter #devcamp lab setup: http://bit.ly/html5setup Blog http://blogs.msdn.com/dorischen
  • 69. Optimize landing page: Load only what you need  <script type="text/javascript" src='file1.js' defer='defer'></script>
  • 72. Join us for this Free, hands-on event and learn how to build a Windows 8.1 and/or Windows Phone game in record time. We’ll cover everything you need to create, upload and publish an amazing game. Expert developers will outline different game frameworks and give you the tools you need to start building. They’ll also explain how to add graphics, level and sound to game starter kits, while sharing other cool ways to make the game your own. In one jam-packed day of learning and coding, you can turn your idea into reality! Register today for a local Game On event. December 4, 2013 December 5, 2013 San Francisco, CA Mountain View, CA http://aka.ms/gameonsf http://aka.ms/gameonsvc
  • 76. • Responsive Web Design and CSS3 • http://bit.ly/CSS3Intro • HTML5, CSS3 Free 1 Day Training • http://bit.ly/HTML5DevCampDownload • Using Blend to Design HTML5 Windows 8 Application (Part II): Style, Layout and Grid • http://bit.ly/HTML5onBlend2 • Using Blend to Design HTML5 Windows 8 Application (Part III): Style Game Board, Cards, Support Different Device, View States • http://bit.ly/HTML5onBlend3 • Feature-specific demos • http://ie.microsoft.com/testdrive/ • Real-world demos PAGE • http://www.beautyoftheweb.com/