Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: use pre-loaded WebP background image on homepage #2523

Merged
merged 8 commits into from
Nov 16, 2024

Conversation

angela-tran
Copy link
Member

@angela-tran angela-tran commented Nov 13, 2024

Closes #2490

This PR switches out our JPEG background image to a WebP image. It also adds HTML that will trigger preloading of the appropriate image based on media queries.

Lastly, to handle the case where the user's browser does not support WebP, we will set the background-color of the page to have sufficient contrast with the text on the page. (PR #2524)

See #2523 (comment) for details on the observed performance gains.

@angela-tran angela-tran self-assigned this Nov 13, 2024
Copy link

Coverage report

This PR does not seem to contain any modification to coverable code.

@github-actions github-actions bot added deployment-dev [auto] Changes that will trigger a deploy if merged to dev front-end HTML/CSS/JavaScript and Django templates labels Nov 13, 2024
@angela-tran
Copy link
Member Author

angela-tran commented Nov 14, 2024

Here's a summary of the improvements I tried and the measurement I did of changes in performance (i.e. "benchmarking").

The improvements on #2490 that made sense to try were:

  • Serve images in next-gen formats (WebP)
    • will reduce the amount of data to be downloaded
    • the change to make is to convert the images to WebP and switch out the JPEGs with them
  • Preload Largest Contenful Paint image
    • will make the network requests for the image happen earlier because otherwise, they would happen upon discovery during CSS parsing (the images are used via CSS, which the preload scanner does not look at)
    • the change to make is to explicitly tell the preload scanner about the background images via <link rel="preload"... in the HTML content

This one didn't seem applicable because we're not using an <img> element for the background image, and also, the background image is already being served responsively via media queries.

Results

I measured the performance of the homepage before any improvements and then after each improvement by generating Lighthouse reports in Google Chrome devtools against my locally running Benefits app. There are four scenarios:

  1. JPEG images, no preload (baseline)
  2. JPEG images, with preload - b5a8ea0
  3. WebP images, no preload - 526abe4
  4. WebP images, with preload - d8e85c7

I did two rounds of testing these scenarios, and for each scenario, I recorded 5 samples.

My Lighthouse settings:

image

Mode: Navigation (default)
Device: Mobile
Categories:
   - Performance
   - Accessibility
   - Best practices
   - SEO
Emulated Moto G Power with Lighthouse 12.2.1
Slow 4G throttling
Single page session
Round 1 results

1. JPEG images, no preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 87 2 3.9
2 85 2 4.1
3 82 2 4.5
4 84 2.3 4.1
5 82 2.3 4.5
Average 84 2.12 4.22

2. JPEG images, with preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 83 2.8 3.9
2 80 3.2 4.2
3 83 2.9 3.9
4 83 2.8 3.9
5 80 3.2 4.2
Average 81.8 2.98 4.02

3. WebP images, no preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 86 2 3.9
2 85 2 4.2
3 85 2 4.2
4 84 2.6 3.9
5 81 2.9 4.2
Average 84.2 2.3 4.08

4. WebP images, with preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 86 2.6 3.6
2 83 2.9 3.8
3 84 2.7 3.8
4 83 2.7 3.9
5 83 2.7 3.9
Average 83.8 2.72 3.8

In Round 1, using WebP images increased the Performance score slightly and decreased the time for Largest Contentful Paint (LCP). An interesting result is that using preload with either JPEG or WebP images increased the time for First Contentful Paint (FCP).

Round 2 results

1. JPEG images, no preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 80 2.6 4.5
2 82 2.9 4.1
3 82 2.6 4.2
4 81 2.7 4.2
5 81 2.7 4.2
Average 81.2 2.7 4.24

2. JPEG images, with preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 80 3 4.2
2 83 2.9 3.9
3 82 3.2 3.8
4 80 3.2 4
5 80 3.2 4.2
Average 81 3.1 4.02

3. WebP images, no preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 84 2.1 4.2
2 85 2.1 4
3 83 2.6 4
4 84 2.3 4
5 85 2.1 4
Average 84.2 2.24 4.04

4. WebP images, with preload

Sample Performance score First Contentful Paint (s) Largest Contentful Paint (s)
1 88 2.4 3.4
2 81 3.2 4
3 81 3.2 4
4 81 3.2 4.1
5 90 2 3.3
Average 84.2 2.8 3.76

Results for Round 2 are relatively similar to those of Round 1. Round 2 shows a clearer difference in performance.

In Round 2, using WebP images increased the Performance score and decreased the time for LCP. Similar to results from Round 1, preloading either JPEG or WebP images increased the time for FCP.

Raw reports

The Lighthouse reports I generated are attached here as JSON files:
performance-testing-2523.zip
You can open them at https://googlechrome.github.io/lighthouse/viewer/ to view more detail. (The report viewer does not upload the files anywhere; it just opens it locally in your browser.)

Conclusion

These results show that preloading WebP images overall reduces the amount of time to load the page than what we were doing (not preloading and using JPEG images).

Regarding the FCP time increase, I don't think there is anything more we can do to how the background image loads to improve it. The FCP time may improve when we do other web performance improvements like optimizing how we're loading CSS and Javascript (#2493) and enabling text compression for our server responses.

The improvements in this PR alone are not enough to get us down to an LCP of 2.5 seconds or less (what Google's Core Web Vitals initiative defines as a good user experience), but they at least do provide about a 0.4 - 0.5 second improvement under the simulated slow 4G throttling that Lighthouse uses.

Other helpful reading

ideally, the user's browser supports WebP and will show the image, but
just in case it doesn't, we want the white text to be readable.

use the same color as the left side of the background image. this
contrast ratio passes WCAG AAA requirements.
@angela-tran angela-tran marked this pull request as ready for review November 14, 2024 23:07
@angela-tran angela-tran requested a review from a team as a code owner November 14, 2024 23:07
@angela-tran
Copy link
Member Author

Another good section to read: https://web.dev/articles/preload-scanner#css_background_images

@angela-tran angela-tran marked this pull request as draft November 15, 2024 21:38
this is just to be more consistent with other usages in our codebase
and doesn't change anything functionally.
@angela-tran angela-tran marked this pull request as ready for review November 15, 2024 22:01
@angela-tran
Copy link
Member Author

I'll go ahead and merge #2524 into this

Copy link
Member

@thekaveman thekaveman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice 👍

@angela-tran angela-tran merged commit 11f5380 into main Nov 16, 2024
10 checks passed
@angela-tran angela-tran deleted the feat/webp-background-image branch November 16, 2024 01:21
@machikoyasuda
Copy link
Member

Thanks for the detailed comments and the great execution @angela-tran! 🎊 💯 💨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deployment-dev [auto] Changes that will trigger a deploy if merged to dev front-end HTML/CSS/JavaScript and Django templates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Web perf: Make homepage image more performant
3 participants