Tuning Web Performance

Preview:

Citation preview

Tuning Web Performancein Frontend Perspective

Lin-Chieh Shangkuan (上官林傑)ericsk@gmail.com

AGENDA

The Impacts of Web PerformanceDevelopment ToolsWebsite Optimization ConceptsReferences

The Impact of Performance

Longer response time from web server.Too many requests (css/javascript files, images, flashes, ...)Complicated DOM structureInefficient JavaScript codes....

The Impact of Performance

Longer response time from web server.Too many requests (css/javascript files, images, flashes, ...)Complicated DOM structureInefficient JavaScript codes

80~90% time spent on the frontend

Page-loading Samples

Development Tools

Firefoxhttp://getfirefox.com/Firebughttp://getfirebug.com/Page Speed (Firebug plugin)http://code.google.com/speed/page-speed/Y!Slowhttp://developer.yahoo.com/yslow/

Development Tools (cont)

Chrome (Chromium/WebKit) Developer Toolshttp://www.chromium.org/devtoolsInstall AMAP Latest Web Browserse.g. IE8/9 (preview), Firefox 3.6/nightly, Safari 4/WebKit,Chrome/Chromium, Opera 10/10.5

Firebug Console

Debugging your JavaScript code.Use console object in your JavaScript code.Interactive in the console tab.

Requests Analysis

Analyzing the requests.

Listen to Suggestions

Follow the suggestions from PageSpeed (or Y!Slow)

Chromium Devtools

HTTP Overviews

Request:GET /foo/bar.js HTTP/1.1Host: example.comUser-Agent: Mozilla/5.0

