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
feat(nuxt-link): Smart prefetching and $nuxt.isOffline #4574
Conversation
Also a good plugin from @Atinux https://github.com/nuxt-community/guess-module/blob/master/lib/plugin.js#L10 |
We shouldn't forget that preloading happens for scripts and styles by default. https://github.com/nuxt/nuxt.js/blob/dev/packages/config/src/config/render.js#L6 |
Co-Authored-By: Atinux <seb@orion.sh>
Agree, here we are working only for |
Codecov Report
@@ Coverage Diff @@
## dev #4574 +/- ##
=======================================
Coverage 90.81% 90.81%
=======================================
Files 67 67
Lines 2220 2220
Branches 542 542
=======================================
Hits 2016 2016
Misses 185 185
Partials 19 19
Continue to review full report at Codecov.
|
@Atinux But isn't that the "wrong way around"? 🤔
(from https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf#89a4) |
Ideally we would EDIT: On the other hand, |
That's exactly the behaviour of this :) This is the <!DOCTYPE html>
<html data-n-head-ssr data-n-head="">
<head data-n-head="">
<title data-n-head="true">Home page</title>
<link rel="preload" href="/_nuxt/runtime.js" as="script" />
<link rel="preload" href="/_nuxt/commons.app.js" as="script" />
<link rel="preload" href="/_nuxt/vendors.app.js" as="script" />
<link rel="preload" href="/_nuxt/app.js" as="script" />
<link rel="preload" href="/_nuxt/pages/index.js" as="script" />
<style data-vue-ssr-id="d71a54be:0">/* ... */</style>
</head>
<body data-n-head="">
<div data-server-rendered="true" id="__nuxt">
<div id="__layout">
<div>
<h1>Welcome!</h1>
<a href="/about"> About Page </a>
</div>
</div>
</div>
<script>
window.__NUXT__ = {
layout: 'default',
data: [{}],
error: null,
serverRendered: true
}
</script>
<script src="/_nuxt/runtime.js" defer></script>
<script src="/_nuxt/pages/index.js" defer></script>
<script src="/_nuxt/commons.app.js" defer></script>
<script src="/_nuxt/vendors.app.js" defer></script>
<script src="/_nuxt/app.js" defer></script>
</body>
</html> As you can see, only the preloaded files are the bundle and current page that is rendered. |
Makes total sense 🙈 Sorry! 😄 |
We shouldnt prefetch links when when data saving enabled/2g like in quicklinks. |
Another thing is that not everyone will want this and the only way to disable it is to set noPrefetch to every link. Maybe add option in config for default value for noPrefetch |
Benefits of the way of this PR over directly prefetching next SSR rendered page:
|
Thank you for your comment @addyosmani You can watch a demo video of this feature: Actually, Nuxt already add the When the link is intersecting, we check if the user has a decent internet connection (online + Sadly, at the moment, Webpack does not support low priority request for lazy import (cc @sokra @TheLarkInn). |
23d53fa
Just wondering about action links... i.e. ones that may make state changes on the back end server (ie. disabling a user, deleting an item from a database, etc). Could this inadvertently do things that it shouldn't? |
@tmorehouse These shouldn't be nuxt links 🤔 |
@manniL yeah, I know, but there might be a few users who blindly will use |
@tmorehouse Even then it shouldn't execute the action as just the js file for the page is loaded and not the page itself |
@manniL Ah yeah, that is true. 😄 |
According to Atinux's comment nuxt/nuxt#4574 (comment), the "native" prefetch feature of Nuxt needs to be disabled for Guess.js to work. So I thought it would good to update the Readme accordingly.
The idea is to provide the same features as quicklink by default in Nuxt.js.
We use the
IntersectionObserver
if available, otherwise we document it to explain how to use Polyfill (see nuxt/docs#1068). When a<nuxt-link>
is detected within the viewport, we prefetch the linked page to it (thanks to Webpack code-splitting <3).A
no-prefetch
prop is also introduced to specify a<nuxt-link>
to not automatically prefetch the page (it won't be observed as well).The usage of
destroyed
hook let us free the observer as well as when the page is already prefetched, so the performances are really good. 🚀Like quicklink, we check is the user internet connection is fast enough (and online) to request the splitted-page file, we also keep observing the links so when she keeps navigating and her internet connection change, it could preload the link 😄
It also introduce the way of splitting components for both client & server to optimize bundle size (
nuxt-link.client.js
andnuxt-link.server.js
), this way, the server component does not rely on the IntersectionObserver. When a use disable this smart prefetching feature globallyrouter.prefetchLinks: false
, we directly use thenuxt-link.server.js
component on the client-bundle to reduce the bundle size 🔥This PR also introduce
$nuxt.isOnline
and$nuxt.isOffline
so users can directly rely on it for their Vue components (these props are reactive), a little Christmas gift 🎁.Demo video: