<link rel="preload">) is a browser optimization that allows critical resources (that may be discovered late) to be requested earlier. If you are comfortable thinking about how to manually order the loading of your key resources, it can have a positive impact on loading performance and metrics in the Core Web Vitals. That said, preload is not a panacea and requires an awareness of some trade-offs.
<script defer> in the document
<body> to help with early discover of these resources.
Preload in single-page apps
While prefetching is a great way to cache resources that may be requested some time soon, we can preload resources that need to be used instantly. Maybe it's a certain font that is used on the initial render, or certain images that the user sees right away.
EmojiPicker component should be visible instantly on the initial render. Although it should not be included in the main bundle, it should get loaded in parallel. Just like prefetch, we can add a magic comment in order to let Webpack know that this module should be preloaded.
const EmojiPicker = import(/* webpackPreload: true */ "./EmojiPicker");
Webpack 4.6.0+ allows preloading of resources by adding
/* webpackPreload: true */to the import. In order to make preloading work in older versions of webpack, you'll need to add the
preload-webpack-pluginto your webpack config.
After building the application, we can see that the
EmojiPicker will be prefetched.
Asset Size Chunks Chunk Names emoji-picker.bundle.js 1.49 KiB emoji-picker [emitted] emoji-picker vendors~emoji-picker.bundle.js 171 KiB vendors~emoji-picker [emitted] vendors~emoji-picker main.bundle.js 1.34 MiB main [emitted] main Entrypoint main = main.bundle.js (preload: vendors~emoji-picker.bundle.js emoji-picker.bundle.js)
The actual output is visible as a
link tag with
rel="preload" in the
head of our document.
<link rel="prefetch" href="emoji-picker.bundle.js" as="script" /> <link rel="prefetch" href="vendors~emoji-picker.bundle.js" as="script" />
EmojiPicker could be loaded in parallel with the initial bundle. Unlike
prefetch, where the browser still had a say in whether it think it's got a good enough internet connection and bandwidth
Instead of having to wait until the
EmojiPicker gets loaded after the initial render, the resource will be available to us instantly! As we're loading assets with smarter ordering, the initial loading time may increase significantly depending on your users device and internet connection. Only preload the resources that have to be visible ~1 second after the initial render.
Preload + the
Should you wish for browsers to download a script as high-priority, but not block the parser waiting for a script, you can take advantage of the preload + async hack below. The download of other resources may be delayed by the preload in this case, but this is a trade-off a developer has to make:
<link rel="preload" href="emoji-picker.js" as="script"> <script src="emoji-picker.js" async>
Preload in Chrome 95+
- Putting it in HTTP headers will jump ahead of everything else
- Generally, preloads will load in the order the parser gets to them for anything >= Medium so be careful putting preloads at the beginning of the HTML.
- Font preloads are probably best towards the end of the head or beginning of the body
- Import preloads should be done after the script tag that needs the import (so the actual script gets loaded/parsed first)
- Image preloads will have a low priority and should be ordered relative to async scripts and other low/lowest priority tags
Again, use preload sparingly and always measure its impact in production. If the preload for your image is earlier in the document than it is, this can help browsers discover it (and order relative to other resources). When used incorrectly, preloading can cause your image to delay First Contentful Paint (e.g CSS, Fonts) - the opposite of what you want. Also note that for such reprioritization efforts to be effective, it also depends on servers prioritizing requests correctly.
You may also find
<link rel="preload"> to be helpful for cases where you need to fetch scripts without executing them.
A variety of web.dev articles touch on how to use Preload to: