-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
[1.0] optimizations around prefetching page resources #1133
Conversation
…elay executing scripts after loading
Deploy preview ready! Built with commit fd01c58 |
Deploy preview ready! Built with commit fd01c58 |
Deploy preview ready! Built with commit fd01c58 |
b6c7328
to
19f7c72
Compare
A few more notes.
It seems to work quite well Been playing with this a lot recently and it definitely seems to speed up page transitions on slow networks so quite happy about that. |
Very cool! |
Do you have an example of that? |
@ev1stensberg every gatsby site before this PR :-) I'd often try loading gatsbyjs.org for example on a slow mobile connection and when I'd click a link be frustrated by the long wait before the next page loaded. The change here has helped a lot. |
Gotcha! You don't happen to have some old code samples, contra new ones? |
Hmm no but you can always clone the repo and go back in its history before this PR was merged and build from there. |
Oki! Thanks for explaining! ❤️ |
Well this ended up taking a lot more time than I anticipated (I thought a day, turned out to be ~3).
But really happy with what I came up with.
This PR does two big things + has a few extras:
Fixes some bugs that had been reported around our runtime #1106 and #1101
And make our prefetching smarter. Currently we prefetch a lot of stuff early on which can be problematic as if you click on a link, the loading of that page's resource can be blocked by the ongoing prefetching of other pages. This comes up fairly often on slower connections e.g. poor mobile connections.
The goal for Gatsby is that whenever you click on a link all the (static) resources for that page are already loaded. This is easy to accomplish on a desktop with a fast network connection but how to do this on a smartphone with limited CPU & network capacity?
On a slow enough connection we can't hope to have everything downloaded before the user clicks like it's quite possible to do on a fast connection.
So ideally we'd prioritize our prefetching by what a user is more likely to click to up the odds of prefetching the right things. But how to do that? One way is to hook up analytics for a site into building so the site prefetches commonly visited pages. But that's not yet ready and in any case, won't work for many sites that don't want to bear the extra complexity.
Also we want our prefetching to be smart so that if a user does click on a link w/o prefetched resources, we can stop prefetching to let just that page resources download. So similar to the React Fiber rewrite in this sense.
I came up with a few heuristics for deciding what resources to prefetch first.
It occurred to me that our
<Link>
components are mounted from the top of the page down (generally). Which is significant as (again generally) you're more likely to click on links at the top of the page vs. the bottom. So we can start downloading resources for the first links to be mounted.The next heuristic is that many pages share resources e.g. a template component. So it also counts how many times a resource is needed and prioritizes that.
So that does a decent job at deciding what resources to fetch first.
The final optimization is to make prefetching interruptible. Gatsby now limits prefetching to one resource at a time and when a page transition happens, stops prefetching until the new page is loaded. This ensures the lowest possible latency for switching to the new page.
Other optimizations
I snuck in a few other optimizations