optimising web application frontend

55
Optimising Web application frontend Tomáš Kramár, @tkramar

Upload: tkramar

Post on 15-May-2015

828 views

Category:

Technology


6 download

TRANSCRIPT

Page 1: Optimising Web Application Frontend

Optimising Web application frontend

Tomáš Kramár, @tkramar

Page 2: Optimising Web Application Frontend

What happens when I type address into browser?

Page 3: Optimising Web Application Frontend

GET /index.html

GET /index.html

Bro

wse

r

S

erve

r

Page 4: Optimising Web Application Frontend

GET /index.html

index.html

Bro

wse

r

S

erve

r

GET /assets/favicon.ico

favicon.ico

Page 5: Optimising Web Application Frontend

GET /index.html

index.html

Bro

wse

r

S

erve

r

GET /assets/favicon.ico

favicon.ico

GET /assets/application.css

application.css

Page 6: Optimising Web Application Frontend

GET /index.html

index.html

Bro

wse

r

S

erve

r

GET /assets/favicon.ico

favicon.ico

GET /assets/application.css

application.css

GET /assets/bg.png

bg.png

Page 7: Optimising Web Application Frontend

GET /index.html

index.html

Bro

wse

r

S

erve

r

GET /assets/favicon.ico

favicon.ico

GET /assets/application.css

application.css

GET /assets/bg.png

bg.png

Backend

Page 8: Optimising Web Application Frontend

Page Load Time =

Backend Time+

Frontend Time

Page 9: Optimising Web Application Frontend

Optimisation rule #1

Optimise only when it makes sense

Page 10: Optimising Web Application Frontend

Optimisation rule #1

Optimise only when it makes sense

* http://www.stevesouders.com/blog/2012/02/10/the-performance-golden-rule/

Page 11: Optimising Web Application Frontend

Waterfall / Firebug

Page 12: Optimising Web Application Frontend

Demo

Page 13: Optimising Web Application Frontend

Sprechen Sie Firebug?

● Blocking - request is queued and waiting● DNS Lookup - time to resolve hostname● Connection - time to create TCP connection● Sending - sending request headers● Waiting - backend is busy now● Receiving - reading the response ● blue and red vertical lines:

DOMContentLoaded and load events○ http://ie.microsoft.

com/testdrive/HTML5/DOMContentLoaded/Default.html

Page 14: Optimising Web Application Frontend

Optimisation rule #2

Download resources in parallel

Page 15: Optimising Web Application Frontend

Resource downloading rules

Clients that use persistent connections SHOULD limit the number of simultaneous connections that they maintain to a given server. A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.

-- RFC 2616 (HTTP 1.1)

Page 16: Optimising Web Application Frontend

Demo

Page 17: Optimising Web Application Frontend

Solution: Asset subdomains

● assets01.domain.com● assets02.domain.com● ... ● Extra:

○ Cookie-less domain○ HTTP Keep-Alive

● Pitfalls:

○ DNS lookups

Page 18: Optimising Web Application Frontend

Optimisation rule #3

Fastest request is the one that doesn't happen

Page 19: Optimising Web Application Frontend

Avada Kedavra Request!

● Merge● Inline● Sprite● Cache

Page 20: Optimising Web Application Frontend

Merge

● Merge multiple CSS files into a single file● Merge multiple JS files into a single file

○ -> Rails/Sprockets/Asset pipeline$ cat app/assets/javascripts/application.js

//= require jquery_ujs//= require_tree ./vendor//= require document_viewer/dv//= require_tree .

Page 21: Optimising Web Application Frontend

Inline

● Inline JavaScript○ Replace <script src=".."></script> with

<script>//code</script>● Inline CSS

○ <style>body { color: red; }</style>● Usable only for small resources, larger

resources benefit more from caching● Inline images using data URIs

○ <img src='data:image/jpeg;base64,/9j/4AAQSkZJR'/>

○ background-image: url(data:image/jpeg;base64,/9j/4AAQS);

○ Pitfalls: size limit, IE <= 7

Page 22: Optimising Web Application Frontend

Demo

Page 23: Optimising Web Application Frontend

CSS sprites

Merge multiple images into one, use background-position to place.

Page 24: Optimising Web Application Frontend

Caching

First request: cache miss, hit the server, obtain tokenAdditional requests: use the token from first request to make conditional request Conditional requests● If-None-Match● If-Modified-Since

Page 25: Optimising Web Application Frontend

If-None-Match: First request

First request: Request headers:GET / Response headers:Status: 200 OKEtag: "be5c5a3edac0592617693fa..."

Page 26: Optimising Web Application Frontend

If-None-Match: Next requests

Request headers:GET /If-None-Match: "be5c5a3edac0592617693fa..." Response headers:Status: 304 Not ModifiedEtag: "be5c5a3edac0592617693fa..."

Page 27: Optimising Web Application Frontend

If-None-Match

● Server needs to calculate ETag (fingerprint)● How?

