-
Notifications
You must be signed in to change notification settings - Fork 11k
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
[11.x] Eager asset prefetching strategies for Vite #52462
Conversation
Thanks for submitting a PR! Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface. Pull requests that are abandoned in draft may be closed due to inactivity. |
937c291
to
890a814
Compare
890a814
to
ed6c5e4
Compare
Just as a question but perhaps something to consider or as additional feature. Would this also allow "page" prefetching when using Inertia? inertiajs/inertia#223 |
5759fca
to
b614355
Compare
@SuperDJ, that is outside the scope of this PR. |
@SuperDJ stay tuned for that. |
Added: Vite::useWaterfallPrefetching(concurrency: 10);
Vite::useAggressivePrefetching(); |
@timacdonald Does it support |
Awesome feature I'm employing immediately! |
I can't find the documentation for the prefetching part at https://laravel.com/docs/11.x/vite, or I might be looking in the wrong place. |
@david-fairbanks42, I've opened a PR that allows fine-grained control of kicking off the prefetch process: #52574 I'm not sure about a delay between individual assets. I would rather set a lower concurrency, e.g., @BassemN, docs are a work in progress. |
@BassemN, you can see the docs here: laravel/docs#9838 They reference a method that will be tagged in the next release (this week). |
@timacdonald, an event sounds like a great solution. Much more flexible. If my Monday doesn't bog me down to much, I'll check it out. |
@timacdonald, the event in #52574 does offer some wonderful flexibility, great solution. The following is probably irrelevant since users of production code wont disable browser cache. Doing some additional testing in Firefox and Chrome: The Firefox got the The use case I am trying to address specifically is application update when users are actively using the system. I already have signalling in place to prompt them to reload their browser window to get the latest code. What I'm trying to avoid is having to leave old versions of the the compiled JS code available and some strategy to clean it up after a reasonable period. Forcing immediate browser reload would not be a good user experience (mid filling out a form for instance). |
@timacdonald, thanks for the response. You're correct about the caching behavior. That's why I thought it was irrelevant. I look forward to event trigger being released! |
This PR adds the ability for applications to eagerly prefetch JavaScript and CSS chunks generated by Vite. The goal is to reduce the network delay / costs when navigating throughout a SPA front-end.
Applications built with Vite will often use "code splitting". This technique splits the JavaScript (and CSS) into smaller "chunks". When you load any given page, only the chunks required to render that page are loaded which leads to faster load times for applications. For example, when you land on the homepage you do not pay the cost of also downloading and parsing the admin dashboard JavaScript.
Below is an example of the chunks generated by a fresh Laravel Breeze application. You will notice some of these are pages, e.g.,
Dashboard
, while others are individual components, e.g.,PrimaryButton
.On subsequent navigation, the browser then needs to download the next page's chunks. This could be one or more files. For most situations, this will involve the browser making a request to download the assets and another request to download the data from the server.
Below is an example of the chunks downloaded when navigating from Breeze's dashboard page to its profile page.
Some front-end frameworks have improved this situation by prefetching assets on link hover or when the link enters the viewport. The Tailwind documentation site prefetches assets when the link enters the viewport.
Screen.Recording.2024-08-16.at.09.16.58.mov
The on-hover and enter-viewport technique works well for static website links, but not so well for stateful redirects to dynamic locations or forms that result in redirects to other locations after a POST, PUT, or other stateful request. It also does not always work when a user clicks a link while the asset is currently downloading. In that case, the browser may trigger another high priority request to download the asset.
This PR introduces a new technique for Laravel where an application can prefetch all chunks in the background on initial load. This retains the initial load optimisation introduced with chunking and improves subsequent navigation as assets have already been downloaded.
There are two strategies:
The waterfall technique allows you to specify how many assets should be concurrently downloaded. This allows you to manually control how much network is used by the prefetching strategy.
The below call to
usePrefetchStrategy
will use a default of3
concurrent downloads.Here is a very throttled load of a fresh Breeze application to illustrate the waterfall prefetching. After page load, which is represented in the timeline by the pink vertical line, the assets start concurrently downloading with a maximum of 3 active at any time.
Screen.Recording.2024-08-16.at.09.42.27.mov
The number of concurrent downloads may be customised by passing
['concurrently' => $count]
.Screen.Recording.2024-08-16.at.10.04.33.mov
The aggressive strategy will ask the browser to download all assets at once. Prefetch links, including those generated by the waterfall strategy, will ask the browser to download the assets with a low priority.
Screen.Recording.2024-08-16.at.10.05.51.mov
Vite adds a content hash to each chunk. When an application makes a change to a component only that chunk will have a new file name. If a browser has recently visited a site and then returns after a change to a single component, only the one component would need to be downloaded by the browser while prefetching. Although the requests for already downloaded assets will show up in the network tab they will show as cached.
Screen.Recording.2024-08-16.at.10.14.59.mov
Inertia-like front-end frameworks could benefit from these prefetching techniques even more. As they are back-end routed, it means that the response from the server determines which chunks are required to render the page. Due to this, the browser cannot start download the assets until the server response has been received. With these strategies in place, the server response is the only network traffic required to navigate between pages.
The prefetching will only load the JavaScript and CSS. It does not support prefetching images or other asset types.
Notes:
See: