Top Banner
Performance Patterns Stoyan Stefanov JSConfEU Berlin, 2010 http://slideshare.net/stoyan/
82

Performance patterns

Jan 29, 2018

Download

Technology

Stoyan Stefanov
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Performance patterns

Performance Patterns

Stoyan Stefanov JSConfEU Berlin, 2010 http://slideshare.net/stoyan/

Page 2: Performance patterns

About me

YSlow 2.0

Page 3: Performance patterns

Lies,

damn lies,

and performance advise

Page 4: Performance patterns

On the agenda

1.  Understanding the problem 2.  Some pointers/patterns

Page 5: Performance patterns

Moving targets

Page 6: Performance patterns
Page 7: Performance patterns

Moving targets

•  Browsers •  Libraries

•  e.g. IE string concatenation

Page 8: Performance patterns

+= or array.join() var res = '', count = 10000;while (count--) { res += 'a';}

var res = [], count = 10000;while (count--) { res.push('a');}

res = res.join('');

http://jsperf.com/join-concat/

Page 9: Performance patterns

“The Pen is mightier

than the Sword”

* only if the Sword is very small and the Pen very sharp

*

Page 10: Performance patterns

Benchmarks

Page 11: Performance patterns

Commonly…

var start = new Date();// ... go crazy ...var took = new Date() – start;

Page 12: Performance patterns

But…

•  Releasing the thread? •  Updating the page? •  In-memory DOM

operations?

Page 13: Performance patterns

Better…

var start = new Date();// ... go crazy ...setTimeout(function () { var took = new Date() – start; }, 0);

Page 14: Performance patterns

Zero timeout

•  15 ms in IE •  10 in FF, Safari •  4 in Chrome

Page 15: Performance patterns

When benchmarking…

1.  Long enough operations (much longer than 15ms)

2.  200 runs for statistical significance

3.  Filtering outliers 4.  0-timeout end time

Page 16: Performance patterns

Results

•  Average •  Median •  Throw < 25% and >75%

Page 17: Performance patterns

Quarters

¼ ¼ ¼ ¼

Garbage Data Garbage

Page 18: Performance patterns

Benchmarks

•  No need to benchmark browsers

•  Time values not important •  Question is: given A and B,

which way to go? Really? All the time?

Page 19: Performance patterns

JSPerf.com

•  Type in a form •  Test, compare browsers •  Community

Page 20: Performance patterns
Page 21: Performance patterns

How about real life?

Page 22: Performance patterns
Page 23: Performance patterns
Page 24: Performance patterns
Page 25: Performance patterns
Page 26: Performance patterns

Picking the battles

Page 27: Performance patterns

Speeding Up

Page 28: Performance patterns

Speeding Up

1.  Loading 2.  Running

Page 29: Performance patterns

Speeding Up

1.  Loading 2.  Running

Page 30: Performance patterns

Loading – the basics

•  Reducing the # scripts •  Gzip •  Minification •  Expires •  CDN

Page 31: Performance patterns

Loading asynchronously

•  Async === Good •  Progress •  Perception

Page 32: Performance patterns

JavaScript blocks

html

js

png

png

Page 33: Performance patterns

JavaScript at the bottom

html

js

png

png

Page 34: Performance patterns

Non-blocking JavaScript

•  defer and async•  Defer: IE innovation, ok to

delay, but keep order •  Async: HTML5, whatever

<script async src="my.js" onload="doIt()"></script> <script defer src="my.js" onload="doIt()"></script> 

Page 35: Performance patterns

defer and async timeline

DOMContentLoaded load

async

defer

Page 36: Performance patterns

Non-blocking JavaScript

•  Asynchronous JavaScript

var js = document.createElement('script'); js.src = 'myscript.js'; var h = document.getElementsByTagName('head')[0]; h.appendChild(js); 

html

js

png

png

Page 37: Performance patterns

flush() early

html

png

js

css

html

png

js

css

Page 38: Performance patterns

flush() <html><head> <script src="my.js"

type="text/javascript"></script> <link href="my.css"

type="text/css" rel="stylesheet" /></head>

<body> ....

<?php flush() ?>

Page 39: Performance patterns

Progressive rendering Chunk #1

Chunk #2

Chunk #3

x.appendChild(script)

Page 40: Performance patterns

<!doctype html><html><head><title>My App</title></head><body> <div id="header"> <img src="logo.png" /> ... </div> <!-- end of chunk #1 -->

... The full body of the page ... <!-- end of chunk #2 -->

<script src="all_20100925.js"></script></body></html> <!-- end of chunk #3 -->

Page 41: Performance patterns

Script injection patterns document.getElementsByTagName("head")[0] .appendChild(script);

document.documentElement.firstChild.appendChild(script);

document.body.appendChild(script);

var first_script = document .getElementsByTagName('script')[0];first_script.parentNode .insertBefore(script, first_script);

Page 42: Performance patterns

HTTP chunking: not only HTML

Page 43: Performance patterns

HTTP chunking: not only HTML

•  Google Instant •  /*""*/ - delimited JSON

pieces, MXHR anyone? •  Chunk #1 suggestions •  Chunk #2 results

http://tinyurl.com/chunkview

Page 44: Performance patterns

Moar HTML5 attributes

