Transcript
Page 1: Web Performance Part 4  "Client-side performance"

Client-side performance

Mykyta Semenistyi

Page 2: Web Performance Part 4  "Client-side performance"

Table of contents

1. Perceived performance

2. Build systems

3. JavaScript

4. Data caching

5. CSS, rendering and fonts

6. DOM

7. Frameworks tweaking

8. Image optimizations

Page 3: Web Performance Part 4  "Client-side performance"

Perceived performance

0.1sfeels instantaneously

1smental context switch

10sinterest in dialog loss

JAKOB NIELSEN on January 1, 1993

Page 4: Web Performance Part 4  "Client-side performance"

Content loading

might not be loaded at once

Page 5: Web Performance Part 4  "Client-side performance"

Visual feedback

Icons by Seth Coelen http://dribbble.com/shots/1167728-PSD-CSS-Button-State-Workfiles

Page 6: Web Performance Part 4  "Client-side performance"

Instant Click

how long ago you gave yourself away

pjax-powered

Page 7: Web Performance Part 4  "Client-side performance"

Sleeping Devices

Page Visibility API hypnos

IE10+, FF 27+, Chrome 31+, iOS 7, Android 4.4, IEMobile 10, Safari 7+

visibilitychange event

hidden

Page 8: Web Performance Part 4  "Client-side performance"

Build systems

Grunt Gulp Broccoli

Page 9: Web Performance Part 4  "Client-side performance"

Build systemsOptimize images Generate sprites

Convert images Concatenate css, js,html

Minify css, js,html Inline css

Compress static files ...

Page 10: Web Performance Part 4  "Client-side performance"

JS performance

“Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at

efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time; premature optimization is the root of all evil. Yet we

should not pass up our opportunities in that critical 3%.”

Donald Knuth, Structured Programming With go to Statements

Page 11: Web Performance Part 4  "Client-side performance"

var person = { name: "Nicholas", age: 30};

function displayInfo(){ var count = 5; with(person){ alert(name + " is " + age); alert("Count is " + count); }}

displayInfo();

Execution context

Nicholas C. Zakas - Writing Efficient JavaScript: Chapter 7 - Even Faster Websites

Page 12: Web Performance Part 4  "Client-side performance"

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

var len = theArray.length;for (var i = 0; i < len; i++) { copyOfTheArray[i] = theArray[i];}

With caching:

Without caching:

Loops performance

Page 13: Web Performance Part 4  "Client-side performance"

for (var i in theArray) { copyOfTheArray[i] = theArray[i];}

theArray.forEach(function(it, idx){ copyOfTheArray[idx] = it;});

forEach:

for in:

Loops performance

Page 14: Web Performance Part 4  "Client-side performance"

WebWorkersBring threading to JS

UI Thread:

var worker = new Worker('task.js');worker.addEventListener('message', function(e) { console.log('Worker said: ', e.data);}, false);

worker.postMessage('Hello World');worker.terminate();

Worker:

self.addEventListener('message', function(e) { //e.data === ‘Hello World’; //process data self.postMessage(result);}, false);self.close();

var blob = new Blob([ "onmessage = function(e) { postMessage('msg from worker'); }"]);

// Obtain a blob URL reference to our workervar blobURL = window.URL.createObjectURL(blob);

var worker = new Worker(blobURL);

On fly:

Eric Bidelman http://www.html5rocks.com/en/tutorials/workers/basics/

Page 15: Web Performance Part 4  "Client-side performance"

WebWorkersPeculiarities

Dedicated Sharedavailable within the

creator scriptavailable within the same

domain scriptsWorkers have access to:

● The navigator object● The location object (read-only)● XMLHttpRequest● setTimeout etc.● The Application Cache● Importing external scripts using the importScripts() method● Spawning other web workers

Workers do NOT have access to:

● The DOM (it's not thread-safe)● The window object● The document object● The parent object

Transferrable types:● string● JSON● binary data (File, Blob, ArrayBuffer)

Page 16: Web Performance Part 4  "Client-side performance"

WebWorkersUse cases

Ray TracerVideo/audio

Route Tracer

DNA Analyzing

Page 17: Web Performance Part 4  "Client-side performance"

WebWorkersbut...

Page 18: Web Performance Part 4  "Client-side performance"

Event loop in JSUI Thread

...onclick XHR state change

setTimeout setInterval

onclick XHR state change

setTimeout

Page 19: Web Performance Part 4  "Client-side performance"

Long running scripts

var sum = 0;for (var i = 0; i < 23000000; i++){

sum += Math.random() * i;}

chunks

by count

by time

if (Date.now() - start > 100){ setTimeout(process);} else { process();}

if (i % 10000 === 0){ setTimeout(process);} else { process();}

Page 20: Web Performance Part 4  "Client-side performance"

asm.js“use asm”;

JIT vs AOT

no need for dynamic type guards, boxed values, and garbage collection.

Page 21: Web Performance Part 4  "Client-side performance"

asm.jswat...

Page 22: Web Performance Part 4  "Client-side performance"

asm.jshow to write

function strlen(ptr) { ptr = ptr|0; var curr = 0; curr = ptr; while (MEM8[curr]|0 != 0) { curr = (curr + 1)|0; } return (curr - ptr)|0; }

Page 23: Web Performance Part 4  "Client-side performance"

asm.jswhy

Page 24: Web Performance Part 4  "Client-side performance"

Native code

NaCl PNaClexecutes native code securely

through Software Fault Isolation (SFI)

1. compiling the source code to a portable bitcode format

2. translating the bitcode to a host-specific executable.

Page 25: Web Performance Part 4  "Client-side performance"

Data caching

Caching is tricky. Avoid it to reduce complexity, allowing you to focus on what matters: javascript variable

minification.@webperftips

Page 26: Web Performance Part 4  "Client-side performance"

1. someFunction(‘param’); 2. someFunction(‘param’);

results[‘param’] = result;

result

return result;

return results[‘param’];

Memoize

Page 27: Web Performance Part 4  "Client-side performance"

Util libraries: Standalone modules:

Memoize.js

Memoize

Page 28: Web Performance Part 4  "Client-side performance"

localStorage sessionStorage

Web Storage

clears when window is closed+:

1. IE8+

2. Simple API

3. Simple sync API

-:

1. Poor performance for large data

2. Lack of indexing

3. Manual serialization

Michael Mahemoff http://www.html5rocks.com/en/tutorials/offline/storage/

if (!localStorage.checkins) localStorage.checkins = JSON.stringify([]);

Page 29: Web Performance Part 4  "Client-side performance"

Web Storage

Page 30: Web Performance Part 4  "Client-side performance"

basket.require( { url: 'jquery.js' }, { url: 'underscore.js' }, { url: 'backbone.js' });

Page 31: Web Performance Part 4  "Client-side performance"

IndexedDB

Michael Mahemoff http://www.html5rocks.com/en/tutorials/offline/storage/

+:

1. Good performance

2. Async API

3. Search is indexed

4. Transactions

-:

1. IE10+

2. Complex API

var request = indexedDB.open("geomood", version);request.onupgradeneeded = function(event) {}request.onsuccess = function(event) {}

Page 32: Web Performance Part 4  "Client-side performance"

IndexedDB

Page 33: Web Performance Part 4  "Client-side performance"

WebSQL

+:

1. Mobile support

2. Good performance

3. Async API

4. Search is indexed

5. Transactions

-:

1. Deprecated (IE and FF)

2. Requires knowledge of SQL

3. SQL

Michael Mahemoff http://www.html5rocks.com/en/tutorials/offline/storage/

Page 34: Web Performance Part 4  "Client-side performance"

WebSQL

Michael Mahemoff http://www.html5rocks.com/en/tutorials/offline/storage/

this.db = openDatabase('geomood', '1.0', 'Geo-Mood Checkins', 8192);

this.db.transaction(function(tx) { tx.executeSql("create table if not exists " + "checkins(id integer primary key asc, time integer, latitude float," + "longitude float, mood string)", [],

function() { console.log("success"); } );});

Page 35: Web Performance Part 4  "Client-side performance"

WebSQL

Page 36: Web Performance Part 4  "Client-side performance"

localForage

WebSQL IndexedDB

localStorage-like API

localforage.setItem('key', 'value', doSomethingElse);

Page 37: Web Performance Part 4  "Client-side performance"

CSS, fonts, rendering

Larger font sizes cost significantly more across the wire. For quick web font loading, keep them under 10pt.

@webperftips

Page 38: Web Performance Part 4  "Client-side performance"

CSS Frameworks

~98 kB ~146 kB

~ 90% of the CSS rules are unused

grunt-uncss

Page 39: Web Performance Part 4  "Client-side performance"

CSS selectors

Ben Frain http://benfrain.com/css-performance-revisited-selectors-bloat-expensive-styles/

1. Data attribute2. Data attribute (qualified)3. Data attribute (unqualified but with value)4. Data attribute (qualified with value)5. Multiple data attributes (qualified with values)6. Solo pseudo selector (e.g. :after)7. Combined classes (e.g. class1.class2)8. Multiple classes9. Multiple classes with child selector

10. Partial attribute matching (e.g. [class^=“wrap”])11. nth-child selector12. nth-child selector followed by another nth-child

selector13. Insanity selection (all selections qualified, every class

used e.g. div.wrapper > div.tagDiv > div.tagDiv.layer2 > ul.tagUL > li.tagLi > b.tagB > a.TagA.link)

14. Slight insanity selection (e.g. .tagLi .tagB a.TagA.link)15. Universal selector16. Element single17. Element double18. Element treble19. Element treble with pseudo20. Single class

Test Chrome 34 Firefox 29 Opera 19 IE9 Android 4

1 56.8 125.4 63.6 152.6 1455.2

2 55.4 128.4 61.4 141 1404.6

3 55 125.6 61.8 152.4 1363.4

4 54.8 129 63.2 147.4 1421.2

5 55.4 124.4 63.2 147.4 1411.2

6 60.6 138 58.4 162 1500.4

7 51.2 126.6 56.8 147.8 1453.8

8 48.8 127.4 56.2 150.2 1398.8

... ... ... ... ... ...Biggest Diff. 16 13.6 17.6 31 152

Slowest 13 6 13 10 6

Page 40: Web Performance Part 4  "Client-side performance"

Dynamic CSS● dynamic properties

● media-queries

● key-frames animations

veinjs

vein.inject([{ '@media (max-width: 768px)': ['h2']}], { 'color': '#f00'});

vein.inject( ['h2', 'h3'], {'color' : 'green', 'font-weight' : null});

Page 41: Web Performance Part 4  "Client-side performance"

Dynamic CSSwhy

Page 42: Web Performance Part 4  "Client-side performance"

Layout performance

this block is being repainted on each

css change

Page 43: Web Performance Part 4  "Client-side performance"

Layout performancelayers

● -webkit-transform: translateZ(0)

● -webkit-transform: translate3d

(0,0,0);

● backface-visibility: hidden

GPU Acceleration

New Layer

Page 44: Web Performance Part 4  "Client-side performance"

● not enough VRAM

● slow CPU to GPU transfer

Layout performancelayers

Pitfalls:

Page 45: Web Performance Part 4  "Client-side performance"

Reflowgeometrical calculations of layout

el:clientHeightclientLeftfocus()getBoundingClientRect()getClientRects()innerTextoffsetHeightoffsetWidthouterTextscrollTopscrollWidth

window:getComputedStyle()scrollBy()scrollTo()scrollXscrollYwebkitConvertPointFromNodeToPage()webkitConvertPointFromPageToNode()

Page 46: Web Performance Part 4  "Client-side performance"

Layout performancesummary

● Try to localize changes● Try to batch changes FastDOM

● window.requestAnimationFrame

● disable animations when possible

● don’t cause reflow

Page 47: Web Performance Part 4  "Client-side performance"

Fonts loadtime1. Load only fonts you need

2. Load only charsets you need

3. Font Load Events API

Ilya Grigorik http://www.igvita.com/2014/01/31/optimizing-web-font-rendering-performance/

var font = new FontFace("FontA", "url(http://mysite.com/fonts/fontA.woff)", {});

font.ready().then(function() { // font loaded.. swap in the text / define own behavior.});

font.load(); // initiate immediate fetch / don't block on render tree!

Page 48: Web Performance Part 4  "Client-side performance"

DOM

Inserting <br> elements liberally throughout your markup will give the rendering engine enough breaks to stay fast for the

whole day.@webperftips

Page 49: Web Performance Part 4  "Client-side performance"

<!doctype html><html lang="en"><head>

...<link rel="stylesheet" href="">

</head><body>

... <script type=“text/javascript” src=""></script></body></html>

in the head to get styling asap

in the bottom of the bodynon-blocking

asyncdefer

Document parsing

Page 50: Web Performance Part 4  "Client-side performance"

Text editing

innerHTML innerText textContenthtml parsing layout reflow bingo! IE9+

Page 51: Web Performance Part 4  "Client-side performance"

Frameworks

Instead of doing costly ajax calls to a server for data, simply generate random data on the client side

and use that instead.@webperftips

Page 52: Web Performance Part 4  "Client-side performance"

you might not need jQueryIE8+

$(‘selector’) document.querySelectorAll(‘selector’)$.ajax new XMLHttpRequest().animate() CSS3 Animations.addClass() .classList.add().html() .innerHTML

...

Page 53: Web Performance Part 4  "Client-side performance"

jQuery-free frameworks

React vue.js

MVVMultra-fast

~13 kb gzipped

widget-orientedfastvirtualDOM

Page 54: Web Performance Part 4  "Client-side performance"

Backbone

grunt-contrib-jstJquery-less

document.fragment

Page 55: Web Performance Part 4  "Client-side performance"

Image optimizations

Page 56: Web Performance Part 4  "Client-side performance"

Sprites

Icons by Denis http://www.iconarchive.com/show/cat-commerce-icons-by-iconka.html

add.png client.png mail.png search.png trash.png

sprite.png

Page 57: Web Performance Part 4  "Client-side performance"

Sprites

.sprite-add-icon { background-position: 0 0; width: 128px; height: 128px; } .sprite-client-icon { background-position: -178px 0; width: 128px; height: 128px; }

.sprite-mail-icon { background-position: -356px 0; width: 128px; height: 128px; }

.sprite-search-icon { background-position: -534px 0; width: 128px; height: 128px; }

.sprite-trash-icon { background-position: -712px 0; width: 128px; height: 128px; }

css snippets

Page 58: Web Performance Part 4  "Client-side performance"

Inline images<img src="data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2w………….. />

background-image: url('data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAcF……..’)

+:1. One request2. IE7+

-:1. base64 > image size2. not cached itself3. processor time

Page 59: Web Performance Part 4  "Client-side performance"

Inline images

Peter McLachlan http://www.mobify.com/blog/base64-does-not-impact-data-uri-performance/

Page 60: Web Performance Part 4  "Client-side performance"

Inline images vs sprites

Peter McLachlan http://www.mobify.com/blog/css-sprites-vs-data-uris-which-is-faster-on-mobile/

Page 61: Web Performance Part 4  "Client-side performance"

Serving perfect sized images1. Scaling the size down with css (e.g. 50%) 2. Serving bad/small images on Retina

problem

Page 62: Web Performance Part 4  "Client-side performance"

Serving perfect sized imagessolutions

media-queries srcset

( (min-device-pixel-ratio: 1.5) and (min-width: 20.001em) and (max-width: 35.999em) ) or( (max-device-pixel-ratio: 1.5) and (min-width: 120.001em) ) or( (min-device-pixel-ratio: 1.5) and (min-width: 60.001em) )

IE9+, FF 23+, Chrome 31+, iOS 3.2, Android 2.1, IEMobile 10, Safari 7+

<img src="small.jpg" srcset="large.jpg 1024w,

medium.jpg 640w, small.jpg 320w"sizes="(min-width: 36)33.3%, 100%"

/>

Chrome 33+, FF 27+, Safari 7+

Page 63: Web Performance Part 4  "Client-side performance"

Font icons

Page 64: Web Performance Part 4  "Client-side performance"

Font iconsicnfnt Fontello IcoMoon

custom builds

Page 65: Web Performance Part 4  "Client-side performance"

Compression

lossy lossless

strip metadatagroup

color quantization

OptiPNG

pngquant

jpegtrangifsicle

Page 66: Web Performance Part 4  "Client-side performance"

New, optimized formats

➔ webp25% less sizeChrome 9+ (stable 23+), Opera 12.1+, Android 4.0+

➔ jpeg-xr... less sizeIE9+

➔ mozjpegwork in progressjpeg compressor

Page 67: Web Performance Part 4  "Client-side performance"

New, optimized formats

Nicholas Doyle http://calendar.perfplanet.com/2013/browser-specific-image-formats/

Page 68: Web Performance Part 4  "Client-side performance"

Convertion tools

Probably the most universal tool. Any kind of convertion, lossless and lossy compression

webp cross-platform codec

ImageMagick

webpjpegxr cross-platform codecbmp -> jpegxr

jxrlib

Page 69: Web Performance Part 4  "Client-side performance"

Conditional serving

webp-detect

connect-image-optimus

koa-image-optimus

apachenginxvarnish

iisAccepts webp

webp on disk

1

add Vary:Accept

1

UA accepts jpegxr

jpegxr on disk

1

0

Page 70: Web Performance Part 4  "Client-side performance"

Top Related