introduc$on to modern performance best prac$ces for web apps. We will dive into the latest tools and best prac$ces for launching an ideal end-user experience. Find out how you can leverage Chrome Developer Tools, Google PageSpeed, and WebPageTest to get started improving your applica$ons. author twitter handle
Common performance best prac$ces – Dive into PageSpeed Rules + look at SiteSpeed.io § A refactoring example – We will have an interac$ve refactoring session of an exis$ng app to reach an ideal pagespeed score § Discuss common tools that automate these techniques (ngx_pagespeed, yo*aa, cloudflare, etc) § Dive into WebPageTest to show how to test web performance from any browser § Recap best prac$ces and follow up with resources
great user experience -Under 100ms is perceived as reac$ng instantaneously -A 100ms to 300ms delay is percep$ble -1 second is about the limit for the user's flow of thought to stay uninterrupted -Users expect a site to load in 2 seconds -ASer 3 seconds, 40% will abandon your site. -10 seconds is about the limit for keeping the user's a*en$on §Modern applica0ons spend more 0me in the browser than on the server-side
performance best prac$ces on server-side and client-side • Use the 14kb rule and op$mize cri$cal path for instant loading • Implement a responsive design + responsive image strategy • Implemen$ng a touch-first strategy • Using task runners to build and deploy code for produc$on
the client-side and server side as possible (javascript, css, images, fonts, content). • Leverage a CDN + browser caching • Use a reverse proxy cache on the server side • Queuing - Do not delay the user experience for tasks that can be executed in the background • Async - Op$mize work to execute concurrently / asynchronously
policy by sejng far future expires header • For dynamic components: use an appropriate Cache-Control header to help the browser with condi$onal requests
the same content on different URLs, then that content will be fetched and stored multiple times. Tip: note that URLs are case sensitive! § Ensure the server provides a validation token (ETag): validation tokens eliminate the need to transfer the same bytes when a resource has not changed on the server. § Identify which resources can be cached by intermediaries: those with responses that are identical for all users are great candidates to be cached by a CDN and other intermediaries. § Determine the optimal cache lifetime for each resource: different resources may have different freshness requirements. Audit and determine the appropriate max-age for each one. § Determine the best cache hierarchy for your site: the combination of resource URLs with content fingerprints, and short or no-cache lifetimes for HTML documents allows you to control how quickly updates are picked up by the client. § Minimize churn: some resources are updated more frequently than others. If there is a particular part of resource (e.g. JavaScript function, or set of CSS styles) that are often updated, consider delivering that code as a separate file. Doing so allows the remainder of the content (e.g. library code that does not change very often), to be fetched from cache and minimizes the amount of downloaded content whenever an update is fetched.
for the h6p response should be queued • Sending emails/sms/push no0fica0ons + pos0ng to social accounts • Upda0ng profiles and discovering friends from social accounts • Analy0cs + Instrumenta0on • …
• To deliver the fastest $me to first render, you want to minimize and (where possible) eliminate the number of cri$cal resources on the page, minimize the number of downloaded cri$cal bytes, and op$mize the cri$cal path length. • Op$mize JavaScript Use • JavaScript resources are parser blocking by default unless marked as async or added via a special JavaScript snippet. Parser blocking JavaScript forces the browser to wait for the CSSOM and pauses construc$on of the DOM, which in turn can significantly delay the $me to first render. • Prefer async JavaScript resources • Async resources unblock the document parser and allow the browser to avoid blocking on CSSOM prior to execu$ng the script. Olen, if the script can be made async, it also means it is not essen$al for the first render - consider loading async scripts aler the ini$al render. • Avoid synchronous server calls • Use the navigator.sendBeacon() method to limit data sent by XMLH*pRequests in unload handlers. Because many browsers require such requests to be synchronous, they can slow page transi$ons, some$mes no$ceably. The following code shows how to use navigator.sendBeacon() to send data to the server in the pagehide handler instead of in the unload handler. • Defer parsing JavaScript • Any non-essen$al scripts that are not cri$cal to construc$ng the visible content for the ini$al render should be deferred to minimize the amount of work the browser has to perform to render the page.
Long running JavaScript blocks the browser from construc$ng the DOM, CSS OM, and rendering the page. As a result, any ini$aliza$on logic and func$onality that is non-essen$al for the first render should be deferred un$l later. If a long ini$aliza$on sequence needs to be run, consider splijng it into several stages to allow the browser to process other events in between. • Op$mize CSS Use • CSS is required to construct the render tree and JavaScript will olen block on CSS during ini$al construc$on of the page. You should ensure that any non- essen$al CSS is marked as non-cri$cal (e.g. print and other media queries), and that the amount of cri$cal CSS and the $me to deliver it is as small as possible. • Put CSS in the document head • All CSS resources should be specified as early as possible within the HTML document such that the browser can discover the <link> tags and dispatch the request for the CSS as soon as possible. • Avoid CSS imports • CSS import (@import) direc$ve enables one stylesheet to import rules from another stylesheet file. However, these direc$ves should be avoided because they introduce addi$onal roundtrips into the cri$cal path: the imported CSS resources are discovered only aler the CSS stylesheet with the @import rule itself has been received and parsed. • Inline render-blocking CSS • For best performance, you may want to consider inlining the cri$cal CSS directly into the HTML document. This eliminates addi$onal roundtrips in the cri$cal path and if done correctly can be used to deliver a “one roundtrip” cri$cal path length where only the HTML is a blocking resource.
rules with tag names or classes • Use the most specific category possible • Avoid the descendant selector • Ques$on all usages of the child selector • Rely on inheritance • Avoid vendor-specific features unless necessary • Remove unused css (uncss)
and scale independent, which makes them a perfect fit for the mul$- device and high-resolu$on world. • Minify and compress SVG assets: XML markup produced by most drawing applica$ons olen contains unnecessary metadata which can be removed; ensure that your servers are configured to apply GZIP compression for SVG assets. • Pick best raster image format: determine your func$onal requirements and select the one that suits each par$cular asset. • Experiment with op$mal quality sejngs for raster formats: don’t be afraid to dial down the “quality” sejngs, the results are olen very good and byte savings are significant. • Remove unnecessary image metadata: many raster images contain unnecessary metadata about the asset: geo informa$on, camera informa$on, and so on. Use appropriate tools to strip this data. • Serve scaled images: resize images on the server and ensure that the “display” size is as close as possible to the “natural” size of the image. Pay close to a*en$on to large images in par$cular, as they account for largest overhead when resized! • Automate, automate, automate: invest into automated tools and infrastructure that will ensure that all of your image assets are always op$mized.
determine the performance impact of web fonts on the page: • The total number of fonts and font-weights used on the page. • The total byte size of fonts used on the page. • The transfer latency of the font resource. • The $me when the font downloads are ini$ated.
do not use too many fonts on your pages, and for each font, minimize the number of used variants. This will assist in delivering a more consistent and a faster experience for your users. • Subset your font resources: many fonts can be subset, or split into mul$ple unicode-ranges to deliver just the glyphs required by a par$cular page - this reduces the filesize and improves download speed of the resource. However, when defining the subsets be careful to op$mize for font re-use - e.g. you don’t want to download a different but overlapping set of characters on each page. A good prac$ce is to subset based on script - e.g. La$n, Cyrillic, and so on. • Deliver op$mized font formats to each browser: each font should be provided in WOFF2, WOFF, EOT, and TTF formats. Make sure to apply GZIP compression to EOT and TTF formats, as they are not compressed by default. • Specify revalida$on and op$mal caching policies: fonts are sta$c resources that are infrequently updated. Make sure that your servers provide a long-lived max-age $mestamp, and a revalida$on token, to allow for efficient font re-use between different pages. • Use Font Loading API to op$mize the Cri$cal Rendering Path: default lazyloading behavior may result in delayed text rendering. Font Loading API allows us to override this behavior for par$cular fonts, and to specify custom rendering and $meout strategies for different content on the page. For older browsers that do not support the API, you can use the webfontloader JavaScript library or use the CSS inlining strategy.
same content on different URLs, then that content will be fetched and stored mul$ple $mes. Tip: note that URLs are case sensi$ve! • Ensure the server provides a valida$on token (ETag): valida$on tokens eliminate the need to transfer the same bytes when a resource has not changed on the server. • Iden$fy which resources can be cached by intermediaries: those with responses that are iden$cal for all users are great candidates to be cached by a CDN and other intermediaries. • Determine the op$mal cache life$me for each resource: different resources may have different freshness requirements. Audit and determine the appropriate max-age for each one. • Determine the best cache hierarchy for your site: the combina$on of resource URLs with content fingerprints, and short or no-cache life$mes for HTML documents allows you to control how quickly updates are picked up by the client. • Minimize churn: some resources are updated more frequently than others. If there is a par$cular part of resource (e.g. JavaScript func$on, or set of CSS styles) that are olen updated, consider delivering that code as a separate file. Doing so allows the remainder of the content (e.g. library code that does not change very olen), to be fetched from cache and minimizes the amount of downloaded content whenever an update is fetched.
path: number of resources, bytes, length. • Minimize number of cri$cal resources: eliminate them, defer their download, mark them as async, etc. • Op$mize the order in which the remaining cri$cal resources are loaded: you want to download all cri$cal assets as early as possible to shorten the cri$cal path length. • Op$mize the number of cri$cal bytes to reduce the download $me (number of roundtrips).
tomorrows an0-pa6erns • The limita$ons of HTTP/1.X forced us to develop various applica$on workarounds (sharding, concatena$on, spri$ng, inlining, etc.) to op$mize performance. However, in the process we’ve also introduced numerous regressions: poor caching, unnecessary downloads, delayed execu$on, and more. • HTTP/2 eliminates the need for these hacks and allows us to both simplify our applica$ons and deliver improved performance. • You should unshard (domains), unconcat (css/javascript), and unsprite your assets (images) • You should switch from inlining to server push • Read Ilya Grigorik awesome book on browser performance - h*p://hpbn.co/h*p2
§ Implement caching and queuing to improve server-side latency § Start with a solid founda0on by leveraging yeoman or google web starter kit § Leverage nginx/apache boilerplate server configs for sane web server secngs § Follow best prac0ces to op0mize delivery of javascript, css, images, and fonts § Op0mize for cri0cal rendering path § Google Chrome Developer Tools is your friend for profiling § Automate build and deployment best prac0ces with Gulp/Grunt § Use PageSpeed Insights, SiteSpeed.io, WebPageTest.org as part of development lifecycle § If you can’t improve the code then leverage mod_pagespeed, Yo6a, or CloudFlare § Monitor the real user experience with applica0on performance management tools
- Aditya Punjabi § High Performance Browser Networking - Ilya Grigorik § Scaling Front-End Performance - Patrick Meehan § Experiences of HTTP/2 in the real world - Michael Gooding § Outages, ownership, and cralsmanship: A devops story - Adam Cath