You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
import Vue from 'vue'
const requestIdleCallback = window.requestIdleCallback || function (cb) { const start = Date.now() return setTimeout(function () { cb({ didTimeout: false, timeRemaining: () => Math.max(0, 50 - (Date.now() - start)) }) }, 1) }
const cancelIdleCallback = window.cancelIdleCallback || function (id) { clearTimeout(id) }
const observer = window.IntersectionObserver && new window.IntersectionObserver((entries) => { entries.forEach(({ intersectionRatio, target: link }) => { if (intersectionRatio <= 0) { return } link.__prefetch() }) })
export default { name: 'NuxtLink', extends: Vue.component('RouterLink'), props: { prefetch: { type: Boolean, default: true }, noPrefetch: { type: Boolean, default: false } }, mounted () { if (this.prefetch && !this.noPrefetch) { this.handleId = requestIdleCallback(this.observe, { timeout: 2e3 }) } }, beforeDestroy () { cancelIdleCallback(this.handleId)
if (this.__observed) { observer.unobserve(this.$el) delete this.$el.__prefetch } }, methods: { observe () { // If no IntersectionObserver, avoid prefetching
if (!observer) { return } // Add to observer
if (this.shouldPrefetch()) { this.$el.__prefetch = this.prefetchLink.bind(this) observer.observe(this.$el) this.__observed = true } }, shouldPrefetch () { return this.getPrefetchComponents().length > 0 }, canPrefetch () { const conn = navigator.connection const hasBadConnection = this.$nuxt.isOffline || (conn && ((conn.effectiveType || '').includes('2g') || conn.saveData))
return !hasBadConnection }, getPrefetchComponents () { const ref = this.$router.resolve(this.to, this.$route, this.append) const Components = ref.resolved.matched.map(r => r.components.default)
return Components.filter(Component => typeof Component === 'function' && !Component.options && !Component.__prefetched) }, prefetchLink () { if (!this.canPrefetch()) { return } // Stop observing this link (in case of internet connection changes)
observer.unobserve(this.$el) const Components = this.getPrefetchComponents()
for (const Component of Components) { const componentOrPromise = Component() if (componentOrPromise instanceof Promise) { componentOrPromise.catch(() => {}) } Component.__prefetched = true } } } }
|