web performance part 4 "client-side performance"
Post on 11-May-2015
1.209 Views
Preview:
DESCRIPTION
TRANSCRIPT
Client-side performance
Mykyta Semenistyi
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
Perceived performance
0.1sfeels instantaneously
1smental context switch
10sinterest in dialog loss
JAKOB NIELSEN on January 1, 1993
Content loading
might not be loaded at once
Visual feedback
Icons by Seth Coelen http://dribbble.com/shots/1167728-PSD-CSS-Button-State-Workfiles
Instant Click
how long ago you gave yourself away
pjax-powered
Sleeping Devices
Page Visibility API hypnos
IE10+, FF 27+, Chrome 31+, iOS 7, Android 4.4, IEMobile 10, Safari 7+
visibilitychange event
hidden
Build systems
Grunt Gulp Broccoli
Build systemsOptimize images Generate sprites
Convert images Concatenate css, js,html
Minify css, js,html Inline css
Compress static files ...
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
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
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
for (var i in theArray) { copyOfTheArray[i] = theArray[i];}
theArray.forEach(function(it, idx){ copyOfTheArray[idx] = it;});
forEach:
for in:
Loops 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/
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)
WebWorkersUse cases
Ray TracerVideo/audio
Route Tracer
DNA Analyzing
WebWorkersbut...
Event loop in JSUI Thread
...onclick XHR state change
setTimeout setInterval
onclick XHR state change
setTimeout
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();}
asm.js“use asm”;
JIT vs AOT
no need for dynamic type guards, boxed values, and garbage collection.
asm.jswat...
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; }
asm.jswhy
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.
Data caching
Caching is tricky. Avoid it to reduce complexity, allowing you to focus on what matters: javascript variable
minification.@webperftips
1. someFunction(‘param’); 2. someFunction(‘param’);
results[‘param’] = result;
result
return result;
return results[‘param’];
Memoize
Util libraries: Standalone modules:
Memoize.js
Memoize
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([]);
Web Storage
basket.require( { url: 'jquery.js' }, { url: 'underscore.js' }, { url: 'backbone.js' });
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) {}
IndexedDB
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/
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"); } );});
WebSQL
localForage
WebSQL IndexedDB
localStorage-like API
localforage.setItem('key', 'value', doSomethingElse);
CSS, fonts, rendering
Larger font sizes cost significantly more across the wire. For quick web font loading, keep them under 10pt.
@webperftips
CSS Frameworks
~98 kB ~146 kB
~ 90% of the CSS rules are unused
grunt-uncss
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
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});
Dynamic CSSwhy
Layout performance
this block is being repainted on each
css change
Layout performancelayers
● -webkit-transform: translateZ(0)
● -webkit-transform: translate3d
(0,0,0);
● backface-visibility: hidden
GPU Acceleration
New Layer
● not enough VRAM
● slow CPU to GPU transfer
Layout performancelayers
Pitfalls:
Reflowgeometrical calculations of layout
el:clientHeightclientLeftfocus()getBoundingClientRect()getClientRects()innerTextoffsetHeightoffsetWidthouterTextscrollTopscrollWidth
window:getComputedStyle()scrollBy()scrollTo()scrollXscrollYwebkitConvertPointFromNodeToPage()webkitConvertPointFromPageToNode()
Layout performancesummary
● Try to localize changes● Try to batch changes FastDOM
● window.requestAnimationFrame
● disable animations when possible
● don’t cause reflow
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!
DOM
Inserting <br> elements liberally throughout your markup will give the rendering engine enough breaks to stay fast for the
whole day.@webperftips
<!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
Text editing
innerHTML innerText textContenthtml parsing layout reflow bingo! IE9+
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
you might not need jQueryIE8+
$(‘selector’) document.querySelectorAll(‘selector’)$.ajax new XMLHttpRequest().animate() CSS3 Animations.addClass() .classList.add().html() .innerHTML
...
jQuery-free frameworks
React vue.js
MVVMultra-fast
~13 kb gzipped
widget-orientedfastvirtualDOM
Backbone
grunt-contrib-jstJquery-less
document.fragment
Image optimizations
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
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
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
Inline images
Peter McLachlan http://www.mobify.com/blog/base64-does-not-impact-data-uri-performance/
Inline images vs sprites
Peter McLachlan http://www.mobify.com/blog/css-sprites-vs-data-uris-which-is-faster-on-mobile/
Serving perfect sized images1. Scaling the size down with css (e.g. 50%) 2. Serving bad/small images on Retina
problem
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+
Font icons
Font iconsicnfnt Fontello IcoMoon
custom builds
Compression
lossy lossless
strip metadatagroup
color quantization
OptiPNG
pngquant
jpegtrangifsicle
New, optimized formats
➔ webp25% less sizeChrome 9+ (stable 23+), Opera 12.1+, Android 4.0+
➔ jpeg-xr... less sizeIE9+
➔ mozjpegwork in progressjpeg compressor
New, optimized formats
Nicholas Doyle http://calendar.perfplanet.com/2013/browser-specific-image-formats/
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
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
top related