docusaurus icon indicating copy to clipboard operation
docusaurus copied to clipboard

feat: defer mode

Open slorber opened this issue 5 years ago • 12 comments

Motivation

Webpack JS assets are added to the page using defer, making them less "critical" for the browser.

As Docusaurus v2 can almost work without any JS, we can see React hydration as non-mandatory progressive enhancement

For now it's just a POC

slorber avatar Aug 07 '20 11:08 slorber

[V2]

Name Link
Latest commit 0423acf493662f31d5b95ac7214279e55dd375ad
Latest deploy log https://app.netlify.com/sites/docusaurus-2/deploys/624fda5d3d15550008e0395a
Deploy Preview https://deploy-preview-3237--docusaurus-2.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

docusaurus-bot avatar Aug 07 '20 11:08 docusaurus-bot

I am highly interested in this, I was thinking of implementing the exact same thing. Is there any drawback you can think of?

Also, it might be interesting to let the user defer the main stylesheet. One could optimise their website by inlining the critical CSS and relying on the full stylesheet later in the rendering process in order to optimise the FCP.

mpsq avatar Aug 14 '20 16:08 mpsq

Hi,

Unfortunately I'm not a perf expert. Using http://web.dev/measure I get highly variable results but I don't see any significant improvement (at least in score) by deferring the scripts, so not sure how to reliably measure that it improves anything.

If that interests you, here are 3 Docusaurus deployments I used for my tests:

No JS at all: https://5f2d50ba7316ec0008f830a9--docusaurus-2.netlify.app/build/

JS low priority (end of body, defer) https://5f2d4cfb5ac4740007ff0684--docusaurus-2.netlify.app/build/

JS high priority (preload + no defer) https://5f2d193a5609540008fb969c--docusaurus-2.netlify.app/build/

If this is useful, I'd find it cool to be able to specific which one of the 3 modes you want :)

The "no js" is likely to have some issues currently but this seems fixable (can't expand sidebar categories etc...)

slorber avatar Aug 14 '20 19:08 slorber

Hi Sébastien,

Thanks for taking the time to do that. Here are Lighthouse performance results for each page:

  1. No JS at all: 2020-08-17-094146_grim

  2. JS low priority (end of body, defer) 2020-08-17-094424_grim

  3. JS high priority (preload + no defer) 2020-08-17-094331_grim

My take on the results:

  1. This is obviously the best, although FCP is higher than in 2. this is still better because the total blocking time is 0ms. That being said, this is probably not a practical solution for many Docusaurus V2 users, I am sure many people rely on client side rendering. This also breaks Algolia's search.

  2. Extremely good FCP, more than 2x faster than 3. while still keeping client side JS, this is the perfect solution IMO.

  3. Current situation, no matter was you do (I tested with: HTTP2, brotli compression, CDN and a blank page!), FCP will be mediocre at best, the blocking JS is the limiting factor.

mpsq avatar Aug 17 '20 08:08 mpsq

  1. => some users might not use the classic theme and won't necessarily have a search. If they really want the classic theme they can eventually not use the Algolia search at all, so I wouldn't see this widely used but I think it makes sense.

  2. 3). I also think 2 is theoretically better, but in my experience running tests using https://web.dev/measure/ (to not have my own computer as a bias), I get very random results, some runs get 2 better, some others get 3 better...

Maybe you could share me how you get these scores? are they consistent across multiple runs? My scores are very random , all 3 gives between 60 and 95 quite randomly so it's hard to do anything with that...

Note, React is working on progressive hydration, afaik this is not ready but this would be an interesting feature to get 3 perform better.

slorber avatar Aug 17 '20 10:08 slorber

Yes you are right, the results are changing quite a lot between runs. I will script this and run 100 tests per version, I will keep you updated once I have the results.

I still think 2. would be a great option: no downside and bench results seem to be better, let's prove it with reliable numbers :slightly_smiling_face:.

mpsq avatar Aug 19 '20 09:08 mpsq

Thanks :) that's something I wanted to do but didn't have time.

slorber avatar Aug 19 '20 10:08 slorber

For 100 runs (using Lighthouse programmatically), I get:

No JS: 99.55
Defer: 96.69
Preload: 92.63

If you want to reproduce the results yourself, you can check the code on this repo.

EDIT: I re-ran the script with 100 benchmarks (50 before) per scenario and updated the results accordingly.

mpsq avatar Aug 24 '20 11:08 mpsq

After 1000 runs:

No JS: 99.336
Defer: 95.886
Preload: 90.453

mpsq avatar Aug 24 '20 16:08 mpsq

⚡️ Lighthouse report for the changes in this PR:

Category Score
🟠 Performance 86
🟢 Accessibility 100
🟢 Best practices 100
🟢 SEO 100
🟠 PWA 80

Lighthouse ran on https://deploy-preview-3237--docusaurus-2.netlify.app/

github-actions[bot] avatar Nov 19 '21 01:11 github-actions[bot]

Size Change: -256 B (0%)

Total Size: 805 kB

Filename Size Change
website/build/index.html 38.3 kB -256 B (-1%)
ℹ️ View Unchanged
Filename Size
website/.docusaurus/globalData.json 49.9 kB
website/build/assets/css/styles.********.css 105 kB
website/build/assets/js/main.********.js 612 kB

compressed-size-action

github-actions[bot] avatar Nov 19 '21 01:11 github-actions[bot]

to be continued after React 18 upgrade: we need time sliced hydration

https://twitter.com/ryanflorence/status/1547959632663961602

slorber avatar Jul 18 '22 19:07 slorber