Next.js Discord

Discord Forum

Preloading dynamic() components on hover

Unanswered
Bombay posted this in #help-forum
Open in Discord
BombayOP
Hi all! 👋 Is there a way to programmatically trigger the download of a dynamic() imported component before it actually renders?

I want to start fetching the JS chunk on onMouseEnter so it opens faster when the user finally clicks. Any tips?

2 Replies

BombayOP
"use client";

import { useState } from "react";
import dynamic from "next/dynamic";

const loadHeavyWidget = () => import("./HeavyWidget");

const LazyWidget = dynamic(loadHeavyWidget, {
  ssr: false,
});

// LazyWidget.preload();

export default function Page() {
  const [showComponent, setShowComponent] = useState(false);

  const handleMouseEnter = () => {
    console.log("User Action: 🖱️ Hover detected. Calling .preload()...");

    loadHeavyWidget()
      .then((mod) => {
        console.log("HeavyWidget loaded!", mod);
      })
      .catch((e) => {
        console.error("Failed to load HeavyWidget", e);
      });
  };

  return (
    <div className="min-h-screen flex flex-col items-center justify-center gap-6 p-10 font-sans">
      <div className="max-w-md text-center">
        <h1 className="text-3xl font-bold mb-4">Lazy Loading Test</h1>
        <p className="mb-8 text-gray-500">
          Lorem ipsum dolor sit, amet consectetur adipisicing elit. Eaque
          corporis rem accusamus, sed qui ipsam et laborum.
        </p>

        <button
          className="px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
          onMouseEnter={handleMouseEnter}
          onClick={() => setShowComponent(true)}
        >
          Hover to Load / Click to Reveal
        </button>

        {showComponent && <LazyWidget />}
      </div>
    </div>
  );
}


any way to preload like LazyWidget.preload();
BombayOP
custom wrapper of dynamic()

import { ComponentType } from "react";
import dynamic from "next/dynamic";

export type LazyComponentType<P> = ComponentType<P> & {
    prefetch: () => void;
};

function customDynamic<P = {}>(
    ...args: Parameters<typeof dynamic>
): LazyComponentType<P> {
    const Component = dynamic(...args) as LazyComponentType<P>;

    const [loader] = args;

    Component.prefetch = () => {
        if (typeof loader === "function") {
            return loader();
        }
    };

    return Component;
}

export { customDynamic as dynamic };