•  ping="http://stats…"•  prefetch="http://later…"

Page 45: Performance patterns

Preload sans execute var preload; if (/*@cc_on!@*/false) { // IE preload = function (file) { new Image().src = file; };} else { preload = function (file) { var obj = document.createElement('object'), body = document.body; obj.width = 0; obj.height = 0; obj.data = file; body.appendChild(obj); };}

Page 46: Performance patterns

Speeding Up

1.  Loading 2.  Running

Page 47: Performance patterns

Runtime performance

1.  Going local 2.  Reusing

aka caching, aka DRY

Page 48: Performance patterns

Runtime performance

1.  Going local 2.  Reusing

Page 49: Performance patterns

Local variables

•  globals are all sorts of bad

•  use var 

•  localize globals

Page 50: Performance patterns

Local variables

var a = 1; (function (){ var a = 2; function b(){ var a = 3; alert(a); } b(); })(); // 3

Page 51: Performance patterns

Local variables

var a = 1; (function (){ var a = 2; function b(){ // var a = 3; alert(a); } b(); })(); // 2

Page 52: Performance patterns

Local variables

var a = 1; (function (){ // var a = 2; function b(){ // var a = 3; alert(a); } b(); })(); // 1

Page 53: Performance patterns

Local variables

•  less crawling up the scope chain

•  helps minification

Page 54: Performance patterns

Localization

var mamodule = (function () {

window... document... otherModule...

}());

Page 55: Performance patterns

Localization

var mamodule = (function (g, d, om) {

g... // global d... // document reference om... // another common module

}(this, document, otherModule));

Page 56: Performance patterns

Runtime performance

1.  Going local 2.  Reusing, aka caching

Page 57: Performance patterns

Init-time branching

•  Before… 

function myEvent(el, type, fn) { if (window.addEventListener) { el.addEventListener(type, fn, false); } else if (window.attachEvent) { el.attachEvent("on" + type, fn); } else {...}

Page 58: Performance patterns

Init-time branching

•  After… 

if (window.addEventListener) { var myEvent = function (el, type, fn) { el.addEventListener(type, fn, false); }} else if (window.attachEvent) { var myEvent = function (el, type, fn) { el.attachEvent("on" + type, fn); }}

Page 59: Performance patterns

Memoization

•  for expensive, repeating tasks

function myFunc(param){ if (!myFunc.cache) { myFunc.cache = {}; } if (!myFunc.cache[param]) { var result = {}; // ... myFunc.cache[param] = result; } return myFunc.cache[param];}

Page 60: Performance patterns

Memoization – other options

•  in a closure •  offline

Page 61: Performance patterns

•  Before…

var inherit = function (C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C;};

Classical inheritance

Page 62: Performance patterns

Classical inheritance

•  After…

var inherit = (function () { var F = function () {}; return function (C, P) { F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C; }}());

http://jsperf.com/holy-grail-classical-reuse

Page 63: Performance patterns

Regex loops

•  Before…

var i = 1000, dude;

while (i--) { dude = /[a-z]/.test('duderino');};

Page 64: Performance patterns

Regex loops

•  After…

var i = 1000, dude, re = /[a-z]/;

while (i--) { dude = re.test('duderino');}

http://jsperf.com/regexp-loops

Page 65: Performance patterns

Cashing lengths in loops

•  before…

var a = [];

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

Page 66: Performance patterns

Cashing lengths in loops

•  later…

var a = [], i = 0;

for (; i < a.length; i += 1) { console.log(a[i]);}

Page 67: Performance patterns

Cashing lengths in loops

•  after…

var a = [], i = 0, len = a.length;

for (; i < len; i += 1) { console.log(a[i]);}

Page 68: Performance patterns

Cashing lengths in loops

•  alternatively…

var a = [], i = a.length;

while (i--) { console.log(a[i]);}

Page 69: Performance patterns

DOM

Page 70: Performance patterns

DOM – case A // bad var count = 0;for (; count < 15000; count += 1) {

document.getElementById('here').innerHTML += 'a';

}

// DOM access = (1 get + 1 set) * 15000

Page 71: Performance patterns

DOM – case B // bettervar count = 0, content = ''; for (; count < 15000; count += 1) {

content += 'a';

}document.getElementById('here').innerHTML += content;

// DOM access: get + set

Page 72: Performance patterns

How bad is A compared to B? IE

6

IE 7

IE 8

Fire

fox

3

Fire

fox

3.5

Safa

ri 3.

2

Safa

ri 4

Ch

rom

e 2

Ch

rom

e 3

Op

era

9.6

4

Op

era

10

Page 73: Performance patterns

DOMland ECMAland

Page 74: Performance patterns

DOM is slow

Page 75: Performance patterns

Proxy Design Pattern

Page 76: Performance patterns

Proxy pattern

•  One object acts as an interface to another

Page 77: Performance patterns

Proxy pattern

Page 78: Performance patterns

Proxy pattern

Page 79: Performance patterns

Proxy pattern

Page 80: Performance patterns

Proxy pattern

Page 81: Performance patterns

Words of Wisdom

•  Ask why? How? •  Load quickly and async •  Don’t touch the DOM •  Go local

Page 82: Performance patterns

Thank you!

Stoyan Stefanov @stoyanstefanov http://www.phpied.com