Jatinder Mann, an Internet Explorer PM at Microsoft, held the session 50 performance tricks to make your HTML5 apps and sites faster at BUILD 2012, providing many tips for creating faster web applications.
The advice provided by Mann was organized around six principles outlined below.
1. Quickly Respond to Network Requests.
- Avoid Redirections. 63% of the top 1,000 websites use redirections. They could increase the speed of their pages by 10% by not performing a redirect.
- Avoid Meta-refresh. 14% of the world’s URLs use meta-refreshes.
- Minimize server response time by using CDNs located as close as possible to the user
- Maximize the usage of concurrent connections by downloading resources from different domains
- Reuse connections. Don’t close the connection when responding to a request.
- Make sure data served by partner sites is not delaying page load
- Understand the network timing components –Redirect, Cache, DNS, Request, Response, etc. –. Use the Navigation Timing API on IE 9&10 to measure the time spent by the browser on each operation.
2. Minimize Bytes Downloaded. Minimize the amount of data downloaded when a web page is loaded. The average website downloads 777KB of data out of which 474KB being images, 128KB scripts, and 84KB Flash.
- Request gzipped content
- Keep resources locally in packages, such as the Package Resource Index generated for the Windows Store apps. That way they are readily available when necessary.
- Cache dynamic resources in HTML5 App Cache. This cache downloads the resources only once avoiding multiple network trips. The cache automatically re-downloads resources when the version of the application changes.
- Provide cacheable content whenever possible by using the “Expires” field in the response.
- Use conditional requests by setting the If-Modified-Since field of the request.
- Cache data requests –HTTP, XML, JSON, etc. – because about 95-96% of the requests don’t change over the day. Although a reasonable idea, less than 1% of the websites cache the requests received.
- Standardize file naming capitalization. While a server may recognize Icon.jpg as icon.jpg, they are different resources for the web platform, generating different network requests.
3. Efficiently Structure Markup. For IE use the latest markup standardization since it is the fastest. Earlier IE6-IE9 markup styles are recognized by IE 10 but they are not as fast as the latest one.
- Use the HTTP header field “X-UA-Compatible: IE=EmulateIE7” instead of the HTML tag <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"> to force IE run in a legacy mode that might be needed for certain business web applications. It’s faster that way.
- Stylesheets should be linked at the top of the page inside the <head>, after the <title> in order to provide a smooth rendering.
- Stylesheets should never be linked at the bottom of the page. The page may be flashing while loading.
- Avoid “@import” for hierarchical styles because it synchronously blocks the creation of CSS data structures and screen painting.
- Avoid embedded and inline styles because it forces the browser to make a context switch between the HTML and CSS parsers.
- Only include the necessary styles. Avoid downloading and parsing style that won’t be used.
- Link JavaScript only at the bottom of the page. This makes sure that the images, CSS, etc. are already loaded so the scripts can do they job without waiting on the resources, and avoiding context switching.
- Do not link JavaScript in the head of the page. Use the “defer” attribute if some scripts must be loaded at the beginning.
- Avoid inline JavaScript to avoid context switching.
- Use the “async” attribute to load JavaScript to make the entire script loading and executing asynchronous.
- Avoid duplicate code. 52% of the world’s web pages contain 100 lines or more of duplicate code such as linking a JavaScript file twice.
- Standardize on one JS framework, be it jQuery, Dojo, Prototype.js, etc.. The browser won’t have to load multiple frameworks that provide basically the same functionality.
- Don’t load scripts –FB, Twitter, etc. - just to be cool. They compete for resources.
4. Optimize Media Usage. Images are the most utilized resource, on average a website downloading 58 images.
- Avoid downloading too many images, keeping their number to maximum 20-30 due to page load time.
- Use image sprites to combine multiple images into one. This technique reduces the number of network connections, and the number of bytes downloaded and GPU cycles.
- Create image sprites by hand because tools may leave large empty spaces leading to larger downloads and more GPU cycles.
- Use PNG: best compromise between download size, decoding time, compatibility, and compression rate. JPEG may be used for photographs.
- Use the native image resolution to avoid unnecessary bytes download and CPU processing for scaling.
- Replace images with CSS3 gradients when possible.
- Replace images with CSS3 border radius when possible.
- Use CSS3 transforms to create move, rotate or skew effects.
- Use Data URI for small single images. It saves an image download.
- Avoid complex SVGs which require longer downloads and processing.
- Specify an image preview when including an HTML5. The browser won’t have to download the entire video to figure out what the preview image should be.
- Use HTML5 instead of Flash, Silverlight, or QuickTime. HTML5 is faster and the plug-in runtime takes system resources.
- Proactively download rich media asynchronously and keep it in the app cache.
5. Write Fast JavaScript.
- Use Integers when doing math operations in JavaScript, if possible. Floating point operations take much longer in JavaScript than their corresponding integer operations. Convert floating points into integers with Math.floor and Math.ceil, especially for computationally intensive operations.
- Minify JavaScript code for smaller downloads and better runtime performance.
- Initialize JS on demand. Load JS dynamically when needed.
- Minimize DOM interactions by caching variable such as document, body, etc.
- Use the built-in DOM code such as element.firstChild or node.nextSibling. They are highly optimized, better than what a third party library might provide.
- Use querySelectorAll for accessing a large number of DOM elements.
- Use .innerHTML to construct dynamic pages.
- Batch markup changes.
- Maintain a Small and Healthy DOM – maximum 1,000 elements.
- JSON is faster than XML.
- Use the browser’s JSON native methods.
- Don’t abuse the usage of regular expressions.
6. Know What Your Application is Doing
- Understand JavaScript timers: setTimeout and clearInterval. Don’t let timers run unless you use them for something. Also, combine timers.
- Align timers to the display frame at 16.7 ms if the monitor refreshes at 60Hz.
- Use requestAnimationFrame for animations to do graphics work in IE 10/Chrome/Firefox. It makes a call back when it is the time to paint, so there is no need for a timer.
- Use the visibility API (document.hidden, Visibilityhange) to determine the visibility state of the application, and throttle down activity when the page is hidden. Saves CPU and battery life.
Mann recommended using Windows Performance Tools to measure the performance of web pages in IE and optimizing pages for less CPU time and increasing parallelism.