Web performance optimization
class: center, middle .title[ Front-end training # Web Performance Optimization ] --- # Web Performance Statistic 72% of RWD sites whose small screen design weighs the same as the large screen design. Mobile first means performance first. ## Unhappy users - 47% of consumers expect a web page to load in 2 seconds or less; - 78% of users say they’ve felt stress or anger while using a slow website; - 4% of people have thrown their phone while using a slow mobile site --- # How fast is fast? - **< 100ms** feels instantaneous - **< 300ms** noticeable but still fast - **< 1000ms** computer is working - **+1s** mental context switch start - **+10s** I’ve got better things to do... --- # Anatomy of a web page loading - DNS resolution - TCP connection - Send request - Wait for response - Download response - Parse (DOM, CSSOM) - Request sub-resource - Execute JS/Apply CSS - Compose Layout - Render --- #Network stages - **DNS Lookup** - Time to map the domain name (www.google.com) to an IP address - **Initial Connection** - Time to open a connection to the server and get an acknowledgement - **Wait Time** - Time between initial connection and the first byte of the response (time it takes the server to “cook” the page). - **Content Download** - Time it takes to download the content that the server has finished creating --- # Network stages in Chrome Dev Tools
.columns[.col-50[  ].col-50[  ]]
.center[  ] --- layout: true # Constructing the Object Model. DOM Before the browser can render the page it needs to construct the DOM and CSSOM trees. --- ### Simple DOM example: ``` html
Critical Path
Hello
web performance
students!
``` --- .img-wrap-80[] --- Chrome DevTools Timeline allows us to capture and inspect the construction and processing costs of DOM and CSSOM
.img-wrap-80[] --- layout: true # Constructing the Object Model. CSSOM Before the browser can render the page it needs to construct the DOM and CSSOM trees. --- .img-wrap-80[] “CSS Object Model”, or CSSOM for short: .img-wrap-80[] --- Chrome DevTools Timeline allows us to capture and inspect the construction and processing costs of DOM and CSSOM
.img-wrap-80[] --- layout: false # Render-tree construction, Layout, and Paint All the steps the browser went through: - Process HTML markup and build the DOM tree. - Process CSS markup and build the CSSOM tree. - Combine the DOM and CSSOM into a render tree. - Run layout on the render tree to compute geometry of each node. - Paint the individual nodes to the screen. .img-wrap-70[] --- layout: true # Render Blocking CSS --- - By default, CSS is treated as a render blocking resource. - Media types and media queries allow us to mark some CSS resources as non-render blocking. - All CSS resources, regardless of blocking or non-blocking behavior, are downloaded by the browser. --- CSS is a render blocking resource, get it down to the client as soon and as quickly as possible to optimize the time to first render. The experience on the right is often referred to as a “Flash of Unstyled Content” (FOUC). .columns[.col-50[.img-wrap-60[  ]].col-50[.img-wrap-60[  ]]] --- ### Use CSS media queries for responsiveness! CSS “media types” and “media queries” allow us to address use-cases when the page is being printed, or being projected onto a large monitor: ``` html
``` --- layout: false # Adding Interactivity with JavaScript When the HTML parser encounters a script tag, it pauses its process of constructing the DOM and yields control over to the JavaScript engine; once the JavaScript engine has finished running, the browser then picks up from where it left off and resumes the DOM construction. - executing our inline script blocks DOM construction, which will also delay the initial render. - the browser will delay script execution until it has finished downloading and constructing the CSSOM, and while we’re waiting, the DOM construction is also blocked. - in the case of an external JavaScript file the browser will also have to pause and wait for the script to be fetched from disk, cache, or a remote server. --- # Adding Interactivity with JavaScript Adding the async keyword to the script tag tells the browser that it should not block the DOM construction while it waits for the script to become available - this is a huge performance win! ```html
Critical Path: Script Async
Hello
web performance
students!
``` --- layout: true # Optimizing the Critical Rendering Path --- No CSS, no JavaScript, or other types of resources .small[ ```html
Critical Path: No Style
Hello
web performance
students!
```] .img-wrap-60[] --- The same page but with an external CSS file: .small[ ```html
Hello
web performance
students!
```] .img-wrap-80[] --- Let’s add an extra JavaScript file: .small[ ```html
Hello
web performance
students!
```] .img-wrap-80[] --- We can add the “async” attribute to the script tag to unblock the parser: .small[ ```html
Hello
web performance
students!
```] .img-wrap-80[] --- Let’s say the CSS stylesheet was only needed for print: .small[ ```html
Hello
web performance
students!
```] .img-wrap-80[] --- ### The general sequence of steps to optimize the critical rendering path is: 1. Analyze and characterize your critical path: number of resources, bytes, length. 2. Minimize number of critical resources: eliminate them, defer their download, mark them as async, etc. 3. Optimize the order in which the remaining critical resources are loaded: you want to download all critical assets as early as possible to shorten the critical path length. 4. Optimize the number of critical bytes to reduce the download time (number of roundtrips). --- layout: false # Reflows & Repaints The render tree is the visual part of the DOM tree. So if you're hiding a div with display: none, it won't be represented in the render tree. Changing a property of a Render Tree node could trigger: - **Reflow** (or layout) - parts of the render tree will need to be revalidated and the node dimensions recalculated (resize window, font changes, height, scrollTop, etc). - **Repaint** (or redraw) - Once the render tree is constructed, the browser can paint (draw) the render tree nodes on the screen (changes in geometric properties of a node or stylistic change: color, visibility, outline) Repaints and reflows can be expensive, they can hurt the user experience, and make the UI appear sluggish. --- # What triggers a reflow or a repaint - Adding, removing, updating DOM nodes - Hiding a DOM node with **`display: none;`** (reflow and repaint) or **`visibility: hidden;`** (repaint only, because no geometry changes) - Moving, animating a DOM node on the page - Adding a stylesheet, tweaking style properties - User action such as resizing the window, changing the font size, or scrolling --- # Minimizing repaints and reflows Batch DOM changes and perform them not in the live DOM tree. You can: - use a documentFragment to hold temp changes; - clone the node you're about to update, work on the copy, then swap the original with the updated clone; - hide the element with display: none (1 reflow, repaint), add 100 changes, restore the display (another reflow, repaint). This way you trade 2 reflows for potentially a hundred. Don't ask for computed styles excessively. If you need to work with a computed value, take it once, cache to a local var and work with the local copy. Using absolute positioning makes element a child of the body in the render tree, so it won't affect too many other nodes when you change it's styles. --- # CSS Transitions & Animations - Offload to GPU - Multithreaded - Subpixel rendering --- layout: true # Image optimization --- ## Size by Content-Type Images are the devil. Consider using CSS, sprites, symbol fonts & SVG .center[] --- ### Eliminating and replacing images - Eliminate unnecessary image resources - Leverage CSS3 effects where possible - Use web fonts instead of encoding text in images --- ### Vector vs. Raster images - Vector images are ideal for images that consist of geometric shapes - Vector images are zoom and resolution-independent - Raster images should be used for complex scenes with lots of irregular shapes and details -- .columns[.col-50[.img-wrap-80[] ].col-50[.img-wrap-80[] ]] --- ### Implications of high-resolution screens - High resolution screens have multiple device pixels per CSS pixel - High resolution images require significantly higher number of pixels and bytes - Image optimization techniques are the same regardless of resolution .img-wrap-80[] --- ### Optimizing vector images - SVG is an XML-based image format - SVG files should be minified to reduce their size - SVG files should be compressed with GZIP ```html
``` --- ### Optimizing raster images - A raster image is a grid of pixels - Each pixel encodes color and transparency information - Image compressors use a variety of techniques to reduce the number of required bits per pixel to reduce file size of the image --- ### Optimizing raster images .img-wrap-80[] ### Note: Left to right (PNG): 32-bit (16M colors), 7-bit (128 colors), 5-bit (32 colors). Complex scenes with gradual color transitions (gradients, sky, etc.) require larger color palettes to avoid visual artifacts such as the pixelated sky in the 5-bit asset. On the other hand, if the image only uses a few colors, then a large palette is simply wasting precious bits! --- ### Selecting the right image format - Start by selecting the right universal format: GIF, PNG, JPEG - Experiment and select the best settings for each format: quality, palette size, etc. - Consider adding WebP and JPEG XR assets for modern clients .img-wrap-70[] --- ## Image compression tools - [https://tinypng.com/](https://tinypng.com/) - [http://www.punypng.com/](http://www.punypng.com/) - [http://compresspng.com/](http://compresspng.com/) - [http://compressnow.com/](http://compressnow.com/) - [http://www.jpegmini.com/](http://www.jpegmini.com/) More tools for image optimization - [http://addyosmani.com/blog/image-optimization-tools/](http://addyosmani.com/blog/image-optimization-tools/) --- layout: false # Webfont optimization - [Anatomy of a webfont](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization#anatomy-of-a-webfont) - [Defining font family with @font-face](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization#defining-font-family-with-font-face) - [Optimizing loading and rendering](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization#optimizing-loading-and-rendering) - [Optimization checklist](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization#optimization-checklist) --- # HTTP caching Fetching something over the network is both slow and expensive: large responses require many roundtrips between the client and server, which delays when they are available and can be processed by the browser, and also incurs data costs for the visitor. As a result, the ability to cache and reuse previously fetched resources is a critical aspect of optimizing for performance. - [Validating cached responses with ETags](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#validating-cached-responses-with-etags) - [Cache-Control](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#cache-control) - [Defining optimal Cache-Control policy](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#defining-optimal-cache-control-policy) - [Invalidating and updating cached responses](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#invalidating-and-updating-cached-responses) - [Caching checklist](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#caching-checklist) --- # PageSpeed Rules and Recommendations - Eliminate render-blocking JavaScript and CSS - Optimize JavaScript Use - Prefer async JavaScript resources - Defer parsing JavaScript - Avoid long running JavaScript - Optimize CSS Use - Put CSS in the document head - Avoid CSS imports - Inline render-blocking CSS --- # Network checklist - GZIP - Minify CSS & JS - Combine CSS & JS - Cache static resources - Use a CDN - Optimize images - Sprite images - base64 images --- # Text compression with GZIP - GZIP performs best on text-based assets: CSS, JavaScript, HTML - All modern browsers support GZIP compression and will automatically request it - Your server needs to be configured to enable GZIP compression - Some CDNs require special care to ensure that GZIP is enabled .img-wrap-100[] --- # Use efficient CSS selectors The following categories of rules are considered to be inefficient: - Rules with descendant selectors ``` css body * { } .hide-scrollbars * { } html #atticPromo ul li a { } ``` - Rules with child or adjacent selectors ``` css body > * { } ul > li > a { } ``` - Rules that apply the :hover pseudo-selector to non-link elements for IE7 and IE8 ``` css h3:hover { } .foo:hover { } ``` --- # Tools - webpagetest.org [http://webpagetest.org](http://webpagetest.org) - YSlow [http://developer.yahoo.com/yslow/](http://developer.yahoo.com/yslow/) - PageSpeed [http://code.google.com/speed/page-speed/](http://code.google.com/speed/page-speed/) --- # Related resources - Chrome Dev Tools Overview [https://developer.chrome.com/devtools](https://developer.chrome.com/devtools) - Jank Free [http://jankfree.org/](http://jankfree.org/) - Website Performance Optimization. [Udacity cource](https://www.udacity.com/course/ud884) - Mobile Web Development [Udacity cource](https://www.udacity.com/course/cs256) - Web Fundamentals. Optimizing Performance [https://developers.google.com/web/fundamentals/performance/](https://developers.google.com/web/fundamentals/performance/)