Response:HTTP/1.1 200 OKContent-Type: application/x-javascriptLast-Modified: Mon, 15 Mar 2010 10:00:00 GMTContent-Length: 1234(function(){ .....

HTTP Reuqest Example $ telnet ajax.googleapis.com 80 Trying 74.125.153.95...Connected to googleapis-ajax.l.google.com.Escape character is '^]'.GET /ajax/libs/jquery/1.4.2/jquery.min.js HTTP/1.1Host: ajax.googleapis.comUser-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; zh-TW; rv:1.9.2) Gecko/20100115 Firefox/3.6 GTB7.0Accept-Encoding: gzip,deflateHTTP/1.1 200 OKContent-Type: text/javascript; charset=UTF-8Last-Modified: Mon, 15 Feb 2010 23:30:12 GMTDate: Mon, 15 Mar 2010 08:39:18 GMTExpires: Tue, 15 Mar 2011 08:39:18 GMTVary: Accept-EncodingX-Content-Type-Options: nosniffServer: sffeContent-Encoding: gzipCache-Control: public, max-age=31536000Age: 2497Content-Length: 24678X-XSS-Protection: 0

;iw?F???+??m?@ə???v?I։/M???6???????$e???...

Ways to Speed up the Website

Optimize the backend processinge.g., PHP engine, database, ....

Scaling TransfersCo-location, CDN, ...

Reducing the browser's requestsCSS sprites, expire headers, http compression...

Optimizing the contentsDefer loading, rearrangement, ...

Efficient JavaScript developmentImproving the programming techs, ...

Scaling Transfers

Use CDNe.g., Akamai, Amazon S3, ...Pixnet experience: http://www.slideshare.net/gslin/using-cdn-to-improve-performance

Reduce DNS LookupsKeep-Alivefewer domains

Avoid RedirectsUse Comet

Scaling Transfers

Sharding Dominant Domainsbrowser HTTP/1.1 HTTP/1.0

IE6, 7 2 4

IE8 6 6

FF2 2 8

FF3 6 6

Saf 4 4

Chrome 6 6

Op 4 4

Connections per server

Reducing Requests

HTTP Compression

Modern browsers support HTTP compression -- to reduce the size of response content

Gzip the static (html, css, js, ...) filesDon't compress everything (e.g., jpg, png, pdf, ... they are already compressed)

Check if the Accept-Encoding header has gzip or deflate value.Respond Content-Encoding: gzip header.

HTTP Compression

In Apache httpd server, use mod_gzip (httpd 1.3) or mod_deflate (httpd 2.x).

[mod_deflate]AddOutputFilterByType DEFLATE text/html text/css application/x-javascript

Problems:Proxy may cache uncompressed content

Add Vary: Accept-Encoding headerIE6 bug: Q312496, Q313712

Make Fewer Requests

CSS Sprites: Combine N icons into 1 bigger image.Reduce N requests info 1 request.Be careful of the arrangement of the iconssample: http://www.google.com.tw/images/nav_logo8.pngtool: http://tw.spritegen.website-performance.org/http://csssprites.com/

Combine CSS/JavaScript filesUsing Google Closure CompilerApache: http://code.google.com/p/modconcat/Lighttpd: http://code.google.com/p/lighttpd-mod-concat/YUI Comobo Handler: http://yuiblog.com/blog/2008/07/16/combohandler/

Make Fewer Requests

Reduce Cookie size (or split domains)Inline images: using base64 encoding

<img src="data:image/png;base64, xxxxx">IE7/6 doesn't support this featureUseful in mobile browserNot only images: <frame src="data:text/html,%3Chtml%3E%3Cbody%20style%3D%22background..."></frame>

Using Expires Headers

Use Expires header to tell the browser how long to keep the resource.

Browser won't fetch the resource again until the expire timeApache mod_expires module can help setting expire time

<FilesMatch "\.(css|js|jpg|png)$"> ExpiresDefault "access plus 1 year"</FilesMatch>

e.g., Expires: Fri, 25 Mar 2011 08:00:00 GMTCache-Control header

In stead of using a specified date, Cache-Control header shows HOW LONG the client should keep ite.g., Cache-Control: max-age=31536000 # cache 1 year

Using Last-Modified Headers

Use Last-Modified header to tell the browser the last modified time of the resource.

[request]GET /foo/bar.css HTTP/1.1....[response]HTTP/1.1 200 OKContent-Type: text/cssLast-Modified: Thu, 25 Mar 2010 10:00:00 GMT+8....

[request]GET /foo/bar.css HTTP/1.1...If-Modified-Since: Thu, 25 Mar 2010 10:00:00 GMT...[response]HTTP/1.1 304 Not Modified...(empty response body)

Configuring ETag

ETag (Entity Tag) header tells browser which to cacheHow ETag works: read Wikipedia

Problem: Not-the-same tag across different serversApache: inode-size-timestampIIS: timestamp:changenumber

Solution:Set ETag manuallyRemove it.

(in Apache) FileETag none

Invalidates the Cached Resources

If the static resources are cached, how to invalidate them?Use signature in filename ( /js/foo.AB32FDC.js )Add query string ( /js/foo.js?20100325110000 )

Optimizing Loadings

Minifying JavaScript

Reduce the size of JavaScript files.Reduce the total response sizes.HTML, CSS files can be also compressed.

Closure-compilerWeb-based http://closure-compiler.appspot.com/RESTful APIhttp://code.google.com/closure/compiler/docs/api-ref.htmlStandalone executable

OfuscationReduce the length of variables namesBe careful the obfuscation method (e.g., eval cause performance degradation)Be careful the conflicts.

Optimizing Images

Using appropriate image format and remove redundant chunks in the image files.

PNG8 (256 colors) is a good choice.Optimizing:

Crushing PNGspngcrush (http://pmt.sf.net/pngcrush/)

Stripping JPEG metadatajpegtran (http://jpegclub.org/)

Convert GIF to PNGImageMagick

Optimizing GIF animationsgifsicle ((http://www.lcdf.org/gifsicle/)

Avoid image scaling

Put Stylesheets on The Top

Browser delays showing any visible components while it and user wait for the stylesheet at the bottom.Use <link> to include stylesheets

@import MUST precede all other rules@import may cause blank white screen phenomenon (in IE)

Put JavaScripts at The Bottom

JavaScript blocks parallel downloadsPut at top: the other components are delayed- loaded.

defer attributes:Firefox still blocks other downloads

Non-blocking Loading Scripts

IE8 is the first browser that supports downloading scripts in parallel.Ways to load JavaScripts

XHR EvalXHR InjectScript in iframeInserting script DOM element document.write

Non-blocking Loading Scripts

Tech Parallel Diff DomainExisting Scripts

Busy indicator

Preserve Order

Normal IE8, SF4 Y Y IE, SF4 IE, SF4

XHR Eval * N N SF, Ch

XHR Injection * N Y SF, Ch

Script in iframe * N N IE, FF, SF, Ch

Script DOM * Y Y FF, SF, Ch FF, Op

Script Defer IE, SF4, Ch2, FF3.1 Y Y * *

document.write IE, SF4, Ch2, Op Y Y * *

iframes

iframes are heavy and block onload event.Use script DOM injection to insert ADs instead of iframes.

Efficiency Practices

Make JavaScript/CSS External

Reusing componentsCache the filesUnobstrusive JavaScripts

Simplifying CSS Selectors

CSS selector policy: Rightmost-FirstTips:

Avoid * selectorDon't qualify ID/CSS selectorsSpecific rulesAvoid descendant selectorsAvoid Tag > Child selectorsRely on inheritance

Efficient JavaScript Tips

Using className instead of modifying style attributes of a DOM element.[bad]

var foo = document.getElementById('foo');foo.style.color = '#f00';foo.style.fontWeight = 'bold';

[good].highlight { color: #f00; font-weight: bold;}

foo.className = 'highlight';

Efficient JavaScript Tips (con'd)

Appending a newly-created DOM element after modifying its attributes. (avoid reflows)[bad]var foo = document.createElement('div');document.body.appendChild(foo);foo.innerHTML = 'Hello, world';foo.className = 'hello';

[good]var foo = document.createElement('div');foo.innerHTML = 'Hello, world';foo.className = 'hello';document.body.appendChild(foo);

Efficient JavaScript Tips

Using document fragment to create new contents.[bad]document.body.appendChild(createDivElement());document.body.appendChild(createDivElement());...

[good]var frag = document.createDocumentFragment();frag.appendChild(createDivElement());frag.appendChild(createDivElement());....document.body.appendChild(frag);

Efficient JavaScript Tips

Using array join instead of directly concatenate strings.[bad]]var a = 'Hel';a += 'lo';a += ', wor';a += 'ld!';

[good]var buf = ['Hel'];buf.push('lo');buf.push(', wor');buf.push('ld!');a = buf.join('');

Efficient JavaScript Tips

Faster trim method: (use simple regular expression) [bad]str.replace(/^\s+|\s+$/g, '');[better]str.replace(/^\s+/, '').replace(/^\s+$/, '');[much better]str = str.replace(/^\s+/, '');for (i = str.length - 1; i >=0; i--) { if (/\S/.test(str.charAt(i))) { str = str.substring(0, i + 1); break; }}

Efficient JavaScript Tips

Use popular JavaScript frameworks. (e.g. jQuery)

Misc.

Responsive Web Applications

Prefetching resourcesAJAXAvoid long-running scripts

HTML5

http://whatwg.org/html5Short tags:

<!DOCTYPE html><meta charset="UTF-8"><script src="xxx.js">, <style>...</style><script async ...>

Application Cache (offline data)https://developer.mozilla.org/En/Offline_resources_in_Firefoxhttp://www.whatwg.org/specs/web-apps/current-work/multipage/offline.htmlhttp://googlecode.blogspot.com/2009/04/gmail-for-mobile-html5-series-using.html

WebStorage/WebDatabase API

Mobile Web

Mobile device has lower hardware-profile so that the web performance is more important! iPhone Safari/Android browser/Opera Mini likes HTML5 (w/ a little CSS3)

References

Books

High Performance Web Sites, O'Reilly Even Faster Web Sites

Websites

Let's Make the Web Faster (Google)http://code.google.com/speed Exceptional Performance (Yahoo!)http://developer.yahoo.com/performance/High Performance Web Sites Bloghttp://www.stevesouders.com/blog/

Recommended