Skip to content

Commit

Permalink
chore(docs): Add more detail to improving site performance doc (#30916)
Browse files Browse the repository at this point in the history
Co-authored-by: Lennart <lekoarts@gmail.com>
  • Loading branch information
calcsam and LekoArts committed Apr 22, 2021
1 parent 8fed439 commit 45e69fa
Showing 1 changed file with 34 additions and 22 deletions.
56 changes: 34 additions & 22 deletions docs/docs/how-to/performance/improving-site-performance.md
Expand Up @@ -22,17 +22,19 @@ These tools measure what are known as "Core Web Vitals", which measure both time

Site performance monitoring becomes increasingly important the more long-lasting your project is. You can put a lot of effort into performance work -- but then ship a performance regression that wipes out all your hard work!

There are two options for this:
There are three options for this:

- Gatsby Cloud has Lighthouse performance reports built into its CI/CD. Every time someone opens a pull request or merges into master, a Lighthouse report will be run and the performance score displayed.

- Use a third-party service that offers performance monitoring. Different services offer different options -- schedule runs on a daily basis or CI/CD integration through GitHub (or your source control service).
- Use a third-party service that offers performance monitoring, such as [Calibre](https://calibreapp.com/) or [Speedcurve](https://speedcurve.com/)

For additional precision, run Lighthouse multiple times and take the median result.
- Integrate Webpagetest or Lighthouse reports into your CI/CD process, via eg webhooks or Github Actions.

For additional precision, run a test multiple times and take the median result.

### Step 3: Quantify the impact of each change you make 

While you're doing performance-improvement work, it's important to understand the impact of each change or set of changes. You may find that one change gives you a 2-point Lighthouse improvement and another gives you a 20-point improvement.
While you're doing performance improvement work, it's important to understand the impact of each change or set of changes. You may find that one change gives you a 2-point Lighthouse improvement and another gives you a 20-point improvement.

There's an easy way to measure this:

Expand All @@ -45,13 +47,13 @@ Performance work can be surprisingly nonlinear in impact.

## Part 2: Implement Improvements.

When you run a test in your testing tool of choice, it will give you a number of recommendations. While this can feel like a laundry list of issues, it can be helpful to understand the five core categories that these issues are bucketed into.
When you run a test in your testing tool of choice, it will give you a number of recommendations. These can be bucketed into five core categories:

- Blocking calls & third-party scripts.
- JavaScript bundle size.
- Stylesheets and font files.
- Images and other media.
- Resource requests & CDN caching configuration.
- [Blocking calls & third-party scripts](#address-third-party-script-impact).
- [JavaScript bundle size](#reduce-your-javascript-bundle-cost).
- [Stylesheets and font files](#styling--fonts).
- [Images and other media](#images--media).
- [Resource requests & CDN caching configuration](#resource-requests--cdn-configuration).

Every site is different, and the recommendations will give some guidance as to where the highest effort to impact ratio is on your site.

Expand Down Expand Up @@ -93,21 +95,29 @@ To reduce your JavaScript bundle size, follow the steps below.

#### Step 1: Profile your bundle

The first step to fix this is to figure out what's going on. Use `gatsby-plugin-webpack-bundle-analyzer` to profile your bundle. When you add this tool to your `gatsby-config.js`, you can analyze the bundle size on each page in your application.
The first step to fix this is to figure out what's going on. Use `gatsby-plugin-webpack-bundle-analyzer-v2` and the _experimental_ plugin `gatsby-plugin-perf-budgets` to profile your bundle. When you add this tool to your `gatsby-config.js`, you can analyze the bundle size on each page in your application.

Chunk naming patterns help you break down a page into three categories:

- application-level chunks (shared with all pages),
- template-level chunks (shared with all pages of the same template),
- page-level data imports

#### Step 2: Remove unneeded third-party imports from `commons.js`
Visuals illustrating this breakdown: [all chunks on a page](https://www.slideshare.net/calcsam/the-anatomy-of-a-performance-audit/29), [only application-level chunks](https://www.slideshare.net/calcsam/the-anatomy-of-a-performance-audit/30), [only template-level chunks](https://www.slideshare.net/calcsam/the-anatomy-of-a-performance-audit/31).

Start by auditing your `commons.js` -- the bundle that is shared by all components.
#### Step 2: Remove unneeded third-party imports from application-level chunks

The first thing to do is inspect third-party package size. Anything over 50kb, and certainly 100kb, is worth examining whether it's needed. Some common culprits include: [Moment.js](https://momentjs.com/docs/#/-project-status/), Lodash, [Material UI](https://www.freecodecamp.org/news/gatsby-perfect-lighthouse-score/#step3droppingmaterialuifortailwindcss), but you'll want to inspect your individual libraries.
Start by auditing your application-level chunks, especially `commons.js` -- the bundle that is shared by all components.

Start by inspecting third-party package size. Anything over 50kb, and certainly 100kb, is worth examining whether it's needed. Some common culprits include: [Moment.js](https://momentjs.com/docs/#/-project-status/), Lodash, [Material UI](https://www.freecodecamp.org/news/gatsby-perfect-lighthouse-score/#step3droppingmaterialuifortailwindcss), but you'll want to inspect your individual libraries.

To prevent large imports from recurring, consider using a tool that displays the size of library imports you're pulling in. The [Import Cost](https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost) extension for Visual Studio Code and [BundlePhobia](https://bundlephobia.com/) are good resources.

In addition, eyeball all the medium-sized packages (10-50kb). If it doesn't look like there's a good reason for that particular package to be in the commons, carefully audit your import structure
In addition, eyeball all the medium-sized packages (10-50kb). If it doesn't look like there's a good reason for that particular package to be in the commons, carefully audit your import structure.

One edge case: If you're [importing Redux globally](/docs/adding-redux-store/), Redux can pull in data bundles that don't seem to be related. If you're only using Redux on a page or two, you may want to check the impact by removing it entirely and running Lighthouse.

#### Step 3: Audit your `commons.js` file for components and data that don't need to be on every page
#### Step 3: Audit your application-level chunks for components and data that don't need to be on every page

One common challenge is inadvertently pulling in more code or data than you intend to your commons bundle.

Expand All @@ -125,21 +135,21 @@ There's a couple ways to detect this:

#### Step 4: On critical paths, identify unneeded code & components

Start by identifying critical paths on your site -- destinations you really care about. This might be your home page, a signup page, a product template, and so on. Other site stakeholders may have opinions; it's worth quickly consulting them.
Your site likely has critical paths on your site that are very important to business success. This might be your home page, a signup page, a product template, and so on.

Then, inspect the critical paths for large third-party libraries and unneeded components. Repeat the process from steps two and three to identify optimization opportunities.
Inspect critical paths' template-level chunks for large third-party libraries and unneeded components. Repeat the process from steps two and three to identify optimization opportunities.

#### Step 5: On critical paths, lazy-load below-the-fold components

Gatsby's default behavior is to bundle the entire page together. However, there may be some components that don't need to be loaded right away. Perhaps your home page is quite long and you're willing to defer loading elements farther down on the page if it makes the initial page load faster.

One way you can do this is to lazy-load below-the-fold components using `loadable-components`. `loadable-components` is the recommended lazy-loading solution for all server-side-rendered React applications, including Gatsby websites.

We recommend you use the [gatsby plugin to install `loadable-components`](https://www.gatsbyjs.com/plugins/gatsby-plugin-loadable-components-ssr/).
We recommend you use the [gatsby plugin to install `loadable-components`](https://www.gatsbyjs.com/plugins/gatsby-plugin-loadable-components-ssr/). This plugin ensures that all components are still server-rendered for performance benefits.

#### Step 6: Consider using the Preact plugin

[Preact](https://preactjs.com/) is a UI library that works similarly to React, but is much smaller (~3kb compressed as opposed to ~40kb). [Gatsby-plugin-preact](https://www.gatsbyjs.com/plugins/gatsby-plugin-preact/) is a drop-in plugin that will render your site in Preact instead of React, cutting 35-40kb of JavaScript from your bundle.
[Preact](https://preactjs.com/) is a UI library that works similarly to React, but is much smaller (~3kb compressed as opposed to ~40kb). [gatsby-plugin-preact](https://www.gatsbyjs.com/plugins/gatsby-plugin-preact/) is a drop-in plugin that will render your site in Preact instead of React, cutting 35-40kb of JavaScript from your bundle.

This step can make sense if the `framework.js` bundle is a large part of your overall bundle size, and want to further optimize.

Expand Down Expand Up @@ -182,13 +192,13 @@ Font optimizations are usually small, but easy performance wins.

Media files are often the largest files on a site, and so can delay page load significantly while they are pulled over the network, especially if their location is not well-defined.

[Gatsby Image](/docs/how-to/images-and-media/using-gatsby-image/) is our approach to optimizing image loading performance. It does three basic things:
[Gatsby Plugin Image](/docs/how-to/images-and-media/using-gatsby-image/) is our approach to optimizing image loading performance. It does three basic things:

1. It delays non-essential work for images not above the fold to avoid esource congestion.
2. It provides a placeholder during image fetch.
3. It minimizes image file size to reduce request roundtrip time.

The `gatsby-image` documentation is fairly exhaustive, ranging from [why image optimization is important](/docs/conceptual/using-gatsby-image/), or [how to implement Gatsby Image](/docs/how-to/images-and-media/using-gatsby-plugin-image/), to a [Gatsby Image reference](/docs/reference/built-in-components/gatsby-image/).
The `gatsby-plugin-image` documentation is fairly exhaustive, ranging from [why image optimization is important](/docs/conceptual/using-gatsby-image/), or [how to implement Gatsby Plugin Image](/docs/how-to/images-and-media/using-gatsby-plugin-image/), to a [Gatsby Image reference](/docs/reference/built-in-components/gatsby-image/).

Implementing Gatsby Image is typically the bulk of image- and media-related performance optimization.

Expand All @@ -206,6 +216,8 @@ Part of the work in loading a Gatsby site is minimizing the time to transport bi

## Additional Resources

- We did a "talk" version of this documentation at GatsbyConf 2021: "The Anatomy of A Performance Audit" ([video](https://www.youtube.com/watch?v=x4RfrJiIzBE),[slides](https://docs.google.com/presentation/d/1tRsmG77NqG85tTbNZF9lDIKe44NPNqZgzWA-J_seQek/edit#slide=id.gcb9a0b074_1_0))

- [Smashing Magazine's Frontend Performance Checklist](https://www.smashingmagazine.com/2021/01/front-end-performance-2021-free-pdf-checklist/#delivery-optimizations) is an in-depth, more generalized guide to performance optimization. It isn't specific to Gatsby, so some of the things it mentions Gatsby will already do for you.

- We've written additional material in the past, for example [Kyle Mathews's deep dive blog](https://www.gatsbyjs.com/guides/why-are-gatsby-sites-fast/), [Dustin Schau's deep dive blog](https://www.gatsbyjs.com/blog/2018-10-03-gatsby-perf), and the [Gatsby Guide](https://www.gatsbyjs.com/guides/why-are-gatsby-sites-fast/).
Expand Down

0 comments on commit 45e69fa

Please sign in to comment.