○ it depends○ easiest way: generate output, calculate hash

● If ETag matches, send 304 Not Modified, no response body

● You save on the data transfer ("Receiving" in Firebug)

Page 28: Optimising Web Application Frontend

If-Modified-Since: First request

Request headers:GET / Response headers:Status: 200 OKExpires: Thu, 31 Dec 2037 23:55:55 GMTLast-Modified: Mon, 30 Jan 2012 13:36:26 GMT

Page 29: Optimising Web Application Frontend

If-Modified-Since: Local cache

Request headers:none Response headers:none Current time is < resource's Expire header

Page 30: Optimising Web Application Frontend

If-Modified-Since: Forced refresh

Request headers:GET /If-Modified-Since: Mon, 30 Jan 2012 13:36:26 GMT Response headers:Status: 304 Not ModifiedExpires: Thu, 31 Dec 2037 23:55:55 GMTLast-Modified: Mon, 30 Jan 2012 13:36:26 GMT

Page 31: Optimising Web Application Frontend

Refresh

Regular click on a link: uses local cache and no request is made F5: Skips local cache, sends If-Modified-Since request, potentially 304-ing Ctrl+F5: Sends requests without If-None-Match and If-Modified-Since

Page 32: Optimising Web Application Frontend

Demo

Page 33: Optimising Web Application Frontend

Far future expires strategy

Set the Expires header far in the future FAQQ: But what if I need to change the resource?A: Use a different name application-f7fd224c9bc0fd4c2f7.css

fingerprint

Page 34: Optimising Web Application Frontend

Rails gotcha

Asset pipeline sets fingerprints, but not Expire headers. You need to DIY. Nginx: location ~* \.(js|css|jpg|jpeg|gif|png|swf|ico)$ { expires max;}

Page 35: Optimising Web Application Frontend

Optimisation rule #3

If you need to make the request, make the response (and request) small.

Page 36: Optimising Web Application Frontend

Follow these rules

● Minify and gzip CSS and JavaScript.● Do not send/set cookies unless necessary

(asset subdomains)● Do not scale images in HTML

○ do not use <img size=""/>, scale image on server● Optimize images

○ http://www.smushit.com/ysmush.it/

Page 37: Optimising Web Application Frontend

Optimisation rule #4

If possible, defer parsing of JavaScripts

Page 38: Optimising Web Application Frontend

How browsers process JavaScript

When browsers encounter <script> tag, the script is downloaded, parsed and executed. Main parsing thread is busy processing the script. Speculative parsing continues downloading and building the DOM in the background, so main thread can pull this fast, but you still pay the parse and execute penalty.

Page 39: Optimising Web Application Frontend

Do you need to execute the script immediately?

Probably not. Is your code waiting for document.ready? Mouse action? Then definitely not.

Page 40: Optimising Web Application Frontend

Then defer it<script type="text/javascript">function downloadJSAtOnload() { var element = document.createElement("script"); element.src = "application.js"; document.body.appendChild(element);} if (window.addEventListener) window.addEventListener("load", downloadJSAtOnload, false);else if (window.attachEvent) window.attachEvent("onload", downloadJSAtOnload);else window.onload = downloadJSAtOnload;</script>

Page 41: Optimising Web Application Frontend

Demo

Page 42: Optimising Web Application Frontend

Optimisation rule #5

As a last resort: simply cheat.

Page 43: Optimising Web Application Frontend

Perceived speed matters

Move all CSS to the top so DOM nodes can be rendered progressivelyIf you cannot defer, at least move <script> to the bottom of the page.Post-load parts of page that are slow to render.

Page 44: Optimising Web Application Frontend

Optimisation rule #5

Think globally.

Page 45: Optimising Web Application Frontend

Location matters

Downloading image placed on a server in Slovakia is relatively cheap than say downloading the same image from Canada.

Page 46: Optimising Web Application Frontend

Use CDN (content delivery network)

Servers spread through the world. Use CDN on common assets (jQuery etc.). Chance is, you will get a cache hit. https://developers.google.com/speed/libraries/

Page 47: Optimising Web Application Frontend

Tools

Web Page Test, http://www.webpagetest.org/Newrelic RUM, http://newrelic.com

Page 48: Optimising Web Application Frontend
Page 49: Optimising Web Application Frontend
Page 50: Optimising Web Application Frontend
Page 51: Optimising Web Application Frontend
Page 52: Optimising Web Application Frontend

Is this all I can do?

Definitely not. Google Page Speed, http://developers.google.com/speed/pagespeed/YSlow, http://yslow.org/

Page 53: Optimising Web Application Frontend
Page 54: Optimising Web Application Frontend

Future

SPDYHTTP archiveslocal storage

Page 55: Optimising Web Application Frontend

Summary

1. Optimise only when it makes sense2. Download resources in parallel3. Fastest request is the one that doesn't

happen4. If you need to make the request, make the

response (and request) small5. If possible, defer parsing of JavaScripts6. Think globally