Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Optimizing Unused CSS and JavaScript with the Coverage Tab

Hello! Welcome to the final lesson of our module on Performance Profiling and Optimization.

In our previous lessons, we've focused on runtime performance—diagnosing jank, identifying long tasks, and visualizing the rendering pipeline to make our applications feel smooth and responsive during user interaction.

Today, we shift our focus from runtime to load-time performance. A fast-loading application is the first step toward a great user experience. As a seasoned front-end developer, you know that modern applications often rely on large libraries and frameworks, leading to substantial bundle sizes. A common side effect is shipping code that isn't immediately necessary for the initial page render. This lesson will equip you to tackle this problem head-on by using the Coverage tab to find unused CSS and JavaScript that can be eliminated or lazy-loaded, directly improving your application's initial load speed.

The Problem: The High Cost of Unused Code

Every byte of code you ship has a cost. For the user, it consumes their mobile data. For the browser, it increases the time spent downloading, parsing, compiling, and executing. If this code is render-blocking, the browser can't show anything to the user until that work is done. This is a common and significant performance bottleneck.

The official Chrome documentation provides a clear example of this problem using Bootstrap.

Coverage: Find unused JavaScript and CSS

To understand why shipping unused code is detrimental to performance, let's start with this brief overview from the Chrome team. It perfectly frames the problem we're solving today.

Read the 'Overview' section. It uses the familiar example of including a large CSS framework for a single component to illustrate why unused code slows down page loads and wastes user data.

As the article highlights, even if you only use one component from a library, you might be forcing the user to download the code for all of its components. The Coverage tab is designed to help you pinpoint exactly this kind of waste.

Finding Unused Code with the Coverage Tab

The Coverage tab is your primary tool for instrumenting your page to see which lines of code are executed versus which are not. Let's get it set up and run our first analysis.

How to Record and Analyze Coverage

The process involves three main steps:

  1. Open the Coverage tab.
  2. Start a recording and reload the page.
  3. Interact with your application to simulate a typical user journey.
  4. Stop the recording and analyze the report.

This video from the "Chrome for Developers" channel provides a concise demonstration of this workflow.

Improving Load Performance - Chrome DevTools 101

This short video demonstrates the end-to-end process of using the Coverage tab to find unused code. It's a great visual primer before we dive into the details.

Watch the segment from 06:36 to 07:58. Pay attention to how the Coverage tab is opened via the Command Menu, how the recording is started, and how the results are displayed in both a summary table and within the Sources panel.

Now that you've seen it in action, let's break down the interface and the data it provides.

Interpreting the Coverage Report

Once you stop the recording, DevTools presents a detailed report.

Chrome DevTools Coverage Tab for Unused Code Identification
The Coverage tab report. The table lists each file, while the Sources panel on the right shows a line-by-line analysis. Red lines indicate code that was not executed during the recording session.

The report table gives you a high-level overview:

  • URL: The resource that was analyzed.
  • Type: Whether the resource is CSS, JavaScript, or both.
  • Total Bytes: The full size of the file.
  • Unused Bytes: The critical metric—how much of the file was not executed.
  • Usage Visualization: A bar chart giving you an at-a-glance view of the used (green/gray) vs. unused (red) code ratio.

Clicking on any file in this table opens it in the Sources panel, where you get a line-by-line breakdown. Lines marked with a solid green bar (or blue in some versions) were executed, while lines marked with a solid red bar were not. This granular view is essential for understanding which specific functions or CSS rules are going unused.

For a more hands-on demonstration that explores the interactive nature of the Coverage tab, the following video is excellent. It shows how user interactions can change the coverage results in real-time.

How to Find Unused CSS Styles with Chrome Dev Tools

This video by Steve Griffith offers a more in-depth walkthrough, showing how to filter the report and how interacting with the page (like clicking a button or resizing the window) affects the code coverage metrics for both CSS and JavaScript.

