| Eliminate render-blocking resources | • Inline critical resources • Defer non-critical resources • Remove resources which are not used on the page | | --- | --- | | Images | • Properly size images ◦ Resize images to save data ◦ Image should not be larger than the version rendered on screen ◦ Serve responsive images ◦ Use an image CDN ◦ Replace complex icons with SVG • Set an explicit width and height on image elements to reduce layout shifts and improve CLS • Defer offscreen images ◦ Consider lazy-loading offscreen and hidden images after critical resources have loaded • Efficiently encode images ◦ Optimize images either manually or through an automated optimization process with every upload • Serve images in next-gen formats ◦ Choose WebP or AVIF instead of PNG or JPEG for your images for better compression, faster downloads and less data consumption | | Minify CSS or remove unused CSS | • Minify CSS through an automated workflow • Remove identified unused CSS | | Minify JavaScript | • Minify JavaScript to reduce payload sizes and script parse time • Remove whitespace and any unnecessary code from the JS code file | | Enable text compression | • Enable text compression on your server • Use tools like gzip, Deflate or Brotli to compress text-based resources | | Preconnect to required origins | • Establish early connections to third-party origins with preconnect and dns-prefetch | | Reduce server response times (TTFB) | • Optimize your server response time by optimizing core conceptual tasks | | Avoid multiple page redirects | • Avoid redirects in resources required for your critical rendering path • Try to avoid redirecting users to a mobile version of your page • Opt for a responsive page instead | | Preload key requests | • Identify critical resources and instruct the browsers to download key resources as soon as possible via preload links in HTML • Consider using <link rel=preload> to prioritize fetching resources that are currently requested later in page load | | Use video format for animated content | • Avoid using large GIF formats for website video/animated content • Convert GIFs into video in loop in MPEG4/WebM • Opt for PNG/WebP for static images instead of GIF • Convert GIFs into HTML5 videos using https://web.dev/image-cdns/ | | Reduce impact of third-party code | • Identify slow third-party code and optimize • Limit the number of redundant third-party providers and try to load third-party code after your page has primarily finished loading | | Avoid non-composited animations | • See https://web.dev/stick-to-compositor-only-properties-and-manage-layer-count/ and https://web.dev/animations-guide/ • Animations which are not composited can be janky and increase CLS | | Lazy load third-party resources with facades | • On load: add a facade • On mouseover: preconnect the facade to third-party resources • On click: facade is replaced with third-party product | | Avoid high network payloads | • Aim to keep total byte size below 1600KiB • Defer requests until needed • Optimize requests to be as small as possible • Cache requests | | Serve static assets with efficient cache policy | • Cache immutable static assets for a year or longer • Use no-cache for resources where freshness matters • A long cache lifetime can speed up repeat visits to your page | | Avoid excessive DOM size | • Try to aim for fewer than ~1500 DOM elements • Try to aim for a tree depth of <32 elements and less than 60 children/parent element • Create DOM nodes only when needed, and destroy nodes when they're no longer needed | | Avoid chaining critical requests | • Minimize number of critical resources (eliminate, defer download, etc.) • Optimize number of critical bytes • Optimize order in which resources are loaded • Consider reducing the length of chains, reducing the download size of resources, or deferring the download of unnecessary resources to improve page load | | User Timing marks and measures | • Consider instrumenting your app with the User Timing API to measure your app's real-world performance during key user experiences • Use the https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html, which makes use of the Profiler API, to measure the rendering performance of your components | | Reduce JavaScript execution time | • Evaluate biggest contributors to execution time • Only send code that users need by implementing code splitting • Minify and compress code • Remove unused code • Reduce network trips through caching | | Minimize main thread work | • Reduce the time spent parsing, compiling and executing JS • Delivering smaller JS payloads helps with this • Consider https://aerotwist.com/blog/the-anatomy-of-a-frame/ for an overview of how Chromium renders web pages and https://developer.chrome.com/docs/devtools/lighthouse#main to learn how to use Chrome DevTools to investigate exactly what your main thread is doing as the page loads | | Ensure text remains visible during webfont load | • Preload webfonts • Google fonts • Leverage the font-display CSS feature to ensure text is user-visible while webfonts are loading | | Ensure lazy load for Largest Content Ful Paint element/image | • Load images above the fold more eagerly as above-the-fold images that are lazily loaded render later in the page lifecycle, which can delay the largest contentful paint | | Avoid long main-tread tasks | • Consider https://web.dev/articles/reduce-javascript-payloads-with-code-splitting large scripts as they are often a major cause of Long Tasks • Also keep an eye on third-party scripts; their Long Tasks can delay primary content from getting interactive | | Avoid large layout shitfs | • Identify causes of CLS and fix issues (e.g., images without dimensions; ads, embeds, and other late-loaded content; animations; web fonts) • Reduce CLS by ensuring pages are eligible for the bfcache | | Use passive listeners to improve scrolling performance | • Mark touch and wheel event listeners as passive to improve your page's scroll performance | | Avoid document.write() | • Remove all uses of document.write() in your code. If it's being used to inject third-party scripts, try using https://web.dev/critical-rendering-path-adding-interactivity-with-javascript/#parser_blocking_versus_asynchronous_javascript instead • If third-party code is using document.write(), ask the provider to support asynchronous loading • For users on slow connections, external scripts dynamically injected via document.write() can delay page load by tens of seconds | | Use a <meta name="viewport"> tag with width or initial-scale | • Use a <meta name="viewport"> not only to optimize app for mobile screen sizes, but also to prevent https://developer.chrome.com/blog/300ms-tap-delay-gone-away/?utm_source=lighthouse&utm_medium=lr |