Performance as UX
Justin Howlett @justinhowlett @Digiflare
Who am I?
Tradition view
Save bandwidth costs
Save server costs
Simply be able to run on a platform
My app/website is good enough
-
-
-
-
Put the user first
Performance improvements should be to improve the user experience
Think of it as a 100ms experience improvement not a performance
bump.
You can design and develop for speed in order to improve UX
-
-
-
Will a user really notice a 200ms
delay?
“Users really respond to speed”
!!!!!!!!- Marissa Mayer CEO Yahoo!
Quantifying the User Experience
Why$Performance$matters$to$User$Experience
A 500ms delay on google.com results
in a 20% reduction in traffic.
A 100ms delay on amazon.com results
in a 1% reduction in sales.
Limit for users feeling that they are directly manipulating
objects in the UI. For example, this is the limit from thetime the user selects a column in a table until that columnshould highlight or otherwise give feedback that it'sselected. Ideally, this would also be the response time forsorting the column - if so, users would feel that they are
sorting the table.
0.1 second
Limit for users feeling that they are freely navigating thecommand space without having to unduly wait for thecomputer. A delay of 0.2-1.0 seconds does mean thatusers notice the delay and thus feel the computer is"working" on the command, as opposed to having the
command be a direct effect of the users' actions
1 second
Limit for users keeping their attention on the task.
Anything slower than 10 seconds needs a percent-doneindicator as well as a clearly signposted way for the user
to interrupt the operation.
10 seconds
Smooth animations and scrolling are
often cited as major reasons iOS users
stay iOS users.
Topics Covered
Topics Covered
Myths about performance
Easy to implement techniques
Emerging standards that improve performance
The perception of performance
-
-
-
-
Topics Avoided
Big-O notation
Too much Objective-C / iOS
-
-
A brief note
You don’t have to implement any of these, just beware of what is out
there.
There are technical descriptions but feel free just to focus on the
diagrams, they tell the most important story.
-
-
“Don’t Trust Anyone. Don’t believe blindly what you are told.
Perform experiments, test your own data and code with your own
users and devices. What ‘seems obvious’ is not always true.”
!!!!!!!!- David Lee
Run tests on your own stack and on your own data.
Then run them again just to make sure.
Myths about performance
XML is much slower than JSON on the
web.
“Overall using native JavaScript the use of XML and JSON is
essentially identical performance for total user experience
(transfer plus parse plus query)”
!!!!!!!!- David Lee
but, but, JSON...
“This study must have been done 5 years
ago on a typewriter running IE6”
33 different documents
The most commonly used browsers and operating systems
Includes mobile devices
August 6-9 2013
-
-
-
-
XML is NOT much slower than JSON
on the web.
UITableViewCells are rendered
quicker in Core Graphics.
What the heck is a “UITableViewCell” ?
What the heck is a “Core Graphics” ?
Draw flat using the CPU
Lines, fills, shapes etc..
-
-
Draw it flat with the CPU, GPU does less work and
bam! extra fps. Now let’s celebrate!
http://floriankugler.com/blog/2013/5/24/layer<trees<vs<flat<drawing<graphics<performance<across<ios<device<
Where is your “fast cell technique” now?
This appears on stackoverflow more than you can
possibly imagine.
Easy to use tools to improve web
performance.
Google Page Speed Insights
Yahoo! YSlow
23 testable rules that affect
performance
Minimize'HTTP'Requests
Use'a'Content'Delivery'Network
Avoid'empty'src'or'href
Add'an'Expires'or'a'CacheDControl'Header
Gzip'Components
Put'StyleSheets'at'the'Top
Put'Scripts'at'the'Bottom
Avoid'CSS'Expressions
Make'JavaScript'and'CSS'External
Reduce'DNS'Lookups
Minify'JavaScript'and'CSS
Avoid'Redirects
Remove'Duplicate'Scripts
Configure'ETags
Make'AJAX'Cacheable
Use'GET'for'AJAX'Requests
Reduce'the'Number'of'DOM'Elements
No'404s
Reduce'Cookie'Size
Use'CookieDFree'Domains'for'Components
Avoid'Filters
Do'Not'Scale'Images'in'HTML
Make'favicon.ico'Small'and'Cacheable
Your users may not be consciously
aware but performance drives positive
user experiences.
Emerging standards and libraries
That%you%can%use%right%now%if%you’re%brave
Server side push
Communication driven by both the
server as well as the client.
Server side push
Not just for real-time applications
1 request and 4 responses is faster than 4 requests and 4 responses
-
-
Server side push
Traditionally this was sockets over some terrible port that was
probably blocked anyway.
Or done with long polling. (YUCK)
-
-
Old$and$busted
Server side push
Multiple emerging standards
Websockets
Push notifications
Not a standard
HTTP 2.0
SPDY+Push
-
-
-
-
-
-
The$new$hotness
Server side push
HTTP 2.0 (SPDY)
Google initiative
SPDY Hint
Rather than automatically pushing resources to the client, the server uses the X-Subresources header to suggest to the
client that it should ask for specific resources, in cases where the server knows in advance of the client that those resources
will be needed
SPDY Push
SPDY%experiments%with%an%option%for%servers%to%push%data%to%clients%via%the%X:Associated:Content%header.%This%header
informs%the%client%that%the%server%is%pushing%a%resource%to%the%client%before%the%client%has%asked%for%it.%%
-
-
-
-
-
HTTP 2.0 (SPDY)
HTTP SPDY SPDY+Hint
Average ms 3111 1695 1608
Speedup 45.51% 48.30%
HTTP 2.0 (SPDY)
HTTP 2.0 (SPDY)
Available for Apache as mod-spdy
Available for Nginx as a patch
Websockets
Easy Implementation, especially in NodeJS.
Support on all current browsers except the Android browser.
-
-
Websockets
Messagepack
“It's like JSON.but fast and small.”
Messagepack
Binary serialization format
Always smaller than XML and JSON
-
-
Messagepack
JSON 8.0KB
Messagepack 5.3KB
Messagepack
*Languages,*Encode*and*Decode*sets*may*be*based*on*entirely*different*sample*data*and*hardware.
Language
Messagepack
Encode
Messagepack
Decode
JSON Encode JSON Decode
Python 2.75s 0.72s 3.33s 6.83s
Ruby 0.06s 0.10s 0.42s 0.23s
NodeJS 5.0s 3.5ms 1.0ms 1.0s
Java 759ms 1386ms 1201ms 1216ms
Messagepack
Not right for everyone
Client-side gains might easily outweigh server-side loses
Test with your own data using your own stack
-
-
-
Image compression
Your%PNGs%are%bad%and%you%should%feel%bad.
Before we get started
JPEGs are for photography
GIFs are for animated cats
PNGs are for everything else
Before we get started
If you save your 2 color logo as a jpeg you should be
banned from the internet.
Think of the electricity we could save if everyone simply
saved their images in the correct format.
Before we get started
</rant>
Your PNGs are bloated
You’re likely using PNGs that are 4x larger in disk size than
they need to be.
Your PNGs are bloated
It’s difficult for users to shop on your site when your images
take forever to load.
Your PNGs are bloated
Savings can be lossy or lossless
24bit vs 8bit PNG
Color palette reduction (256 to 2 colors)
Lossy color reduction causes banding
-
-
-
-
Your PNGs are bloated
139KB (24bit) 41KB (8bit 256 colors) 21KB (8bit 64 colors)
Your PNGs are bloated
What is banding and how to mitigate it.
Lossless image compression
PNGOUT
Zopfli
Pngcrush
AdvPNG
OptiPNG
-
-
-
-
-
Image compression
ImageOptim OSX (contains all previously mentioned libraries)
JpegMini (OSX + Windows)
ImageAlpha OSX
-
-
-
Image Size Reduction
Huge impact on shipping application size, download wait time.
Huge impact on asset downloading times
Downloading and installing a 1GB app is an awful. And yes you’re still
responsible for that part of your user experience.
-
-
-
http://imageoptim.com/tweetbot.html
But wait, there’s more.
Image size reductions have a direct impact on the
performance of iOS applications.
(And probably all others)
Image Performance gains
“Xcode-optimized images were significantly slower to display. Decoding speed appears to be correlated
to image file size more than anything else (most likely savings on byteswapping are negligible compared
to additional disk I/O and extra data to decompress.)”
http://imageoptim.com/tweetbot.html
webP
What is webP and why does it render
everything I just said obsolete?
webP
One format to rule them all.
webP
Open source, developed mainly by Google.
25-34% smaller than JPEGs
26% smaller than PNGs
Supports alpha channel
Animation support (though ironically the chrome team won’t support it)
-
-
-
-
-
webP
Many mobile Operating systems and GPUs are heavily optimized for
PNGs
WebP should not replace PNG assets that ship with an application.
For low internet speeds, small sized images and desktops it may
be a great option, easy to fallback.
!
!
!
webP Performance
JPEGwebPJPEG
JPEG
webP
webP
0481216200
0
4
4
8
8
12
12
16
16
20
20
Image Size (KB)
Image Size (KB)
webP Performance
JPEGwebPJPEG
JPEG
webP
webP
00.020.040.060.080
0
0.02
0.02
0.04
0.04
0.06
0.06
0.08
0.08
iOS Render Time
iOS Render Time
webP support
Chrome 9+
Opera 12+
Android browser 4.0+
Opera Mobile 11.1+
Chrome for Android 29+
-
-
-
-
-
Techniques to improve performance
Without'having'a'PHD'in'Computer'Science
Behavioral APIs
Sits between DB or API or Feeds and the client.
Abstract heavy parsing and multiple requests to a server
Reduce data sent to the client
I don’t care what “page” of data this came from.
-
-
-
-
Behavioral APIs
Prepare data in a way that’s best for that particular device
messagepack, json, jsonP, XML, PNG, webP.
Prepare data in a way that’s best for the application
This views has these 4 elements, this endpoint provides all four models at the same time.
-
-
-
-
Unnecessary iteration
A case study.
Unnecessary iteration
The worst way
Unnecessary iteration
int bytesPerPixel = 4; //r,g,b,a
for(int x = 0; x < imageWidth; x++) {
for(int y = 0; y < imageHeight; y++) {
int pixelStartIndex = (x + (y * imageWidth)) * bytesPerPixel;
int r = pixels[pixelStartIndex ];
int g = pixels[pixelStartIndex +1];
int b = pixels[pixelStartIndex + 2];
//calculate the luminosity of the pixels
}
}
Unnecessary iteration
Do you really need the pixel location in the
image?
Unnecessary iteration
The better way
Unnecessary iteration
int bytesPerPixel = 4; //r,g,b,a
for(NSInteger i=0; i<length; i+= bytesPerPixel){
int r = pixels[i];
int g = pixels[i+1];
int b = pixels[i+2];
}
Unnecessary iteration
If my image has 100 pixels.
1 loop2 loops1 loop
1 loop
2 loops
2 loops
02000400060008000100000
0
2000
2000
4000
4000
6000
6000
8000
8000
10000
10000
Don’t try and do everything yourself
Apple has implemented sorting algorithms far
better and far faster than I could ever dream
to.
Threading for performance
Some%people,%when%confronted%with%a%problem,%think,%"I%know,%I'll%use
threads,"%and%then%two%they%hav%erpoblesms.
Threads, queues, workers
Embarrassingly parallel
Little&or&no&effort&is&required&to&separate&the&problem&into&a&number&of&parallel&tasks.
Threading Case
Let’s&break&up&our&image&into&smaller&chunks&and&iterate&those&chunks&using&separate&threads
Threading for Performance
1 Thread2 Threads3 Threads4 Threads100 Threads1 Thread
1 Thread
2 Threads
2 Threads
3 Threads
3 Threads
4 Threads
4 Threads
100 Threads
100 Threads
012340
0
1
1
2
2
3
3
4
4
iPhone 5 iOS7 (lower is better)
iPhone 5 iOS7 (lower is better)
Threading for Performance
+5%$performance$when$recompiled$as$a$646bit$binary$
Threading for Performance
1 Thread2 Threads3 Threads4 Threads100 Threads1 Thread
1 Thread
2 Threads
2 Threads
3 Threads
3 Threads
4 Threads
4 Threads
100 Threads
100 Threads
012340
0
1
1
2
2
3
3
4
4
OSX 10.8 rMBP (lower is better)
OSX 10.8 rMBP (lower is better)
Threading for Performance
More threads aren’t better
Threads can be expensive to spawn
Thread spawn cost can outweigh performance gains
Data set size, hardware and threading API performance are the
largest contributing factors
Threads are difficult to debug
-
-
-
-
-
CDNs
Divide&and&conquer
If you’re using Amazon S3 or a static
server and your user base isn’t hyper
local... you’re doing it wrong.
http://www.quora.com/What0are0typical0latencies0for0static0content0in0S30vs0Cloudfront
S3CloudFrontS3
S3
CloudFront
CloudFront
040801201602000
0
40
40
80
80
120
120
160
160
200
200
Latency from EU (ms)
Latency from EU (ms)
CDNs
Reuse and recycle
UITableViewCells
UICollectionViewCells
Reuse DOM Elements
-
-
-
Reuse and recycle
Reuse DOM Elements
“The solution is to recycle DOM nodes once they’re no longer visible. In
this way, a list that seems to have infinite content could contain only say
10 elements – just enough to fill the screen. Once you scroll down the list,
DOM nodes that scrolled off the top are detached, updated with new data
and placed at the bottom of the list. Simple. Ingenius. Beautiful.”
Sencha Fastbook