Watch from 02:08 to 06:29. This covers opening the panel, recording coverage for CSS, and then for JavaScript. Notice how he triggers a media query and a click event, and the corresponding code's coverage status updates from unused (red) to used (blue/green).

Test your understanding!

You are working on a single-page application (SPA) for a project management tool. The main dashboard loads a large vendor.js bundle that includes code for every feature (e.g., charts, calendars, chat widgets).

You run the Coverage tab on the initial page load of the dashboard and find that the code for the charting library and the calendar widget is almost 100% unused.

  1. What does this finding immediately tell you about your application's bundling strategy?
  2. What is the most effective optimization you could implement based on this data?
Show answer
  1. This finding indicates that the application is using a monolithic bundling strategy, where code for all features is bundled together and loaded upfront, regardless of whether the user needs it immediately. The code for the charts and calendar is being downloaded and parsed on initial load, even though those features might not be visible or used right away.

  2. The most effective optimization would be code-splitting and lazy-loading. You should configure your bundler (like Webpack or Vite) to split the charting library and calendar widget code into separate JavaScript chunks. Then, you would modify your application logic to dynamically import() these chunks only when the user needs them—for example, when they navigate to a reporting page that displays charts or click a button to open the calendar view. This would remove that code from the initial vendor.js bundle, making the dashboard load significantly faster.

From Detection to Action: Optimizing Your Codebase

Identifying unused code is only the first step. The real value comes from acting on that information. The strategies you employ will depend on your project's build process and architecture, with which you are undoubtedly familiar. The Coverage tab provides the data to justify and guide these efforts.

1. Code-Splitting and Lazy-Loading (JavaScript)
As highlighted in the exercise, the most powerful strategy for unused JavaScript is to not load it until it's needed. The Coverage report is your map for identifying candidates for code-splitting. If a large portion of code related to a specific feature is red on initial load, it's a prime candidate to be split into a separate chunk and lazy-loaded.

2. Tree-Shaking and Dead Code Elimination (JavaScript & CSS)
Modern bundlers are excellent at tree-shaking—automatically removing unreachable code from your final bundles. The Coverage tab can help you verify that your tree-shaking is working as expected. If you see code that you believe should have been removed, it might point to a configuration issue or a library that has side effects preventing it from being eliminated.

For CSS, tools like PurgeCSS can be integrated into your build process. They analyze your template files and remove any CSS selectors that aren't being used, which is especially effective when using large utility-first frameworks.

The Lighthouse documentation provides a concise summary of these approaches.

Remove unused JavaScript | Lighthouse

This Lighthouse article reinforces the importance of removing unused JavaScript and connects the detection phase (using the Coverage tab) to the action phase (using build tools).

Read the sections 'Detect unused JavaScript' and 'Build tool for support for removing unused code'. This will solidify the connection between what you find in DevTools and the practical steps you take in your development environment with bundlers and code splitting.

Conclusion

In this lesson, we completed our tour of the Performance panel by focusing on a critical aspect of load performance: bundle size. You learned how to use the Coverage tab to get precise, line-by-line data on which parts of your CSS and JavaScript are actually being used.

Key Takeaways:

  • Shipping unused code significantly slows down initial page load and wastes users' data.
  • The Coverage tab is the definitive tool for identifying unused CSS and JavaScript by recording a user session.
  • The report provides both a high-level summary and a granular, line-by-line view in the Sources panel, marked with red (unused) and green/blue (used) indicators.
  • The data from the Coverage tab is actionable: it provides the evidence needed to implement powerful optimization techniques like code-splitting, lazy-loading, and dead code elimination using your build tools.

This lesson concludes our module on performance. You now have a robust toolkit for diagnosing and fixing both runtime and load-time bottlenecks.

In our next module, Advanced Network Analysis, we will take a deeper dive into the Network panel. We'll start by learning how to diagnose connection issues by interpreting the timing phases in the network waterfall, giving you an even more detailed understanding of what happens before your code even begins to execute.

Can't find a good explanation? Sign up and we'll make it for you

Sign up