zooniverse / front-end-monorepo

A rebuild of the front-end for zooniverse.org
https://www.zooniverse.org
Apache License 2.0
104 stars 30 forks source link

Home page loads in ~11MB of images, ~13MB of JS #6254

Open eatyourgreens opened 2 weeks ago

eatyourgreens commented 2 weeks ago

Expected behavior

Images should be optimised for display online, and the home page should ideally load in less than 1s.

Current behavior

The home page pulls in a bunch of unoptimised images from the Zooniverse blogs, ranging in size from 0.5MB all the way up to a whopping 7.5MB! Even on fibre broadband, the page takes 11s to fully load.

These images in particular could benefit from being resized for display online:

Steps to replicate

Examine the overall page weight and image sizes in the Network panel of the browser dev console.

Image sizes for the Zooniverse home page, in the Firefox Network panel.

Signed-out, the home page also loads in more than 10MB of YouTube JS, for a total page weight of 31MB.

JavaScript download sizes, ordered by size, for the signed-out Zooniverse home page in the Firefox Network panel.

Additional context

Here's a page speed report, including Core Web Vitals: https://pagespeed.web.dev/analysis/https-fe-root-preview-zooniverse-org/xk3wjubq40?form_factor=mobile

It's a failure on both desktop and mobile, but includes a list of steps you can take in order to pass. It estimates that you can reduce image sizes by at least 6MB.

The new page renders entirely in the browser and is also much slower than the old home page:

eatyourgreens commented 2 weeks ago

One of the reasons that the new page is slow, is that isLoading here is always true on the server, so rendering of the whole home page (including static content like the list of blog posts) is deferred to the browser: https://github.com/zooniverse/front-end-monorepo/blob/f7c4e1064eb2da9650d7f4831cebe3af2c05a53e/packages/app-root/src/components/HomePageContainer.js#L18-L22

This also means that the page scroll position is lost when navigating backwards and forwards, since the scroll position refers to the height of the server-rendered Loader component (#6208.)

Here's the new home page in Firefox, with JS disabled. This is what a user will see if they're on a flaky connection and one of the JS files errors while it's downloading. This is also how search engines and social media bots will see the home page.

The new Zooniverse home page in Firefox with JS enabled, showing just a loading spinner that will never complete.
eatyourgreens commented 2 weeks ago

Paul Irish's lite-youtube-embed has a couple of React ports that won't use 2.5MB of JS per video. It's probably quite easy to write your own lightweight React YouTube embed too.

EDIT: There's a lite-youtube-embed React wrapper for Next.js. It's distributed with @next/third-parties. It's only 30 lines of JS!

seanmiller26 commented 2 weeks ago

@eatyourgreens I went ahead and resized the penguin photo. I didn't bother to optimize the other 2 as they soon will be pushed off the feed by new posts. This is a good reminder to optimize our image sizes before uploading to the blogs.

eatyourgreens commented 2 weeks ago

@seanmiller26 👍 The penguin image looked like it had been uploaded straight from someone's iPhone. I'm surprised that Wordpress doesn't automatically resize images for the blog RSS feeds.

Longer term, it should be straightforward to add rules to https://github.com/zooniverse/thumbnailer/ that allow it to resize images from daily.zooniverse.org and blog.zooniverse.org.

eatyourgreens commented 2 weeks ago

If you want to test this in a browser, I recommend setting throttling to either 4G or 'slow 4G', which is apparently representative of rural network speeds in the USA.

For a more in-depth write-up of JS-first performance and its disproportionate effect on the least privileged members of society, read Alex Russell's excellent Reckoning series of posts. Simon Willison summarised it in a single page too.

eatyourgreens commented 1 week ago

@seanmiller26 I've added lazy loading in #6255, so that blog images aren't loaded unless you scroll down to that section of the page.