Pagina’s alvast laden voordat iemand klikt

Jeroen Bijgewerkt 2026-07-16 · 3 min lezen

Een klik voelt direct als de volgende pagina al klaarstaat. Dat kan, want je laat bijna altijd zien waar je heen wilt voordat je klikt. Eerst gaat de muis naar de link. Dan druk je de knop in, en pas bij het loslaten volgt de browser de link. Elk van die momenten kun je gebruiken.

Kort gezegd

  1. 01 NuxtLink laadt code, geen data
  2. 02 Laad de data al bij hover
  3. 03 Navigeer bij indrukken, alleen met een muis
  4. 04 Laad nooit vooraf wat iets verandert

Wat Nuxt al doet

NuxtLink laadt standaard de code van een pagina zodra de link in beeld komt. Op een pagina met veel links is dat veel werk voor pagina’s die niemand opent. Je kunt het omzetten naar laden bij hover of focus:

// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    defaults: {
      nuxtLink: {
        prefetchOn: { visibility: false, interaction: true }
      }
    }
  }
})

Bij een 2G-verbinding of offline slaat Nuxt het vooraf laden over.

Let op: dit laadt de code van de pagina. De data komt alleen mee bij pagina’s die al bij de build gerenderd zijn. Haalt de pagina zijn inhoud live op met useFetch, dan wacht je daar na de klik nog op.

Data laden bij hover

Daarom laad ik bij hover ook de data. Tussen de muis op de link zetten en klikken zit tijd. Is de data binnen voordat je klikt, dan staat de pagina er meteen. Een klein hulpje is genoeg:

// app/utils/prefetch.js
const cache = new Map()

// Start the request on hover, the page picks it up after the click
export function prefetchData(url) {
  if (import.meta.server || cache.has(url)) return
  const request = $fetch(url)
  request.catch(() => cache.delete(url))
  cache.set(url, request)
}

export function fetchData(url) {
  const request = cache.get(url)
  cache.delete(url)
  return request || $fetch(url)
}

Op de link start je het verzoek, op de pagina pak je het op:

<NuxtLink
  :to="'/producten/' + product.slug"
  @mouseenter="prefetchData('/api/producten/' + product.slug)"
>
const url = '/api/producten/' + useRoute().params.slug
const { data } = await useAsyncData(url, () => fetchData(url))

De browser volgt een link pas als je de muisknop loslaat. Navigeer je al bij het indrukken, dan win je die tijd ook nog.

function onPointerdown(event, to) {
  // Only a plain left click with a mouse: touch starts a scroll, modifier keys open a new tab
  if (event.pointerType !== 'mouse' || event.button !== 0) return
  if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return
  navigateTo(to)
}
<NuxtLink :to="to" @pointerdown="onPointerdown($event, to)">

Wat er vaak misgaat

  • Alles vooraf laden. Elke link in beeld laden kost data en servertijd voor pagina’s die niemand opent. Laad bij hover, en wacht even: 50 tot 100 ms. Dan laadt een muis die over een menu schiet niet elke pagina.
  • Routes die iets doen. Haal vooraf alleen op wat niets verandert. Een API-route die een teller ophoogt, iets in een winkelwagen legt of iemand uitlogt, hoort er niet bij.
  • Oude data. Wie bij hover laadt en pas een minuut later klikt, ziet misschien een oude prijs of voorraad. Gooi vooraf geladen data na korte tijd weg als die vaak verandert.
  • Telefoons. Op een touchscreen is er geen hover. Navigeren bij aanraken breekt scrollen: wie een lijst wil scrollen en op een link begint, wordt weggestuurd. Navigeer daarom alleen bij indrukken met een muis.
  • Slepen en nieuwe tabbladen. Wie een link naar een nieuw tabblad sleept, of klikt met ctrl of cmd, wil niet weg. Controleer daarom de knop en de toetsen, zoals in het voorbeeld hierboven.

Wil je weten waar jouw winst zit?

Met de snelheidsaudit kijk ik verder dan de score, van server tot klik. Vaste prijs: € 850.

Bekijk de snelheidsaudit

Meer over snelheid