web performance part 4 "client-side performance"

70
Client-side performance Mykyta Semenistyi

Upload: binary-studio

Post on 11-May-2015

1.209 views

Category:

Software


0 download

DESCRIPTION

The presentation is devoted to client side performance of a web app. All 4 presentations will help you reduce latency, enrich optimization of javascript code, discover tricky parts when working with API browser, see best practices of networking and learn lots of other important and interesting things. Enjoy! =)

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"