{"id":22535032,"url":"https://github.com/flowforfrank/performance-checklist","last_synced_at":"2026-01-07T22:02:41.096Z","repository":{"id":48412405,"uuid":"296890219","full_name":"flowforfrank/performance-checklist","owner":"flowforfrank","description":"📈 A comprehensive list of performance optimization techniques to improve your site's performance","archived":false,"fork":false,"pushed_at":"2024-08-03T19:15:01.000Z","size":3330,"stargazers_count":38,"open_issues_count":0,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-02T07:12:29.286Z","etag":null,"topics":["checklist","css-optimization","font-optimization","html-optimization","image-optimization","javascript-optimization","performance","performance-optimization","resources","server-optimization","tools","web-vitals","webtips"],"latest_commit_sha":null,"homepage":"https://webtips.dev","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flowforfrank.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"custom":["https://www.buymeacoffee.com/webtips"]}},"created_at":"2020-09-19T14:48:12.000Z","updated_at":"2024-11-27T14:03:24.000Z","dependencies_parsed_at":"2022-08-24T02:50:12.951Z","dependency_job_id":null,"html_url":"https://github.com/flowforfrank/performance-checklist","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowforfrank%2Fperformance-checklist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowforfrank%2Fperformance-checklist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowforfrank%2Fperformance-checklist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flowforfrank%2Fperformance-checklist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flowforfrank","download_url":"https://codeload.github.com/flowforfrank/performance-checklist/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245978279,"owners_count":20703678,"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":["checklist","css-optimization","font-optimization","html-optimization","image-optimization","javascript-optimization","performance","performance-optimization","resources","server-optimization","tools","web-vitals","webtips"],"created_at":"2024-12-07T10:06:18.386Z","updated_at":"2026-01-07T22:02:41.003Z","avatar_url":"https://github.com/flowforfrank.png","language":null,"readme":"\u003ch1 align=\"center\"\u003e\n    \u003cimg src=\"assets/performance-checklist.png\" alt=\"Performance Checklist\" /\u003e\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003e📈 The Performance Checklist is a comprehensive list of performance optimization techniques to improve your site's performance, and with it, its user experience. 🆙\n\u003cbr /\u003e\n\u003ci\u003e“Premature optimization is the root of all evil” - Donald Knuth\u003c/i\u003e\n\u003c/h4\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://webtips.dev\"\u003e\u003cimg src=\"https://img.shields.io/badge/webtips.dev-FCC700.svg?labelColor=221F22\u0026logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAWCAYAAABtwKSvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAN4SURBVHgBzVdLUhRBEH3VPaMS4QJPIDdAlmgQwgnQE6An8AiGJ1BvACdwOAFtGILhQuEENDdgYcinP2VW9TSTmZUFLsnNTGdnvcrPy6xq1x3h1AMrYNL3WHvwAse4p9IcYdMBB1znPI4L70ynn+Eei+tl8oP0wFnhe5wlxkiN75N4yz+qzIQcr+jvO64vCjy1QKzylo/wxK3h3LJvf+ALbfJqfKa1u+U63lq2F0dYmQKnwr8WW9ON6J8QV2I1RCSkR1U0Fs18hmY9NrWq+btw9i57onTWdmpg+9L2w6LZ5DH1zNI6anJeZNYXNs1cgZdaVxq6IKGKVIpl6R2Wr79nElViW6sKl+oijEsw6sCOYlilSmls6g+iY5sGsJ1tI9NRXEZv2ZPT/rdMSEyS9sHjJPzGYGgUf0UqIpjuYcYJCrz5lr5zmYpZ2TarOMdu/6ikGi3gh74fgnFG3zhdykzJo5SyOqGZgUzwpNfZ5kPiLmxKxqo2cd3gfwxmcpkGQy9EZh1zjsb5yW22uplpbc2f9dDQ1QoH4C3vksqME2+ozBbOOUB0mPH1+if9Z7OdKPSJOxhtf7FxLilWU/AfODYfGgk2+dEBezfY9G7EDn1rNH+12HYudIImfXPD11ZmuiGA3mNf6C7xGgsP+NlSldeYcVsxNBR28KNz0n7Ebh8Z/eIXLCn4ponhfM7zUofMxXGuNhxtdDPTZvuh8uD4bGgkA6HDLOBbVLOaP9gnwZRXxklLfaKbeaTAdJ3s5fkUG5vW7HCMcmnA1ZUMjW0Minrkf++EfcS2JmE4LJNgkuxhGK/JyewXNkQJSbULvHHSuWq86kyvsKuwd4xBUfG1Gtu4mVT8KlVIP1XfEB1oh49MU/NPAxrfu9ycwN6rS+BNI1tUU9iRkuN/XfmArc8iXW0RDIy+4QC6r+JI51RTmzXKPkkWt3c4nzxXg4IlI3OoVvxRBGP0gZC+ZeCYZ9tlP+KqOCiYtJCVFFheBjIoDd1Cav0BqSsjs6EWW9dxahzTPml4knlwlWXvDfuk8kys6VsYVrP/XRwkniHGhl0GxxvnmUWxqKbK6yEzimZJkCSYXDasxeOGya3boNgoFtVMio3vnEFNCt5iyQSGc80h9ijKbb54smFXJghR5HPBbtm3UDVSjb5AZ/yOlUtUkNDH3SElmA0AuuWb1foHkNJ6z8TJflAAAAAASUVORK5CYII=\" alt=\"Learn more about JavaScript and web development\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://twitter.com/flowforfrank\"\u003e\u003cimg src=\"https://img.shields.io/badge/Twitter-15202B.svg?logo=Twitter\" alt=\"Follow on Twitter\"/\u003e\u003c/a\u003e\n    \u003ca href=\"https://medium.com/@ferencalmasi\"\u003e\u003cimg src=\"https://img.shields.io/badge/Medium-000.svg?logo=medium\" alt=\"Follow on Medium\"/\u003e\u003c/a\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://www.buymeacoffee.com/webtips\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/default-orange.png\" alt=\"Support on Buy Me A Coffee\" width=\"150px\"\u003e\u003c/a\u003e\n    \u003cbr /\u003e• • •\u003cbr /\u003e\n    \u003ca href=\"https://github.com/flowforfrank/seo-checklist\" alt=\"Check out the SEO checklist\"\u003e🕵️ SEO Checklist\u003c/a\u003e\n\u003c/p\u003e\n\n## 🗃️ Table of Contents\n\n1. **🛠️ [Tools](#%EF%B8%8F-tools)**  \n    1.1. [Built-in Tools](#built-in-tools)\n    - 1.1.1. [Lighthouse](#%EF%B8%8F-lighthouse)\n    - 1.1.2. [Network Tab](#%EF%B8%8F-network-tab)\n    - 1.1.3. [Performance Tab](#%EF%B8%8F-performance-tab)\n    - 1.1.4. [Memory Tab](#%EF%B8%8F-memory-tab)\n    - 1.1.5. [Layers Panel](#%EF%B8%8F-layers-panel)\n    - 1.1.6. [Coverage Drawer](#%EF%B8%8F-coverage-drawer)\n    - 1.1.7. [Issues Drawer](#%EF%B8%8F-issues-drawer)\n    - 1.1.8. [Rendering Drawer](#%EF%B8%8F-rendering-drawer)\n    - 1.1.9. [Request Blocking Drawer](#%EF%B8%8F-request-blocking-drawer)\n\n    1.2. [Online Tools](#online-tools)\n    - 1.2.1. [Webhint](#-webhint)  \n    - 1.2.2. [PageSpeed Insights](#-pagespeed-insights)  \n    - 1.2.3. [Web.dev](#-webdev)\n    - 1.2.4. [Bundlephobia](#-bundlephobia)\n    - 1.2.5. [GTMetrix](#-gtmetrix)\n    - 1.2.6. [WebPageTest](#-webpagetest)\n    - 1.2.7. [Pingdom Website Speed Test](#-pingdom-website-speed-test)\n    - 1.2.8. [Varvy](#-varvy)\n    - 1.2.9. [DebugBear](#-debugbear)\n\n    1.3. [Chrome Extensions](#chrome-extensions)\n    - 1.3.1. [React Developer Tools](#-react-developer-tools)\n    - 1.3.2. [Web Vitals](#-web-vitals)\n2. **🏗️ [HTML Optimization](#%EF%B8%8F-html-optimization)**  \n    2.1. [Write Valid and Readable DOM](#%EF%B8%8F-write-valid-and-readable-dom)  \n    2.2. [Don't Use Inline Styles and Scripts](#%EF%B8%8F-dont-use-inline-styles-and-scripts)  \n    2.3. [Inline Critical CSS](#%EF%B8%8F-inline-critical-css)  \n    2.4. [Place Script Tags at the Bottom](#%EF%B8%8F-place-script-tags-at-the-bottom)  \n    2.5. [Avoid Using Plugins](#%EF%B8%8F-avoid-using-plugins)  \n    2.6. [Reduce the Number of DOM Elements](#%EF%B8%8F-reduce-the-number-of-dom-elements)  \n    2.7. [Compress HTML](#%EF%B8%8F-compress-html)\n3. **🖍️ [CSS Optimization](#%EF%B8%8F-css-optimization)**  \n    3.1. [Reconsider if you really need a framework](#%EF%B8%8F-reconsider-if-you-really-need-a-framework)  \n    3.2. [Prefer Using a CSS Methodology](#%EF%B8%8F-prefer-using-a-css-methodology)  \n    3.3. [Use Markup Instead of CSS](#%EF%B8%8F-use-markup-instead-of-css)  \n    3.4. [Use Shorthand Properties](#%EF%B8%8F-use-shorthand-properties)  \n    3.5. [Reduce Redundancy](#%EF%B8%8F-reduce-redundancy)  \n    3.6. [Avoid Complex Selectors](#%EF%B8%8F-avoid-complex-selectors)  \n    3.7. [Use Mobile First](#%EF%B8%8F-use-mobile-first)  \n    3.8. [Compress CSS](#%EF%B8%8F-compress-css)  \n4. **👨‍💻 [JavaScript Optimization](#-javascript-optimization)**  \n    4.1. [Defer JavaScript Files](#%EF%B8%8F-defer-javascript-files)  \n    4.2. [Update Libraries](#%EF%B8%8F-update-libraries)  \n    4.3. [Use Web Workers](#%EF%B8%8F-use-web-workers)  \n    4.4. [Eliminate Long-running Tasks](#%EF%B8%8F-eliminate-long-running-tasks)  \n    4.5. [Use the Coverage Drawer](#%EF%B8%8F-use-the-coverage-drawer)  \n    4.6. [Avoid Micro-Optimization](#%EF%B8%8F-avoid-micro-optimization)  \n    4.7. [Compress JavaScript](#%EF%B8%8F-compress-javascript)\n5. **🖼️ [Image Optimization](#%EF%B8%8F-image-optimization)**  \n    5.1. [Replace Images](#%EF%B8%8F-replace-images)  \n    5.2. [Use Vector Images](#%EF%B8%8F-use-vector-images)  \n    5.3. [Minify SVG Markup](#%EF%B8%8F-minify-svg-markup)  \n    5.4. [Choose the Right Raster Format](#%EF%B8%8F-choose-the-right-raster-format)  \n    5.5. [Scale Your Images](#%EF%B8%8F-scale-your-images)  \n    5.6. [Lazy Load Images](#%EF%B8%8F-lazy-load-images)  \n    5.7. [Compress Images](#%EF%B8%8F-compress-images)\n6. **🗛 [Font Optimization](#-font-optimization)**  \n    6.1. [Minimize Number of Font Use](#%EF%B8%8F-minimize-number-of-font-use)  \n    6.2. [Subset Fonts](#%EF%B8%8F-subset-fonts)  \n    6.3. [Implement Custom Font-loading Strategies](#%EF%B8%8F-implement-custom-font-loading-strategies)  \n    6.4. [Cache Fonts](#%EF%B8%8F-cache-fonts)  \n    6.5. [Compress Fonts](#%EF%B8%8F-compress-fonts)\n7. **🗄️ [Server Optimization](#%EF%B8%8F-server-optimization)**  \n    7.1. [Configure Compression](#%EF%B8%8F-configure-compression)  \n    7.2. [Minimize the Number of HTTP Requests](#%EF%B8%8F-minimize-the-number-of-http-requests)  \n    7.3. [Use a CDN](#%EF%B8%8F-use-a-cdn)  \n    7.4. [Use a Cache-Control Header](#%EF%B8%8F-use-a-cache-control-header)  \n8. **🇼 [Core Web Vitals](#-core-web-vitals)**  \n    8.1. [Largest Contentful Paint](#%EF%B8%8F-largest-contentful-paint)  \n    8.2. [First Input Delay](#%EF%B8%8F-first-input-delay)  \n    8.3. [Cumulative Layout Shift](#%EF%B8%8F-cumulative-layout-shift)  \n    8.4. [How to Measure Core Web Vitals](#%EF%B8%8F-how-to-measure-core-web-vitals)\n9. **⚛️ [Frameworks](#%EF%B8%8F-frameworks)**  \n    9.1. [React Optimization Techniques](#react-optimization-techniques)\n    - 9.1.1. [Use Production Build](#%EF%B8%8F-use-production-build)\n    - 9.1.2. [Profile Components](#%EF%B8%8F-profile-components)\n    - 9.1.3. [Virtualize Long Lists](#%EF%B8%8F-virtualize-long-lists)\n    - 9.1.4. [Pre-render Routes](#%EF%B8%8F-pre-render-routes)\n10. **📚 [Other Resources](#-other-resources)**\n\n## 🛠️ Tools\nℹ️ *If you can't measure it, you can't improve it - Before you make any changes, the first step is to measure performance. This way, you will have a baseline and you can make comparisons later on. Never make performance optimizations, without first creating a baseline.*\n\n\u003e 🆓 The tools listed below are free to use\n\n### Built-in Tools\nℹ️ *Built-in tools will be your first station in improving performance. If you don't find a certain tab in DevTools, you can open the tools pane by hitting `ctrl` + `shift` + `p`.*\n\n\u003e #### 🛠️ [Lighthouse](https://developers.google.com/web/tools/lighthouse)\n\u003e Lighthouse will be one of your best friends for performance audits. It is built into Chrome's DevTools, and can create audits for performance, accessibility, progressive web apps, SEO and more. If you don't happen to find the audit you are looking for your specific use case, it also lets you create your own plugins.\n\u003e\n\u003e The generated audit also contain further resources for explanation of failed audits, and steps on how to resolve them.\n\u003e\n\u003e 📖 [GitHub - Plugin Handbook](https://github.com/GoogleChrome/lighthouse/blob/master/docs/plugins.md)\n----------\n\n\u003e #### 🛠️ Network Tab\n\u003e Use the *Network* tab to identify issues related to network requests. These can be things like:\n\u003e\n\u003e - Long server response times\n\u003e - Verify resources are compressed\n\u003e - Identifying large resource sizes\n\u003e - Making sure resources are downloaded or uploaded correctly\n\u003e\n\u003e You can also use the Network tab to simulate slow network connection, or even simulate offline state.\n\u003e\n\u003e 📖 [Chrome DevTools - Inspect Network Activity In Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/network)\n\n![Enable throttling](assets/enable-throttling.png)\n\n----------\n\n\u003e #### 🛠️ Performance Tab\n\u003e The performance tab is where you can identify most of the issues related to performance, such as:\n\u003e\n\u003e - FPS drops\n\u003e - High CPU usage\n\u003e - Memory leaks\n\u003e - Long running JavaScript tasks\n\u003e - Forced reflows\n\u003e\n\u003e The performance tab also shows you the time frame of different key events and core web vitals, such as **First Paint**, **First Contentful Paint**, **Largest Contentful Paint**, **DOMContentLoaded** event, or the **Onload** event.\n\u003e\n\u003e 📖 [Chrome DevTools - Get Started With Analyzing Runtime Performance](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance)  \n\u003e 📖 [Chrome DevTools - Performance Analysis Reference](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/reference)\n----------\n\n\u003e #### 🛠️ Memory Tab\n\u003e If you suspect your application has memory leaks, this is where you can:\n\u003e\n\u003e - Create heap snapshots\n\u003e - Record memory usage over time\n\u003e\n\u003e To identify the root cause of the problem. If you experience one of the followings, it is likely you have memory leaks.\n\u003e\n\u003e - Slow load times\n\u003e - Sluggish performance\n\u003e - The performance of the application degrades over time\n\u003e - High memory usage\n\u003e\n\u003e 📖 [Chrome DevTools - How to Record Heap Snapshots](https://developers.google.com/web/tools/chrome-devtools/memory-problems/heap-snapshots)  \n\u003e 📖 [Chrome DevTools - Fix Memory Problems](https://developers.google.com/web/tools/chrome-devtools/memory-problems)\n----------\n\n\u003e #### 🛠️ Layers Panel\n\u003e The *Layers* panel can help you visualize different layers on your website and identify, if:\n\u003e\n\u003e - You have too many layers\n\u003e - You can prevent repaint of large areas by promoting them to new composite layers\n\u003e\n\u003e You also get to know the reason for having elements on different layers.\n\u003e\n\u003e 📖 [LogRocket - Eliminate content repaints with the new Layers panel in Chrome](https://blog.logrocket.com/eliminate-content-repaints-with-the-new-layers-panel-in-chrome-e2c306d4d752/)\n\n![The visuals of the Layers Panel](assets/layers-panel.png)\n\n----------\n\n\u003e #### 🛠️ Coverage Drawer\n\u003e The *Coverage* drawer in Chrome DevTools can help you find unused JavaScript and CSS. Removing them can speed up your page load and reduce the number of bytes transferred.\n\u003e\n\u003e ❗ When you are doing analysis, make sure you interact with the page before deeming a piece of code \"unused\".\n\u003e\n\u003e Anything that is shown in red inside the Coverage drawer can be potentially deferred to speed up initial page load.\n\u003e\n\u003e 📖 [Find Unused JavaScript And CSS Code With The Coverage Tab In Chrome DevTools](https://developers.google.com/web/tools/chrome-devtools/coverage)\n----------\n\n\u003e #### 🛠️ Issues Drawer\n\u003e The *Issues* drawer aims to combine common issues in your Console tab, to de-clutter it. It aggregates similar issues and provides resources with actions on how to resolve them.\n----------\n\n\u003e #### 🛠️ Rendering Drawer\n\u003e The *Rendering* drawer lets you identify issues related to rendering. With the rendering drawer, you have the ability to:\n\u003e\n\u003e - Highlight areas of the page that needs to be repainted\n\u003e - Highlight areas of the page that were shifted\n\u003e - Highlight ad frames\n\u003e - Show layer borders\n\u003e - Show FPS\n\u003e - Show scrolling performance issues\n\u003e - Show borders around hit-test regions\n\u003e\n\u003e You also have the ability to emulate different types of media type — such as `print` or `screen` — and different vision deficiencies:\n\u003e\n\u003e - Blurred vision\n\u003e - Protanopia\n\u003e - Deuteranopia\n\u003e - Tritanopia\n\u003e - Achromatopsia\n----------\n\n\u003e #### 🛠️ Request Blocking Drawer\n\u003e With the *Request Blocking* drawer, you have the ability to block certain requests using text patterns, to simulate issues related to network requests.\n----------\n\n### Online Tools\nℹ️ *Online tools give you additional help to address performance issues.*\n\n\u003e #### 📈 [Webhint](https://webhint.io/)\n\u003e Webhint provides you with deep details not only on performance but other aspects as well, such as common pitfalls or security issues.\n\u003e\n\u003e - You can run your audits through its official website\n\u003e - You can use it in [VS Code](https://marketplace.visualstudio.com/items?itemName=webhint.vscode-webhint)\n\u003e - You can use it as a [browser extension](https://chrome.google.com/webstore/detail/webhint/gccemnpihkbgkdmoogenkbkckppadcag)\n\u003e - You can even integrate it into your release process through [CLI](https://webhint.io/docs/user-guide/)\n\u003e\n\u003e It also gives you the ability to write and enforce your own set of rules.\n----------\n\n\u003e #### 📈 [PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/)\n\u003e PageSpeed Insights is the browser version of Lighthouse. It can generate audits for you for both Mobile and Desktop with [Core Web Vitals](#core-web-vitals) being reported at the very top.\n----------\n\n\u003e #### 📈 [Web.dev](https://web.dev/measure/)\n\u003e Web.dev, generates a similar report to Lighthouse. Identify performance, accessibility, best practices, or SEO problems with your site. See issues with the highest impact on the top of your report.\n\n![Report generated on Web.dev](assets/webdev-report.png)\n\n----------\n\n\u003e #### 📈 [Bundlephobia](https://bundlephobia.com/)\n\u003e Bundlephobia lets you find out the real cost of adding npm packages to your bundle, by analyzing the bundle size of each package. You can generate a report by dropping your `package.json` file into the tool. This will generate a report for each package used, how much it adds to your load time, and what is the total cost of all packages combined.\n\n![A generated report from Bundlephobia](assets/bundlephobia.png)\n\n----------\n\n\u003e #### 📈 [GTMetrix](https://webhint.io/)\n\u003e GTmetrix helps you discover performance issues and provides you with optimization opportunities. It generates a report for you with the most impactful issues at the top.\n\n![Report generated by GTMetrix](assets/gtmetrix.png)\n\n----------\n\n\u003e #### 📈 [WebPageTest](https://www.webpagetest.org/)\n\u003e WebPageTest categorizes your site from *A* to *F* in the following metrics:\n\u003e - Security score\n\u003e - First Byte Time\n\u003e - Keep-alive Enabled\n\u003e - Compress Transfer\n\u003e - Compress Images\n\u003e - Cache static content\n\u003e - Effective use of CDN\n----------\n\n\u003e #### 📈 [Pingdom Website Speed Test](https://tools.pingdom.com/)\n\u003e The Pingdom Website Speed Test lets you insert your URL for inspection. It analyzes page load time, gives you hint on how to improve your page's performance, and let's you find bottlenecks by giving you a detailed report.\n----------\n\n\u003e #### 📈 [Varvy](https://varvy.com/pagespeed/)\n\u003e The Varvy SEO tools are now unavailable due to their legacy nature. We're hoping to get them back sometime in the future.\n----------\n\n\u003e #### 📈 [DebugBear](https://www.debugbear.com/test/website-speed)\n\u003e DebugBear analyzes your website performance and generates a detailed report:\n\u003e - Request Waterfall\n\u003e - Automatic page speed recommendations\n\u003e - Real user Core Web Vitals data from Google\n\u003e - Lighthouse report\n----------\n\n### Chrome Extensions\nℹ️ *Chrome extensions can help you enhance your workflow by providing some additional debugging tools on top of Chrome DevTools*\n\n\u003e #### 💻 [React Developer Tools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)\n\u003e This Chrome extension is an essential tool for any React developer. It adds two additional tabs to your Chrome DevTools:\n\u003e\n\u003e - **⚛️ Components:** Shows you the rendered components tree, with information on each component's props and state.\n\u003e - **⚛️ Profiler:** The Profile tab lets you record performance information for React components to easily identify unnecessary renders that may cause slow performance.\n----------\n\n\u003e #### 💻 [Web Vitals](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma)\n\u003e This Chrome extension measures Core Web Vitals, providing instant feedback on loading, interactivity and layout shift metrics. It reports the same metrics you find in Lighthouse, Page Speed Insights, or Search Console.\n----------\n\n## 🏗️ HTML Optimization\nℹ️ *Optimizing HTML is often overlooked. However, it is a core part of any web application, therefore you should take good care of it, just as you do for other assets.*\n\n\u003e #### ☑️ Write Valid and Readable DOM\n\u003e This include steps that not only helps in terms of performance, but also creates a more dev friendly environment:\n\u003e - **Write in all lowercase:** Every tag should be lowercase, so please don't use any uppercase in HTML tags.\n\u003e - **Indentation is key to readability:** Use it to avoid a flat, cluttered document. Enhancing readability also means it reduces development time.\n\u003e - **Close self-closing tags:** This was once mandatory. With HTML5 it’s optional and purely up to the developer. Either use it on all tags or don’t use it at all. The key here is being consistent.\n\u003e - **Avoid overusing comments:** Unless you have a build system in place or you are using a template engine, these can add up and increase the weight of your HTML file.\n\u003e - **Organize DOM:** Always consider if you need that extra div or extra element. Try to create only the absolute necessary ones and divide only large parts of your page with not `div`s, but semantic HTML elements.\n----------\n\n\u003e #### ☑️ Don't Use Inline Styles and Scripts\n\u003e Always use external stylesheets. Also, try to avoid using `import` statements in your CSS files. They produce extra server requests. Also make sure you bundle files together to reduce the number of network requests. If bundle size is a problem for you, you can split them up into 2-4 smaller chunks and take advantage of [domain sharding](https://developer.mozilla.org/en-US/docs/Glossary/Domain_sharding)\n\u003e\n\u003e 📖 [MDN Web Docs - Domain Sharding](https://developer.mozilla.org/en-US/docs/Glossary/Domain_sharding)\n----------\n\n\u003e #### ☑️ Inline Critical CSS\n\u003e Critical CSS refers to the minimum set of CSS that is required to render the top of your page, a user sees first when landing on your site.\n\u003e Consider inlining critical CSS. By doing so, users will get to see the first portion of your page rendered more quickly.\n\u003e *(Critical CSS is also referred to as “above the fold” CSS)*\n\n![Critical CSS](assets/critical-css.png)\n\n----------\n\n\u003e #### ☑️ Place Script Tags at the Bottom\n\u003e This way, all the content of the body will get loaded in, before you load the content of the script tag. In return, you can trick your users into believing that your page is loading faster than it actually is.\n\u003e\n\u003eYou can also add a `defer` tag to your script tags to make sure the HTML gets loaded first. To get a good grasp on what is the difference between a normal, and an `async` vs `defer` script tag, take a look at the following example:\n\n![The difference between async and defer script tags](assets/async-vs-defer.png)\n\n----------\n\n\u003e #### ☑️ Avoid Using Plugins\n\u003e Search engines can't index plugin content, and many devices restrict plugins or don't support them. Therefore it's better to leave them out and cut down on some precious bytes.\n\u003e\n\u003e Elements such as `embed`, `object` or `applet` are checked and if their MIME type matches any of the following:\n\u003e - `application/x-java-applet`\n\u003e - `application/x-java-bean`\n\u003e - `application/x-shockwave-flash`\n\u003e - `application/x-silverlight`\n\u003e - `application/x-silverlight-2`\n\u003e \n\u003e Then it will be flagged as a plugin.\n\u003e\n\u003e 📖 [Web.dev - Document avoids plugins](https://web.dev/plugins/)\n----------\n\n\u003e #### ☑️ Reduce the Number of DOM Elements\n\u003e Monitor the number of DOM elements present on your page. Make sure you don't:\n\u003e\n\u003e - Have more than 1500 DOM nodes\n\u003e - Have a depth greater than 32 nodes\n\u003e - Have a parent node with more than 60 children\n\u003e \n\u003e Having excessive amount of DOM nodes on your page can affect performance in a number of ways:\n\u003e\n\u003e - Slow down initial page load time\n\u003e - Slow down rendering performance\n\u003e - Can cause heavy memory usage\n\u003e\n\u003e 📖 [Web.dev - Avoid an excessive DOM size](https://web.dev/dom-size/)\n\n```javascript\n// The fastest way to count the number of DOM nodes on your site\n// is using the all (*) query selector\ndocument.querySelectorAll('*').length;\n```\n\n----------\n\n\u003e #### ☑️ Compress HTML\n\u003e Compress your HTML to further reduce file sizes, after you've [validated them](https://validator.w3.org/). You can use third party libraries, build tools, bundlers or online applications for this.\n\u003e\n\u003e 🛠️ [W3C - Markup Validation Service](https://validator.w3.org/)  \n\u003e 🛠️ [NPMJS - HTMLMinifier](https://www.npmjs.com/package/html-minifier)  \n\u003e 🛠️ [Webpack](https://webpack.js.org/)  \n\u003e 🛠️ [HTML Minifier](https://www.willpeavy.com/tools/minifier/)\n----------\n\n## 🖍️ CSS Optimization\nℹ️ *CSS may seem like an unusual choice for performance optimization, however taking good care of your CSS assets can come a long way, as little repetitions do add up.*\n\n\u003e #### ☑️ Reconsider if you really need a framework\n\u003e There are now many lightweight alternatives to robust frameworks. Usually, you won’t be using every selector from a framework, so your bundle will contain dead code. you can identify unused CSS rules using code coverage in DevTools.\n\u003e\n\n![Coverage Tab in Chrome's DevTools](assets/coverage-tab.png)\n\n----------\n\n\u003e #### ☑️ Prefer Using a CSS Methodology\n\u003e CSS methodologies helps you to create consistency and modularity across your CSS files, which can lead to leaner file sizes. Some popular CSS methodologies are:\n\u003e\n\u003e 📖 [BEM - *(Block, Element, Modifier)*](http://getbem.com/)  \n\u003e 📖 [ITCSS - *(Inverted Triangle CSS)*](https://itcss.io/)  \n\u003e 📖 [OOCSS - *(Object-oriented CSS)*](https://github.com/stubbornella/oocss/wiki)\n----------\n\n\u003e #### ☑️ Use Markup Instead of CSS\n\u003e You can reduce the size of your CSS bundles by simply using correct HTML elements.\n\n```css\n/* 🔴 Instead of resetting styles */\nspan.heading {\n    display: block;\n    font-size: 1.2em;\n    margin-top: 1em;\n    margin-bottom: 1em; \n}\n\n/* ✅ Use a heading */\nh1 { ... }\n```\n----------\n\n\u003e #### ☑️ Use Shorthand Properties\n\u003e To further reduce the number of rules, always try to go with shorthand properties with `margins`, `paddings`, `borders`, or `backgrounds`.\n\u003e\n\u003e 📖 [MDN Web Docs - Shorthand properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties)\n\n![Using CSS Shorthand Properties](assets/shorthand-properties.gif)\n\n----------\n\n\u003e #### ☑️ Reduce Redundancy\n\u003e Sometimes it’s hard to spot redundancy, especially when repeating rules don’t follow the same order in both selectors. If your classes differ in just one or two rules, it’s better to outsource those rules and use them as an extra class.\n\n```html\n\u003c!-- 🔴 Instead of --\u003e\n\u003cstyle\u003e\n    .warning {\n        width: 100%;\n        height: 50px;\n        background: yellow;\n        border-radius: 5px;\n    }\n\n    .elevated-warning {\n        width: 100%;\n        height: 50px;\n        font-size: 150%;\n        background: yellow;\n        box-shadow: 1px 2px 5px #CCC;\n        border-radius: 5px;\n    }\n\u003c/style\u003e\n\n\u003cdiv class=\"warning\"\u003e⚠️\u003c/div\u003e\n\u003cdiv class=\"elevated-warning\"\u003e🚨\u003c/div\u003e\n```\n\n```html\n\u003c!-- ✅ Do --\u003e\n\u003cstyle\u003e\n    .warning {\n        width: 100%;\n        height: 50px;\n        background: yellow;\n        border-radius: 5px;\n    }\n\n    .warning--elevated {\n        font-size: 150%;\n        box-shadow: 1px 2px 5px #CCC;\n    }\n\u003c/style\u003e\n\n\u003cdiv class=\"warning\"\u003e⚠️\u003c/div\u003e\n\u003cdiv class=\"warning warning--elevated\"\u003e🚨\u003c/div\u003e\n```\n\n----------\n\n\u003e #### ☑️ Avoid Complex Selectors\n\u003e There are two major problems with using complex selectors. First, your increased specificity will not only make it harder to later rewrite existing rules, but also increase the time it takes for the browser to match selectors.\n----------\n\n\u003e #### ☑️ Use Mobile First\n\u003e When you are dealing with media queries, always use mobile-first. This will ensure that you mostly add extra rules to cater for large screen devices, rather than rewriting existing CSS rules. This can reduce the number of rules you end up with.\n\u003e\n\u003e 📖 [MDN Web Docs - Mobile first](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/Mobile_first)\n\n```css\n/* 🔴 Non mobile-first media query, everything below 600px will get the below styles */\n@media (max-width: 600px) {\n    /* your CSS rules */\n}\n\n/* ✅ Mobile-first media query, everything above 600px will get the below styles */\n@media (min-width: 600px) {\n    /* your CSS rules */\n}\n```\n\n----------\n\n\u003e #### ☑️ Compress CSS\n\u003e Compress your bundles to reduce their size. Compression removes comments and white spaces, so your bundles require less bandwidth to fetch. Another great way to further reduce the size of your CSS  — and markup— is obfuscating class names. To achieve this, depending on your project setup you can:\n\u003e\n\u003e - **Webpack**: use the [`css-loader`](https://github.com/webpack-contrib/css-loader) module\n\u003e - **Gulp**: use the [`gulp-minify-cssnames`](https://www.npmjs.com/package/gulp-minify-cssnames) plugin\n\u003e - **Own implementation:** if you don't have a dedicated package for your project, you can also [use your own implementation](https://www.webtips.dev/how-i-reduced-my-css-bundle-size-by-more-than-20-percent).\n\n![Minified CSS Classnames](assets/minify-class-names.png)\n\n----------\n\n## 👨‍💻 JavaScript Optimization\nℹ️ *Bad JavaScript implementations are usually the main cause of sluggish, slow responding interfaces. When you write your JavaScript files, keep in mind the following points.*\n\n\u003e #### ☑️ Defer JavaScript Files\n\u003e As described in the [HTML section](#place-script-tags-at-the-bottom), try to defer your JavaScript assets to avoid render blocking the page. You can achieve this by moving your resources to the bottom of the page and placing them before the closing of your `body` tag. You can also defer non critical resources by using the `async` or `defer` attributes.\n\n```html\n\u003c!-- 🔴Instead of --\u003e\n    ...\n    \u003cscript src=\"app.js\"\u003e\u003c/script\u003e\n\u003c/head\u003e\n\n\u003c!-- ✅ Do --\u003e\n    ...\n    \u003cscript src=\"app.js\"\u003e\u003c/script\u003e\n\n    \u003c!-- Also try to make use of `async` /` defer` tags --\u003e\n    \u003cscript src=\"app.js\" async\u003e\u003c/script\u003e\n    \u003cscript src=\"app.js\" defer\u003e\u003c/script\u003e\n\u003c/body\u003e\n```\n\n----------\n\n\u003e #### ☑️ Update Libraries\n\u003e Make sure your dependencies are all updated. This not only helps improve the security on your page by patching common security vulnerabilities for packages, but may also improve the size of your bundles. To know what is the real cost of your `node_modules` for your project setup, you can use Bundlephobia.\n\u003e\n\u003e 🛠️ [Bundlephobia](https://bundlephobia.com/)\n----------\n\n\u003e #### ☑️ Use Web Workers\n\u003e Use web workers for complex calculations. JavaScript runs on the main thread in the browser. This means that long-running tasks can freeze up the page and block user interaction. If you have heavy computational work to do, do it inside a web worker. They run on a separate thread and are non-blocking.\n\u003e\n\u003e *Note: You don’t have access to the DOM inside a web worker.*\n----------\n\n\u003e #### ☑️ Eliminate Long-running Tasks\n\u003e Long-running JavaScript tasks are usually behind input delays. You can identify them through profiling your page with DevTools' Performance Tab. Anything shown in the stack with a red triangle is a long-running task that could be refactored to take less time to process.\n\u003e\n\u003e 📖 [MDN Web Docs - Intensive JavaScript](https://developer.mozilla.org/en-US/docs/Tools/Performance/Scenarios/Intensive_JavaScript)\n\n![Long-running JavaScript Tasks](assets/long-running-javascript-task.png)\n\n----------\n\n\u003e #### ☑️ Use the Coverage Drawer\n\u003e The coverage tab can be a powerful tool to see which code you truly need during page load. Anything that you see in red on the image below, is not executed right away. This means you can potentially defer and request it after loading has finished.\n\n![JavaScript Code Coverage](assets/javascript-code-coverage.png)\n\n----------\n\n\u003e #### ☑️ Avoid Micro-Optimization\n\u003e It may sound tempting to optimize every bit of your code, but you’ll only save a fraction of a millisecond by doing so, and you may end up sacrificing readability and maintainability for performance. Only break this rule if you are making video games or computation-heavy applications, where every bit counts.\n----------\n\n\u003e #### ☑️ Compress JavaScript\n\u003e Just as for HTML and CSS, make sure you always minify, and also obfuscate your JavaScript code to add a little bit of security to your page. You should do this as part of your build process.\n\u003e\n\u003e 🛠️ [JavaScript Minifier](https://javascript-minifier.com/)  \n\u003e 🛠️ [JSCompress](https://jscompress.com/)  \n\u003e 🛠️ [Minify](https://www.minifier.org/)\n----------\n\n## 🖼️ Image Optimization\nℹ️ *Most of the time, images account for most transferred bytes, meaning you can gain the most on performance by optimizing them. To start doing so, you need to know where and what types of images you are using.*\n\n\u003e #### ☑️ Replace Images\n\u003e Some images can be removed and replaced by utilizing CSS effects. These include things like:\n\u003e\n\u003e - Drop shadows\n\u003e - Triangular shaped objects, arrows\n\u003e - Tooltips\n\u003e - Speech bubbles\n\u003e - Toggles and other more complex UI handlers\n\u003e\n\u003e If you need to display text on images, use web fonts instead of encoding them into the image itself. This helps reduce resource size.\n----------\n\n\u003e #### ☑️ Use Vector Images\n\u003e Whenever you’re using a combination of different geometric shapes in your images, prefer using vector instead of raster. Vector images are resolution- and scale-independent making them a good choice in a world with high resolution and different screen size devices. Note the difference between the two:\n\u003e\n\u003e 📖 [Shutterstock - Raster vs. Vector: What’s the Difference and When to Use Which](https://www.shutterstock.com/blog/raster-vs-vector-file-formats)\n\n![The difference between vector and raster images](assets/vector-vs-raster.png)\n\n----------\n\n\u003e #### ☑️ Minify SVG Markup\n\u003e The XML markup that makes up an SVG often contains unnecessary metadata added by applications that generate them. These can be safely removed to ensure you are only delivering the absolutely necessary pieces and nothing more.\n\u003e\n\u003e 📖 [CSS Tricks - Tools for Optimizing SVG](https://css-tricks.com/tools-for-optimizing-svg/)\n----------\n\n\u003e #### ☑️ Choose the Right Raster Format\n\u003e Picking the right raster image format is essential to get precious bytes saved. To choose which format is best for you, go over these questions:\n\u003e\n\u003e 1. *\"Do I need animations?\"*  👉 go with **GIF**\n\u003e 2. *\"Do I need transparency?* 👉 go with **PNG-8/24**\n\u003e 3. *\"Do I need to preserve fine details?\"* 👉 go with **PNG-8/24**, else go with **JPG**\n\u003e 4. *\"Do I have more than 256 colors in my palette?\"* 👉 go with **PNG-24**\n\u003e 5. Otherwise, go with **PNG-8**\n\n![How to choose the right raster format](assets/how-to-choose-raster-format.png)\n\n----------\n\n\u003e #### ☑️ Scale Your Images\n\u003e Resize your images and ensure that the display size is as close to the natural size of the image as possible. If you are displaying a `300x150px` image on your site, there’s no need for it to be `1500x750`.\n\u003e\n\u003e You can also use a `srcset` to display responsive images, and ensure that your images are as close to the device's display size as possible.\n\u003e\n\u003e 📖 [MDN web docs - Responsive images](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images)\n\n![Natural (intrinsic) vs display size of the image shown in DevTools](assets/natural-vs-display-size.png)\n\n```html\n\u003c!-- Use `srcset` with sizes to display different images based on screen size --\u003e\n\n\u003cimg srcset=\"small-nickcage.jpg 320w,\n             medium-nickcage.jpg 768w,\n             large-nickcage.jpg 1024w\"\n     sizes=\"(max-width: 320px) 280px,\n            (max-width: 768px) 720px,\n            1024px\"\n     src=\"large-nickcage.jpg\"\nalt=\"No need for introduction, you already know him\" /\u003e\n```\n\n----------\n\n\u003e #### ☑️ Lazy Load Images\n\u003e Many images are off-screen initially, so there’s no point in downloading every single one of them upfront. By lazy loading them, you can reduce initial page load and enhance performance. Especially on websites that are content-heavy, like image galleries or social networks based around image posts.\n\u003e\n\u003e You can set the `loading` attribute to `lazy` in HTML to natively lazy load images where the browser supports it. For older browsers, you can provide a fallback solution, such as using the `IntersectionObserver` API.\n\u003e\n\u003e 📖 [Webtips.dev - How to Lazy Load Images Natively](https://www.webtips.dev/how-to-lazy-load-images-natively)  \n\u003e 📖 [Webtips.dev - How to Lazy Load Images With Intersection Observer](https://www.webtips.dev/how-to-lazy-load-images-with-intersection-observer)\n\n```html\n\u003c!-- \n    Lazy-loading an image natively.\n    Whenever the image comes close to the viewport, a request will be made to fetch the image.\n---\u003e\n\u003cimg src=\"http://place-puppy.com/500x500\" loading=\"lazy\" /\u003e\n```\n\n```javascript\n// Make sure you provide fallback for browsers that do not support the `loading` attribute.\nif ('loading' in HTMLImageElement.prototype) { \n    // This means the browser supports lazy-loading natively, you are good to go\n} else {\n    // This means the browser does not support lazy-loading natively\n}\n```\n\n----------\n\n\u003e #### ☑️ Compress Images\n\u003e Just like SVGs, many raster images contain metadata like camera information or even geolocation. These can be safely removed.\n\u003e\n\u003e Apart from removing meta information, you can further reduce file size with lossy compression. Due to the way of how our eyes work, you can reduce resolution without noticing a difference.\n\u003e\n\u003e 🛠️ [TinyPNG](https://tinypng.com/)\n----------\n\n## 🗛 Font Optimization\nℹ️ *Just like for images, in order to know where you can make improvements, you need to first monitor your font usage, although the techniques mentioned here apply to all fonts.*\n\n\u003e #### ☑️ Minimize Number of Font Use\n\u003e The simplest and easiest to implement is minimizing the number of fonts used on a page and the number of variants used for each font family. This not only helps in terms of performance, but also creates a more consistent design, making way for better user experience.\n\u003e\n\u003e You can experiment with font load times on [Google Fonts](https://fonts.google.com/).\n\n![Font load time shown on Google Fonts](assets/font-load-time.png)\n\n----------\n\n\u003e #### ☑️ Subset Fonts\n\u003e Many fonts come with a wide range of glyphs that you will probably never use. If your site is made of only Latin characters, there’s no point in keeping Cyrillic glyphs in your font sets. These fonts can be subset and only include the required Unicode range to further reduce file size.\n\u003e\n\u003e 🛠️ [NPMJS - Glyphhanger](https://www.npmjs.com/package/glyphhanger)  \n\u003e 🛠️ [Transfonter](https://transfonter.org/)  \n\u003e 🛠️ [Font Subsetter](https://everythingfonts.com/subsetter)\n----------\n\n\u003e #### ☑️ Implement Custom Font-loading Strategies\n\u003e By default, font requests are put aside, until the render tree is constructed, meaning we have both DOM and CSSOM ready. This can result in delayed text rendering. By using `rel=\"preload\"`, you can tell the browser to treat the resource with high priority, so fonts can be requested early on.\n\u003e\n\u003e 📖 [CSS Tricks - A Comprehensive Guide to Font Loading Strategies](https://css-tricks.com/comprehensive-guide-font-loading-strategies/)  \n\u003e 📖 [Web.dev - Preload key requests](https://web.dev/uses-rel-preload/)\n\n```html\n\u003c!-- Make sure to also specify the type of resource with the `as` attribute --\u003e\n\u003clink rel=\"preload\" href=\"myCustomFont.woff2\" as=\"font\" /\u003e\n```\n----------\n\n\u003e #### ☑️ Cache Fonts\n\u003e Fonts are static resources. Most of the time, they rarely change, meaning you can provide a long `Cache-Control: max-age` directive to have them cached and avoid unnecessary network requests.\n----------\n\n\u003e #### ☑️ Compress Fonts\n\u003e Some font formats such as **EOT** or **TTF** are not compressed by default. Make sure to apply some kind of compression to them.\n\u003e\n\u003e 🛠️ [Font Squirrel - Webfont Generator](https://www.fontsquirrel.com/tools/webfont-generator)\n----------\n\n## 🗄️ Server Optimization\nℹ️ *You can make huge improvements, even before your web app receives your assets.*\n\n\u003e #### ☑️ Configure Compression\n\u003e If you haven’t already, enable server-side compression. This reduces the size of HTTP responses and has the most impact. To see which type of compression your server supports, go to the \"Network\" tab in DevTools. Inspect the `Accept-Encoding` header in a request and you’ll see all available options.\n\u003e\n\u003e According to a benchmark test done by Akamai, brotli outperformed gzip by a median of **21%**.\n\u003e\n\u003e 📖 [Akamai - Understanding Brotli's Potential](https://blogs.akamai.com/2016/02/understanding-brotlis-potential.html)\n\n![Accept-Encoding Request Header](assets/accept-encoding-header.png)\n\n----------\n\n\u003e #### ☑️ Minimize the Number of HTTP Requests\n\u003e While compression can save significant amounts of data, you can further cut down page load times by minimizing the number of HTTP requests. Some common techniques are:\n\u003e\n\u003e - Bundling your assets\n\u003e - If bundle sizes are too large, you can make use of domain sharding and split them to smaller chunks\n\u003e - Use image sprites for CSS\n\u003e\n\u003e 📖 [MDN Web Docs - Domain Sharding](https://developer.mozilla.org/en-US/docs/Glossary/Domain_sharding)\n----------\n\n\u003e #### ☑️ Use a CDN\n\u003e Content delivery network can help you reduce response times. A CDN is a collection of servers distributed across the globe. It aims to help deliver content to users faster by choosing the server closest to the user’s location.\n\u003e\n\u003e 📖 [Akamai - What does CDN stand for? CDN Definition](https://www.akamai.com/us/en/cdn/what-is-a-cdn.jsp)\n----------\n\n\u003e #### ☑️ Use a Cache-Control Header\n\u003e Cache each resource to avoid unnecessary network trips.\n\u003e\n\u003e - For static assets that rarely change *(images, fonts)*: use a long expiry date\n\u003e - For other resources *(JavaScript, CSS)*: use an appropriate Cache-Control header\n\u003e\n\u003e 📖 [KeyCDN - How to Propertyl Configure Cache-Control](https://www.keycdn.com/support/cache-control)  \n\u003e 📖 [MDN Web Docs - Cache-Control](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)\n----------\n\n## 🇼 [Core Web Vitals](https://www.webtips.dev/core-web-vitals)\nℹ️ *Metrics that focus on three aspects of the user experience; loading, interactivity, and visual stability. They aim to quantify user experience, by introducing the below performance metrics*\n\n\u003e #### ☑️ Largest Contentful Paint\n\u003e **LCP** for short, measures the time it takes for the browser to fully render the main content of your page. LCP is considered good when it happens [within 2.5 seconds](https://web.dev/lcp/#what-is-a-good-lcp-score).\n\u003e\n\u003e ❓ **What are the main causes?**\n\u003e - Slow server response times\n\u003e - Slow resource loading\n\u003e - Render blocking elements\n\u003e\n\u003e ❓ **How can you resolve them?**\n\u003e - Optimize your server-side\n\u003e - Cut down the number of network requests\n\u003e - Lazy load offscreen resources\n\u003e - Defer render blocking assets\n\u003e\n\u003e 📖 [Web.dev - Largest Contentful Paint (LCP)](https://web.dev/lcp/)  \n\u003e 📖 [Webtips.dev - Core Web Vitals: Loading](https://www.webtips.dev/core-web-vitals#loading)\n----------\n\n\u003e #### ☑️ First Input Delay\n\u003e **FID** for short, measures the time it takes for the first user input to be processed. Anything [below 100ms](https://web.dev/fid/#what-is-a-good-fid-score) is considered good.\n\u003e\n\u003e ❓ **What are the main causes?**\n\u003e - Long-running JavaScript tasks\n\u003e - Slow resource times\n\u003e - Render blocking elements\n\u003e\n\u003e ❓ **How can you resolve them?**\n\u003e - Eliminate long-running JavaScript tasks, that you can identify through DevTools' Performance tab\n\u003e - Defer render blocking assets\n\u003e\n\u003e 📖 [Web.dev - First Input Delay (FID)](https://web.dev/fid/)  \n\u003e 📖 [Webtips.dev - Core Web Vitals: Interactivity](https://www.webtips.dev/core-web-vitals#interactivity)\n----------\n\n\u003e #### ☑️ Cumulative Layout Shift\n\u003e **CLS** for short, measures the amount of layout shifts on your page that causes elements to change position unexpectedly. A good CLS score is [less than 0.1](https://web.dev/cls/#what-is-a-good-cls-score).\n\u003e\n\u003e ❓ **What are the main causes?**\n\u003e - Images with no dimensions\n\u003e - Dynamically rendered content\n\u003e - Web fonts causing FOIT or FOUT\n\u003e - Bad state management *(can be counted as dynamically rendered content)*\n\u003e\n\u003e ❓ **How can you resolve them?**\n\u003e - Define a `width` and `height` property for images\n\u003e - Use `srcset` to display different resolution images for different devices\n\u003e - Always try to inject dynamic content below already existing content\n\u003e - If you use ads, define a fix size for them to reserve space\n\u003e\n\u003e 📖 [Web.dev - Cumulative Layout Shift (CLS)](https://web.dev/cls/)  \n\u003e 📖 [Webtips.dev - Core Web Vitals: Visual Stability](https://www.webtips.dev/core-web-vitals#visual-stability)\n----------\n\n\u003e #### ☑️ How to Measure Core Web Vitals?\n\u003e If you can't measure it, you don't know where to improve. Some tools that you can use for audits are listed below.\n\u003e\n\u003e 🛠️ [Lighthouse](https://developers.google.com/web/tools/lighthouse) - *An open-source, automated tool for improving the quality of web pages.*  \n\u003e 🛠️ [DevTools Performance Tab](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance) - *Get Started With Analyzing Runtime Performance*  \n\u003e 🛠️ [Goolge's PageSpeed Insight Tool](https://developers.google.com/speed/pagespeed/insights/) - *Generate the same Lighthouse report you would get from Chrome's DevTools*  \n\u003e 🛠️ [Google's Search Console](https://search.google.com/search-console/about) - *Measures your site's search traffic and performance, and shows which pages needs your attention for optimization*  \n\u003e 🛠️ [Web Vitals Chrome Extension](https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma) - *Chrome extension created for reporting core web vital scores*\n----------\n\n## ⚛️ Frameworks\nℹ️ *JavaScript Frameworks deserves a whole section on its own, as each can come with performance best practices on top of vanilla JavaScript.*\n\n### React Optimization Techniques\nℹ️ *A component-based declarative JavaScript Library for building user interfaces both on the web and mobile.*\n\n\u003e #### ☑️ Use Production Build\n\u003e By default, React includes many helpful warnings. These warnings are very useful in development. However, they make React larger and slower so you should make sure to use the production version when you deploy the app.\n\u003e\n\u003e 📖 [React.org - Use the Production Build](https://reactjs.org/docs/optimizing-performance.html#use-the-production-build)\n----------\n\n\u003e #### ☑️ Profile Components\n\u003e Using either DevTools' built in [Performance Tab](#performance-tab) or the [React Developer Tools](#react-developer-tools) Chrome extension, you can profile and visualize how components are mounted, updated and unmounted. This helps you visualize unnecessary re-renders.\n\u003e\n\u003e 📖 [React.org - Profiling Components with the Chrome Performance Tab](https://reactjs.org/docs/optimizing-performance.html#profiling-components-with-the-chrome-performance-tab)\n----------\n\n\u003e #### ☑️ Virtualize Long Lists\n\u003e If you are rendering long lists of data, reduce render time and the number of DOM nodes created by only rendering components that are visible to the user.\n\u003e\n\u003e 📖 [React.org - Virtualize Long Lists](https://reactjs.org/docs/optimizing-performance.html#virtualize-long-lists)  \n\u003e 📺 [YouTube:Addy Osmani - Rendering large lists with react-virtualized or react-window](https://www.youtube.com/watch?v=QhPn6hLGljU)\n----------\n\n\u003e #### ☑️ Pre-render routes\n\u003e If rendering React on your server is not an option for you, but you still want to improve the first paint of your application, you can try pre-rendering with React snap.\n\u003e It uses a headless browser to generate static HTML of every route during build time. These can be shipped along with your bundle to improve page load speed.\n\u003e\n\u003e 📖 [Web.dev - Pre-render routes with react-snap](https://web.dev/prerender-with-react-snap/)\n----------\n\n## 📚 Other Resources\n- 🏗️ HTML\n    - 📖 [Webtips.dev - 10 Best Practices for HTML](https://www.webtips.dev/10-best-practices-for-html)\n    - 📺 [YouTube:Google Chrome Developers - Optimise your code: load code at the right time](https://www.youtube.com/watch?v=eDd6Y6Z50Mg)\n\n- 🖍️ CSS\n    - 📖 [Webtips.dev - 10 Best Practices for Quickly Improving Your CSS](https://www.webtips.dev/10-best-practices-for-quickly-improving-your-css)\n    - 📖 [Webtips.dev - 7 Tips That Will Help You Get The Best Out of Sass](https://www.webtips.dev/7-tips-that-will-help-you-get-the-best-out-of-sass)\n    - 📖 [Webtips.dev - How to Get Better Overview of Your CSS](https://www.webtips.dev/how-to-get-better-overview-of-your-css)\n\n- 👨‍💻 JavaScript\n    - 📖 [Webtips.dev - 5 Best Practices for Clean JavaScript](https://www.webtips.dev/5-best-practices-for-clean-javascript)\n    - 📖 [Web Fundamentals - Optimize JavaScript Execution](https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution)\n    \n- 🗛 Fonts\n    - 📖 [Smashing Magazine - Optimizing Google Fonts Performance](https://www.smashingmagazine.com/2019/06/optimizing-google-fonts-performance/)\n    - 📺 [YouTube:DevTips - Font Loading Performance 📉 6 Experiments with FOUT \u0026 FOIT](https://www.youtube.com/watch?v=vTf9HRTWKtM)\n\n- 🇼 Core Web Vitals\n    - 📖 [Webtips.dev - Core Web Vitals: What Are They and Why You Need to Know About Them?](https://www.webtips.dev/core-web-vitals)\n    - 📖 [Web.dev - Web Vitals](https://web.dev/vitals/)\n    - 📖 [Web.dev - Tools to measure Core Web Vitals](https://web.dev/vitals-tools/)\n    - 📺 [YouTube:Google Chrome Developers - Optimize for Core Web Vitals](https://www.youtube.com/watch?v=AQqFZ5t8uNc)\n\n- ⚛️ Frameworks\n    - 📖 [ReactJS - Optimizing Performance](https://reactjs.org/docs/optimizing-performance.html)\n\n- 📜 Other\n    - 📖 [Webtips.dev - 10 Critical Performance Optimization Steps You Should Take](https://www.webtips.dev/10-critical-performance-optimization-steps-you-should-take)\n    - 📖 [Webtips.dev - How to Improve Page Speed by Optimizing Content](https://www.webtips.dev/how-to-improve-page-speed-by-optimizing-content)\n    - 📖 [Web.dev - Fast load times](https://web.dev/fast/)\n    - 📖 [Web.dev - Measure performance with the RAIL model](https://web.dev/rail/)\n    - 📖 [GitHub - Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist)\n    - 📺 [YouTube:Google Chrome Developers - Improving Load Performance - Chrome DevTools 101](https://www.youtube.com/watch?v=5fLW5Q5ODiE)\n","funding_links":["https://www.buymeacoffee.com/webtips"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowforfrank%2Fperformance-checklist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowforfrank%2Fperformance-checklist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowforfrank%2Fperformance-checklist/lists"}