{"id":15407992,"url":"https://github.com/danilqa/web-performance-handbook","last_synced_at":"2025-04-18T14:54:52.518Z","repository":{"id":201164813,"uuid":"706799681","full_name":"Danilqa/web-performance-handbook","owner":"Danilqa","description":"📖 Selected and essential information on web performance collected in one place.","archived":false,"fork":false,"pushed_at":"2024-05-17T14:44:10.000Z","size":58,"stargazers_count":21,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-29T06:22:28.440Z","etag":null,"topics":["bundle","glossary","handbook","javascript","metrics","performance","react","terms","web-performance"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Danilqa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-18T16:31:31.000Z","updated_at":"2024-10-01T15:29:26.000Z","dependencies_parsed_at":"2024-10-21T13:04:44.940Z","dependency_job_id":null,"html_url":"https://github.com/Danilqa/web-performance-handbook","commit_stats":{"total_commits":18,"total_committers":1,"mean_commits":18.0,"dds":0.0,"last_synced_commit":"2c7e37a0ce2e6b970138497fccf521a0f01ddc9c"},"previous_names":["danilqa/performance-glossary"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Danilqa%2Fweb-performance-handbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Danilqa%2Fweb-performance-handbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Danilqa%2Fweb-performance-handbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Danilqa%2Fweb-performance-handbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Danilqa","download_url":"https://codeload.github.com/Danilqa/web-performance-handbook/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249507515,"owners_count":21283220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","glossary","handbook","javascript","metrics","performance","react","terms","web-performance"],"created_at":"2024-10-01T16:30:34.473Z","updated_at":"2025-04-18T14:54:52.496Z","avatar_url":"https://github.com/Danilqa.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Web Performance Handbook\n\n\u003cimg align=\"right\" width=\"100\" height=\"100\" title=\"Logo\"\nsrc=\"./static/images/logo.png\" /\u003e\n\nThis handbook helps to quickly understand the topic and start improving performance. It contains a metrics glossary, \na compilation of useful tools, and a catalog of necessary materials. \n\nI really want to share proven knowledge to make the web even better and faster. Support and bookmark the project by giving it a star! ⭐\n\n## Table of Contents\n\n- [Web Performance Handbook](#web-performance-handbook)\n  - [Table of Contents](#table-of-contents)\n  - [Tools](#tools)\n    - [Global Stats](#global-stats)\n    - [Treo — Site Speed](#treo--site-speed)\n    - [Web Vitals (extension)](#web-vitals-extension)\n    - [PageSpeed Insights](#pagespeed-insights)\n    - [WebPageTest](#webpagetest)\n    - [Lighthouse](#lighthouse)\n    - [DevTools Performance (with experimental features)](#devtools-performance-with-experimental-features)\n  - [Monitoring](#monitoring)\n    - [LHCI Server (open-source)](#lhci-server-open-source)\n    - [DebugBear (paid)](#debugbear-paid)\n  - [Optimizing Hydration](#optimizing-hydration)\n      - [Disable Hydration](#disable-hydration)\n      - [Server Components](#server-components)\n  - [Optimizing Page Load Speed](#optimizing-page-load-speed)\n    - [Image Proxy: Use avif / webp / progressive jpeg](#image-proxy-use-avif--webp--progressive-jpeg)\n    - [Data Compression with brotli](#data-compression-with-brotli)\n  - [Optimizing Bundle](#optimizing-bundle)\n    - [Tools to Analyze](#tools-to-analyze)\n      - [Statoscope](#statoscope)\n      - [Bundle Analyzer](#bundle-analyzer)\n      - [Why?](#why)\n    - [Webpack Alias: Remove 3-rd Party Code from Bundle](#webpack-alias-remove-3-rd-party-code-from-bundle)\n    - [Lazy Code Loading: On Viewport, on Interaction](#lazy-code-loading-on-viewport-on-interaction)\n    - [Deduplication](#deduplication)\n    - [Webpack: Magic Comments on Imports](#webpack-magic-comments-on-imports)\n  - [React Tools](#react-tools)\n    - [Why Did You Render](#why-did-you-render)\n    - [React DevTools Profiler](#react-devtools-profiler)\n  - [Learning Resources](#learning-resources)\n    - [Browser Rendering Optimization Course](#browser-rendering-optimization-course)\n    - [Web App Performance Course](#web-app-performance-course)\n  - [Metrics](#metrics)\n    - [CLS](#cls)\n    - [DCL](#dcl)\n    - [FCP](#fcp)\n    - [FID](#fid)\n    - [FP](#fp)\n    - [INP](#inp)\n    - [L](#l)\n    - [LCP](#lcp)\n    - [SI](#si)\n    - [TBT](#tbt)\n    - [TTI](#tti)\n    - [TTFB](#ttfb)\n\n---\n\n## Tools\n\n### Global Stats\n\nBrowser market share worldwide. This allows you to see device and browser usage in specific regions.\n\n[link](https://gs.statcounter.com/browser-market-share/)\n\n### Treo — Site Speed\n\nHow to view historical performance data of real users?\n\nAllows viewing annual reports for websites based on Light House and CrUX (Chrome User Experience Report) metrics. \nFilters can also be set, such as internet connection speed, location, and device. Uses real user data. Very useful for observing trends \nand metrics specific to certain user types.\n\n[link](https://treo.sh/sitespeed)\n\n### Web Vitals (extension)\n\nCollect metrics such as [**INP**](#INP), [LCP](#LCP), [CLS](#CLS), [FIP](#FIP), [FCP](#FCP), and [TTFB](#TTFB) in real-time and easily view them in a popup. \nEnabling logging in options can assist in debugging [INP](#INP).\n\n[link](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma/)\n\n### PageSpeed Insights\n\nAllows you to conduct Lighthouse performance tests remotely, in a more realistic environment. Can be used for taking \nmore objective measurements, as computer powers vary among teammates. Especially, developers tend to have significantly \nmore powerful computers than the general market. Also, for popular websites, it provides data from the CrUX report.\n\n[link](https://pagespeed.web.dev)\n\n### WebPageTest\n\nThe same as previous, but on steroids. Allows you to set up a testing environment: location, browser, its available \nfunctionality, connection speed, etc. Can record a video of the loading process, providing more understandable and \ndetailed reports on the webpage loading process and requests.\n\n[link](https://www.webpagetest.org/)\n\n### Lighthouse\n\nA tool designed for assessing the quality of a web page, focusing on core vitals metrics, SEO, and accessibility.\nIt is built into Chrome DevTools and can be also used as a CLI tool, making it especially useful for measuring \nperformance during CI processes. Additionally, it offers practical suggestions to enhance the quality and loading \nspeed of the page.\n\n### DevTools Performance (with experimental features)\n\nRecord and analyze the performance of a page. It allows you to see the loading process in detail, including the\nloading, scripting, rendering, and painting phases. It also provides a timeline of events, which can be used to\nunderstand what is happening under the hood. For instance, you can see how long the hydration takes.\n\nHint:\\\nEnable the experimental \"timeline-*\" features in DevTools settings to see more information about events. It's especially \nuseful for React apps. By default, it's challenging to understand what's really happening because of tons of anonymous\nevents.\n\n---\n\n## Monitoring\n\n### LHCI Server (open-source)\n\nAllows you to store historical performance data and see differences between builds. It integrates with CI/CD processes.\n\n[GitHub link](https://github.com/GoogleChrome/lighthouse-ci/blob/main/docs/server.md)\n\n### DebugBear (paid)\n\nA tool for monitoring web performance and Lighthouse metrics. It can be used to set up alerts for performance regressions.\n\n[link](https://www.debugbear.com/)\n\n---\n\n## Optimizing Hydration\n\n#### Disable Hydration\n\nReact has a trick that allows you to disable hydration for a component. The server will render it once, then send an HTML that won't be hydrated. Perfect for static content.\n\n```jsx\n\u003cdiv suppressHydrationWarning dangerouslySetInnerHTML={{ __html: \"\" }}/\u003e\n```\n\nIt's also available as part of an npm package:\n[react-lazy-hydration](https://www.npmjs.com/package/react-lazy-hydration)\n\n#### Server Components\n\n[more them](https://nextjs.org/docs/app/building-your-application/rendering/server-components)\n\n---\n\n## Optimizing Page Load Speed\n\n### Image Proxy: Use avif / webp / progressive jpeg\n\nTo improve LCP and reduce traffic volume, you can use image proxies or CDNs. They will reformat, resize, and optimize your images on the fly, and cache them immediately.\n\nPossible solutions:\n1. Cloudflare Images\n2. UploadCare\n3. [ImageProxy](https://github.com/imgproxy/imgproxy)\n4. Implement manually: [Good starting point](https://github.com/Danilqa/image-proxy-service).\n\n### Data Compression with brotli\n\nReduce the size of static files by 15-17% (the exact number is better to calculate using your own resources). The best results can be achieved using brotli with compression level 11. However, the compression time is longer than with gzip (level 9), so it's better to avoid using it on-the-fly and only use pre-compressed or cached versions.\n\n[Comparison table](https://cran.r-project.org/web/packages/brotli/vignettes/brotli-2015-09-22.pdf)\n\n---\n\n## Optimizing Bundle\n\n### Tools to Analyze\n\n#### Statoscope\n\nBuilt elaborated report of your bundle. Separates scripts from initial loading and asynchronous loading.\n\n[Github Link](https://github.com/statoscope/statoscope)\n\n#### Bundle Analyzer\n\n[Github Link](https://github.com/webpack-contrib/webpack-bundle-analyzer)\n\n#### Why?\n\nIdentifies why a package has been installed. Especially useful for transitive dependencies.\n\n```sh\nyarn why\npnpm why\n```\n\n### Webpack Alias: Remove 3-rd Party Code from Bundle\n\n```js\nconst mockEmptyModule = path.resolve('./mock-empty-module.js');\n// ...\nconfig.resolve.alias['reactstrap/lib/Carousel.js'] = mockEmptyModule;\n```\n\n### Lazy Code Loading: On Viewport, on Interaction\n\nThe key principle is to avoid including code in the initial load that can be downloaded later. Instead, download it when a user is about to view it in their viewport, during idle time, or at the start of an interaction. \n\nFor React, combine dynamic module import with Suspense.\n\n[real world example](https://dev.to/dsitdikov/my-journey-to-accelerate-load-times-in-heavy-frontend-30c7/)\n\n### Deduplication\n\nIf it's safe, align the minor versions of installed modules that are duplicated.\n\n```sh\nyarn dedupe\nnpm dedupe\npnpm dedupe\n```\n\n### Webpack: Magic Comments on Imports\n\nAllows you to rename chunks, regroup, prefetch lazy chunks and more.\n\n[link](https://webpack.js.org/api/module-methods/#magic-comments)\n\n---\n\n## React Tools\n\n### Why Did You Render\n\nA tool for detecting unnecessary re-renders. It can be used to find components that are re-rendered too often. Write \nmessages to the console.\n\n[link](https://github.com/welldone-software/why-did-you-render)\n\n### React DevTools Profiler\n\nShows the time spent rendering each component and how many times it was rendered. To observe why it was rendered, \nenable the \"Record why each component rendered while profiling\" flag in the settings.\n\n[link](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)\n\n---\n\n## Learning Resources\n\n### Browser Rendering Optimization Course\n\nProvides a solid basis for understanding how a browser renders a document and what happens behind the scenes.\n\n[link](https://www.udacity.com/course/browser-rendering-optimization--ud860)\n\n### Web App Performance Course\n\nReveals many subtleties and working practices about optimization that are not usually written about. \n\n[link](https://frontendmasters.com/courses/web-app-performance/)\n\n---\n\n## Metrics\n\nThis is a list of the most common metrics which may appear in articles, DevTools, Lighthouse, and other\nvarious tools for working with web performance. Everything is sorted in the alphabetical order.\n\nThe factual data is primarily sourced from MDN, web.dev and w3c, however the short description has been rewritten and enhanced.\n\n\n### CLS\n\n**Cumulative Layout Shift**\n\nMeasurement Unit: Score (lower is better)\n\nShows how often users experience unexpected changes in the layout. It measures the \ninstability of elements and their overall impact. For example, the banner element changes its height \nduring the loading process, which causes a shift in the elements below.\n\n[more details](https://web.dev/articles/cls)\n\n### DCL\n\n**DOMContentLoaded**\n\nMeasurement Unit: Milliseconds (ms)\n\nRefers to the moment in a webpage's loading process when the DOM is completely parsed. And all deferred scripts have \ndownloaded and executed. It doesn't wait for resources.\n\n[more details](https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event)\n\n### FCP\n\n**First Contentful Paint**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time it takes for first bit of any actual content on a page to become visible on the screen. \nThis includes text, images, background images, SVG elements, and non-white canvas elements.\n\n[more details](https://web.dev/articles/fcp)\n\n### FID\n\n**First Input Delay**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time it takes for the browser to respond to a user's first interaction. This interaction can \ninclude clicks, hovers, touches, and other user events.\n\n[more details](https://web.dev/articles/fid)\n\n### FP\n\n**First Paint**\n\nMeasurement Unit: Milliseconds (ms)\n\nMarks the first time the browser renders anything visually different from the default background color of the body.\n\n### INP\n\n**Interaction to Next Paint**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time it takes for the browser to paint the next frame after a user interaction. \n\n[more details](https://web.dev/articles/inp)\n\n### L\n\n**On Load**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time when the entire page and its resources are fully loaded. \nIt includes all dependent resources: stylesheets, scripts, iframes, and images.\n\n[more details](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event)\n\n### LCP\n\n**Largest Contentful Paint**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time when the largest content block is rendered in the user viewport. The content may include images, \nbackground images, SVG, video, and text.\n\n[more details](https://web.dev/articles/lcp)\n\n### SI\n\n**Speed Index**\n\nMeasurement Unit: Score (lower is better)\n\nMeasures how swiftly the contents of a page are visually populated. Technically, in a graph, it is represented \nby the area above the curve, which will approach 0 as the page loads faster.\n\n[more details](https://developer.mozilla.org/en-US/docs/Glossary/Speed_index)\n\n### TBT\n\n**Total Blocking Time**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time between [FCP](#FCP) and [TTI](#TTI) when the main thread was blocked for long enough to prevent input responsiveness. \nMore specifically, it's the sum of the blocking time for each long task (\u003e50 ms). For web frameworks, this time is \nusually consumed by virtual DOM renders and hydration.\n\n[more details](https://web.dev/articles/tbt)\n\n### TTI\n\n**Time to Interactive**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures the time when than at least for 5 seconds where weren't long tasks (\u003e50ms) and\nno more than two in-flight network GET requests.\n\n[more details](https://web.dev/articles/tti)\n\n### TTFB\n\n**Time To First Byte**\n\nMeasurement Unit: Milliseconds (ms)\n\nMeasures when the first byte of data from the web server reaches the browser.\n\n[more details](https://web.dev/articles/ttfb)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanilqa%2Fweb-performance-handbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanilqa%2Fweb-performance-handbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanilqa%2Fweb-performance-handbook/lists"}