If you ever worked with me you know how much I love talking about web performance. I usually share a few performance resources here in the newsletter, but in general, I try to keep it light and diversify the content a little bit.
Fast from the Start
Learning about web performance can sometimes feel like reading a business book; it's all fun and games until the acronyms show up.
Okay, business books aren't fun and games at all, but my point still stands. Open any web performance report, and you'll find yourself facing a wealth of different metrics, usually in the form of a three-letter acronym such as FCP, LCP, FID, CLS, TBT, INP, TTI, and the like.
If you're a performance expert, these reports are like music to your ears. But if you're just getting started, they can feel like a lot.
The challenge is not so much creating a fast website, but maintaining good performance over time and keeping bundle sizes in check as your website grows in complexity.
Easier said than done, I know, but there are a lot of great tools that can help us with it. Some of my most frequently used are:
- Webpack Bundle Analyzer, or a similar package for non-Webpack bundles, such as vite-bundle-visualizer or Lighthouse Treemap. These tools let you see the composition of your bundles via a treemap visualization, which makes it easy to identify heavy modules and third-party dependencies.
- bundlesize: a small and easy-to-use tool that checks your bundle size after every build as part of your CI pipeline. You can set limits for how much you're willing to let your bundles grow, and bundlesize will break your build if you go over them.
Take Meaningful Metrics
Before we can talk about specific performance metrics, it's important to define the two different types of metrics that we can measure: lab metrics and field metrics.
Lab metrics are gathered via synthetic testing tools like Google Lighthouse or WebPageTest, and they measure your website's performance at a particular moment in time and on specific device and network conditions. Lab metrics might not represent your typical customer experience, but they're useful as a baseline for measuring your progress during development.
Field metrics, on the other hand, are gathered by browser APIs and Real User Monitoring (RUM) tools from your real visitors. These metrics are a more accurate representation of how your users experience your website, but they take longer to collect and can be quite expensive depending on how popular your site is.
The next thing to figure out is which metrics are worth tracking. There are tons of different ones, and trying to measure each one of them can be a daunting task, even for the most performance-focused organizations.
A good place to start is by measuring Core Web Vitals. This is a set of user-centric metrics with the goal of measuring loading performance, interactivity, and visual stability. The current set of Core Web Vitals as I'm writing this are:
- Largest Contentful Paint (LCP): measures loading performance by reporting the render time of the largest image or text block on the page.
- First Input Delay (FID): measures interactivity by reporting the time it takes to respond to the first user interaction.
- Cumulative Layout Shift (CLS): measures visual stability by tracking how much your page's content unexpectedly shifts around.
A new metric called Interaction to Next Paint (INP) will soon replace FID to become a new stable Core Web Vital. INP is measured over the course of a user's visit rather than just the first interaction, and it's been proven to be a more accurate measurement of your website's responsiveness.
Measure Runtime Performance
Users will interact with your website beyond the initial page load, so ensuring a fast and responsive runtime experience is also very important—particularly for single-page applications where most user interactions do not cause a full-page refresh.
My favorite way of measuring runtime performance is using the Chrome DevTools Performance panel. You can start a performance recording at any time, perform any number of interactions, and then stop the recording to see the result.
A performance recording produces a comprehensive but quite intimidating report. Will it feel overwhelming the first time you look at it? Yes. But will it still feel overwhelming after the 1,000th time? Also yes.
There's a new Performance Insights panel that gives you actionable tips for improving your site's performance via a much simpler report. I like this panel for measuring Web Vitals and page-load performance, but I find the traditional Performance panel more useful for runtime metrics.
In particular, I like to focus on these two areas:
- The Network panel—look for resources that take too long to download or request waterfalls that could be parallelized. Pay special attention to this tab when lazy-loading scripts or navigating between routes on a single-page application.
Lastly, keep in mind that performance snapshots taken this way will give you lab data. Interactions might feel snappy on your device, but that doesn't necessarily mean it will feel the same for your users. It's generally a good idea to turn on throttling to simulate a 4x CPU slowdown to ensure users on lower-power devices also get a great experience.
We've only touched the surface of everything there's to know about web performance, but hopefully, this will give you a solid starting point.
If you're looking for more advanced web performance content, you're in luck! You'll find other great resources in today's newsletter.
This talk is also my favorite way to keep up with modern and evolving rendering patterns. Server-side rendering, islands architecture, server components, and resumable hydration are all covered in great detail with clear examples and visualizations. And if you're looking for a deeper dive on this subject, Addy and Lydia Hallie wrote an excellent guide on their book patterns.dev.
|Watch on YouTube|
Links Worth Checking Out
We've been talking about React Server Components for a while now, but the pattern can still lead to some confusion. Thankfully, Josh wrote a fantastic guide to help us make sense of them, which is also part of his upcoming and amazingly looking course The Joy of React.
Did you know you can define types for your CSS custom properties? @property lets you do exactly that, with types that are enforced both during development and in the browser.
The Shopify team wrote a detailed case study on how they tackled three of their biggest performance challenges with layout position: lazy-loading images, loading asynchronous CSS, and prioritizing the LCP.
Understanding the distinction between owners and parents is essential for composing React components correctly. This visual guide, full of interactive examples, clearly explains the differences.
Astro 3.0 launched a couple of weeks ago, and one of the most exciting new features is its built-in support for the View Transitions API. I had the pleasure of contributing a small part to this article, so this one is a bit of a shameless plug 😊
In its seven chapters, you'll learn about:
- Optimizing load-time and runtime performance: how the browser's main thread works and ways in which we can parallelize tasks.
- Managing third-party scripts: self-hosting, pre-connecting, and lazy-loading.
|Read more on A Book Apart|
That’s all for today, friends! Thank you for making it all the way to the end. If you enjoyed the newsletter, it would mean the world to me if you’d share it with your friends and coworkers. (And if you didn't enjoy it, why not share it with an enemy?)
Did someone forward this to you? First of all, tell them how awesome they are, and then consider subscribing to the newsletter to get the next issue right in your inbox.
I read and reply to all of your comments. Feel free to reach out on Twitter or reply to this email directly with any feedback or questions.
Have a great week 👋