vite icon indicating copy to clipboard operation
vite copied to clipboard

Setting manualChunks breaks react lazy loading

Open yspreen opened this issue 1 year ago • 3 comments

Describe the bug

I'm using a react component like

import { lazy, Suspense } from "react";
const Lazy = lazy(() => import("./LazyCanvasPreload"));

const FullPageSpinner = () => <>spin...</>;

const Component = () => {
  return (
    <>
      <Suspense fallback={<FullPageSpinner />}>
        <Lazy />
      </Suspense>
    </>
  );
};

export default Component;

to load a heavy three.js canvas. Without lazy loading this component makes the first paint have to wait for the ~2MB three and rapier libraries.

Vite does successfully chunk this component and it works great. Until I add this vite config:

{
    plugins,
    build: {
      rollupOptions: {
        output: {
          manualChunks(id: string) {
            const module = id.split("/node_modules/")[1];
            if (!module) {
              return; // void
            }
            if (module.match(/^@react-three\/drei\//)) return "drei";
            if (module.match(/^@react-three\/fiber\//)) return "fiber";
            if (module.match(/^@react-three\/rapier\//)) return "rapier";
            if (module.match(/^leva\//)) return "leva";
            if (module.match(/^meshline\//)) return "meshline";
            if (module.match(/^three\//)) return "three";
            return; // void
          },
        },
      },
    },
  }

Now my vendor libraries are correctly split but, but all of the sudden my first paint is now dependent on loading the three (but not the rapier) chunks making first paint incredibly slow. I'm using the vercel 3d tag as an example with asset preloading. The first paint is delayed by 18,000ms in chrome's slow 3G preset

I did try returning a string instead of void in all non-matched returns without an improvement.

screenshots: https://imgur.com/a/BbfO8NT

Reproduction

https://github.com/yspreen/vite-bug-showcase

deployed:
https://vite-bug-no-manual-chunks.pages.dev
https://vite-bug-manual-chunks.pages.dev

Steps to reproduce

install, build and serve both variants of the showcase project.

one of them will show the spinner immediately, the other one only shows the spinner after loading the three.js library

see screenshots: https://imgur.com/a/BbfO8NT

System Info

macOS, latest Chrome

Used Package Manager

yarn

Logs

vite v5.3.3 building for production...

Validations

yspreen avatar Jul 10 '24 18:07 yspreen

this plugin fixed my issue. would be great if I didn't need to add a third party plugin https://github.com/CaptainLiao/vite-plugin-webpackchunkname

yspreen avatar Jul 10 '24 20:07 yspreen

this plugin fixed my issue. would be great if I didn't need to add a third party plugin https://github.com/CaptainLiao/vite-plugin-webpackchunkname

I think this also helped in my case, confirming

long story short: vite module preload code (importAnalysisBuild.ts) gets bundled with (or even: replaces) the react-three/drei/core/Text.tsx code (see [https://github.com/pmndrs/drei/blob/master/src/core/Text.tsx])

sztepen avatar Dec 29 '24 23:12 sztepen

For those who run into this problem, here is a related issue with more details - https://github.com/vitejs/vite/issues/5189

notmedia avatar May 25 '25 20:05 notmedia