preload.ts


Overview

The preload.ts file is a utility module within the SWR (stale-while-revalidate) data fetching ecosystem that enables data preloading. Its main purpose is to allow data fetching operations to be initiated before a React component mounts and requests that data, thereby reducing loading delays and avoiding redundant network requests.

This module provides:

Together, they enable anticipatory data fetching with seamless integration into the SWR lifecycle, improving perceived performance and reducing fetch duplication.


Detailed Explanation

Type Definitions

type PreloadFetcher<
  Data = unknown,
  SWRKey extends Key = Key
> = SWRKey extends () => infer Arg
  ? (arg: Arg) => FetcherResponse<Data>
  : SWRKey extends infer Arg
  ? (arg: Arg) => FetcherResponse<Data>
  : never

preload Function

export const preload = <
  Data = any,
  SWRKey extends Key = Key,
  Fetcher extends BareFetcher = PreloadFetcher<Data, SWRKey>
>(
  key_: SWRKey,
  fetcher: Fetcher
): ReturnType<Fetcher> => {
  const [key, fnArg] = serialize(key_)
  const [, , , PRELOAD] = SWRGlobalState.get(cache) as GlobalState

  // Prevent preload to be called multiple times before used.
  if (PRELOAD[key]) return PRELOAD[key]

  const req = fetcher(fnArg) as ReturnType<Fetcher>
  PRELOAD[key] = req
  return req
}

Purpose

Parameters

Returns

Usage Example

import { preload } from './preload'

const key = ['user', 123]
const fetcher = (id: number) => fetch(`/api/user/${id}`).then(res => res.json())

// Initiate preload
const preloadPromise = preload(key, fetcher)

// Later, when component mounts, useSWR with the same key will consume this preloaded data

Implementation Details


middleware Function

export const middleware: Middleware =
  useSWRNext => (key_, fetcher_, config) => {
    // fetcher might be a sync function, so this should not be an async function
    const fetcher =
      fetcher_ &&
      ((...args: any[]) => {
        const [key] = serialize(key_)
        const [, , , PRELOAD] = SWRGlobalState.get(cache) as GlobalState

        if (key.startsWith(INFINITE_PREFIX)) {
          // we want the infinite fetcher to be called.
          // handling of the PRELOAD cache happens there.
          return fetcher_(...args)
        }

        const req = PRELOAD[key]
        if (isUndefined(req)) return fetcher_(...args)
        delete PRELOAD[key]
        return req
      })
    return useSWRNext(key_, fetcher, config)
  }

Purpose

Parameters

Returns

Usage Example

import useSWR from 'swr'
import { middleware as preloadMiddleware } from './preload'

const useSWRWithPreload = (key, fetcher, config) =>
  useSWR(key, fetcher, { ...config, middleware: [preloadMiddleware] })

const Component = () => {
  const { data, error } = useSWRWithPreload('user:123', fetchUser)
  // If data was preloaded, fetchUser won't be called again here.
}

Implementation Details


Important Implementation Details and Algorithms


Interaction with Other Parts of the System


Mermaid Diagram: Class & Function Structure

flowchart TD
  A[preload(key, fetcher)] -->|serialize key| B[Check PRELOAD cache]
  B -->|exists| C[Return cached Promise]
  B -->|not exists| D[Call fetcher with argument]
  D --> E[Store Promise in PRELOAD cache]
  E --> F[Return Promise]

  subgraph SWR Middleware Flow
    G[useSWR calls fetcher(key_)] --> H[serialize key_]
    H --> I{Key starts with INFINITE_PREFIX?}
    I -- Yes --> J[Call original fetcher]
    I -- No --> K[Check PRELOAD cache]
    K -->|exists| L[Delete PRELOAD entry]
    L --> M[Return preloaded Promise]
    K -->|not exists| N[Call original fetcher]
  end

Summary

The preload.ts module is a critical utility for enabling data preloading in the SWR framework. By providing a preload function and a middleware, it allows data to be fetched and cached before React components mount, improving performance and reducing redundant network requests. It integrates seamlessly with the SWR lifecycle by leveraging a dedicated preload cache and middleware interception, carefully handling key serialization and infinite loading edge cases.

This design supports:

Together, these features form an efficient, modular preloading system enhancing data fetching workflows in React applications using SWR.


Appendix: Key Imports and Dependencies


End of Documentation for preload.ts