gregberge / loadable-components

The recommended Code Splitting library for React ✂️✨
https://loadable-components.com
MIT License
7.65k stars 380 forks source link

Change the extractor.getLinkTags and getScriptTags to have options to speed up FCP for PageSpeed #720

Closed justin808 closed 3 years ago

justin808 commented 3 years ago

🚀 Feature Proposal

Numerous web sources suggest using defer and not async for the scripts.

We have found that by only using the first link tag, we get a considerably better (50% smaller) FCP, on pages like 110grill.com. This affects PageSpeed scores.

 const linkTags = extractor.getLinkTags().split('\n')[0];

The other scripts get loaded as needed.

Many articles recommend using defer rather than async. You can see some articles here: https://www.google.com/search?q=async+scripts+slowing+fcp

It seems that async scripts can pause rendering while the script is evaluated, which increases both FCP and LCP times.

Using defer instead of async would ensure that scripts are only evaluated after the document is painted. However, we probably don't want to defer code splitting bundles.

Maybe the "link data-chunk" is good enough for the async bundles?

Maybe even the first bundle should be using defer?

image

Motivation

Better page PageSpeed scores!

Example

See page source at https://www.110grill.com/

Pitch

Faster PageSpeed scores!

open-collective-bot[bot] commented 3 years ago

Hey @justin808 :wave:, Thank you for opening an issue. We'll get back to you as soon as we can. Please, consider supporting us on Open Collective. We give a special attention to issues opened by backers. If you use Loadable at work, you can also ask your company to sponsor us :heart:.

rtymchyk commented 3 years ago

Improving FCP can increase the gap until the content is interactive, widening the "uncanny valley" period, which means worse TTI (time to interactive scores).

Since TTI is weighed higher than FCP, it's actually sometimes better to "delay" the paint, and so I think defaulting to defer vs async is not a decision that can be made globally for all apps. It's also worth noting that Next.JS uses async by default.

Correct me if I'm wrong, but you should be able to provide { async: false, defer: true } to your getScriptTags call, if it works better for your app.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.