Reduce unused JavaScript and CSS: a practical guide

Pages ship code they never use. How to find unused JavaScript and CSS with the Coverage tool, what Lighthouse flags, and how to remove, split or delay it.

IntermediateHow-to6 min readUpdated October 30, 2026

In this guide
  1. What "unused" means
  2. Why it costs speed
  3. What Lighthouse reports
  4. Step 1: find the unused code
  5. Step 2: remove what nobody uses
  6. Step 3: ship only what each page needs
  7. Step 4: test every state
  8. A worked example
  9. How to check the result
  10. Check your own page
  11. Sources

What "unused" means

When a browser loads a stylesheet or a script, it does not know which part the current page will need. It downloads the whole file. Unused code is the part that is never used while the page loads and while you use it: CSS rules for elements that are not on the page, and functions that never run.

The Chrome documentation gives the standard example. You want one button component from a CSS framework, so you link the framework's whole stylesheet. The page needs a few hundred bytes of it and downloads tens of kilobytes. JavaScript works the same way: a charting library imported for one small chart, a sliding gallery loaded on every page, a polyfill for a browser nobody uses.

Why it costs speed

Text compression shortens the download but not the parsing, so shrinking the code is better than compressing it.

What Lighthouse reports

Lighthouse 13 lists two diagnostics, "Reduce unused JavaScript" and "Reduce unused CSS" (more on CSS in CSS performance). Neither counts toward the performance score directly. They describe how many bytes of each file were not used, and they have thresholds so that small cases do not clutter the report: the JavaScript diagnostic ignores a source unless more than 20 KB of it is unused, and the CSS diagnostic ignores a stylesheet unless more than 10 KB of it is unused. A page that passes both can still have unused code, just under those limits.

Step 1: find the unused code

Chrome DevTools Coverage. Open DevTools, run the "Show Coverage" command, press the record button and reload the page. The panel lists every CSS and JavaScript file with its size and the percentage that was unused, and colors the lines in the Sources panel: one color for what ran, another for what did not. Sort by unused bytes to see the worst first. Then use the page as a visitor would: open the menu, scroll, switch tabs, and watch the numbers change.

The Lighthouse report. It names the files and the unused bytes without you having to interact, which is a good way to start.

Bundle analysis. If your site is built with a bundler, a bundle analyzer draws a map of what is in each file, which library takes how much, and what is included twice. Most bundlers have a plugin for it. This finds the dependencies that cost the most before the code reaches the browser.

A caution from the Chrome documentation applies: finding unused code is relatively easy, and refactoring a codebase so each page ships only what it needs can be difficult. Coverage shows what did not run during your recording, not what can never run.

Step 2: remove what nobody uses

The cheapest bytes are the ones you delete.

Step 3: ship only what each page needs

Where the code is needed somewhere but not everywhere, split it.

JavaScript. Code splitting breaks one large bundle into several smaller files. MDN lists two main approaches: splitting by entry point, so that each page or section has its own bundle, and dynamic splitting, where a dynamic import() loads a piece of code at the moment it is needed:

document.querySelector('#open-chart').addEventListener('click', async () => {
  const { drawChart } = await import('./chart.js');
  drawChart();
});

The chart code downloads only when someone asks for the chart. Import only the parts of a library that you use, for example a single function instead of the whole package, so that your bundler can leave the rest out. This is called tree shaking, and it only works with modules that are written so that unused exports can be seen. The whole process for a bundle, from finding what is in it to splitting it, is in JavaScript bundle size and code splitting, and old libraries are covered in removing jQuery and other legacy libraries.

CSS. Split the stylesheet by template or section, so the checkout page does not load the blog's styles. A link with a media attribute keeps a file from blocking rendering when the condition is false, which suits print styles and large-screen-only styles. Remove rules for components that are not on the page with a tool that scans your pages and drops what they do not use. Many performance plugins have this option. Always keep a safelist for classes that are added by scripts or appear only in some states.

Both. Load heavy, rarely used parts only when needed: a video player on a click, a map when the visitor scrolls to it, a chat tool after a delay. See third-party scripts for patterns that work.

Step 4: test every state

Unused code removal is the kind of change that can break things in ways you do not see on the first load. Before and after, check:

When you remove CSS automatically, compare screenshots of your main pages before and after.

A worked example

This one is made up to show the method. A WordPress home page loads 14 stylesheets and 22 scripts. The Coverage tool shows that two stylesheets from a form plugin and a gallery plugin are 94% unused, because neither feature is on the home page, and a slider script of 180 KB runs on a page that has no slider. Three changes remove most of the waste: set the form plugin to load its files only on the contact page, remove the gallery plugin from the pages that do not use it, and replace the slider on the home page with a single image. None of this needs code. After each change, the page is tested again and the unused bytes drop.

How to check the result

  1. Run Coverage again and compare the total unused bytes.
  2. Compare the requests in the Network panel: fewer and smaller files.
  3. Run the lab test three times. Total Blocking Time and First Contentful Paint should improve, since less code is parsed and run.
  4. Click through the pages as in Step 4.

Check your own page

Run the free audit and look at the unused code diagnostics and the JavaScript execution time. Start with the largest file on the list: ask what it is for, which pages need it, and whether it can be removed, split or loaded later.

Sources

Start here

Free website audit

Live Google data for any public page: mobile and desktop.

Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it

Rather have this done for you? Speed optimization · Book a call

Related guides

All guides →