Scripts set in manualChunks are loaded directly in front page, instead to be lazy loaded when needed

See original GitHub issue

Describe the bug

To manage well the bundle, I am setting the packages into manualChunks e.g.:

The package fabric is used only in the admin area of my app, that is why I don’t need it to be loaded directly in the front page.

If I don’t set it in manualChunks, it works good and it will not be loaded in the front page, but my chunks then are too large, because vite place it automatically together with others in a huge backend chunk. Then as soon I open the backend it lazy loads all the other chunks, including the one that contains fabric. So this is the expected behavior.

If I set it in manualChunks, e.g.:

    rollupOptions: {
      output: {
        manualChunks: {
          fabric: ['fabric'],
        }
     }
   }

the fabric chunk is loaded directly on the front page. Even if I am not admin.

You can see the differences when I include fabric or not:

Not included in manualChunks image

Included in manualChunks: image

Expected behavior is: fabric should only be loaded when really used, else it creates only network traffic and lowers the Lighthouse score because of unused code!

NOTE: I am using an example with fabric here, but in my project I have a bunch of other libraries that have the same issue with manualChunks.

Reproduction

I created a small reproduction in this repo:

https://github.com/a-tonchev/react-boilerplate/tree/vite_no_lazy_load

Steps to reproduce:

  1. Install deps (yarn)

Try bug:

  1. yarn build && yarn serve
  2. Open localhost:4000 and see in Network -> JS, the fabric script is loaded

To try without, open vite.config.js: https://github.com/a-tonchev/react-boilerplate/blob/vite_no_lazy_load/vite.config.js

and comment out line 40

  1. yarn build && yarn serve
  2. Open localhost:4000 and see in Network -> JS, the fabric script is no more loaded,

System Info

Windows 10 + WSL (Ubuntu)

Vite version "^2.3.8"

Used Package Manager

yarn

Logs

No response

Validations

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:6
  • Comments:14 (4 by maintainers)

github_iconTop GitHub Comments

5reactions
booelleancommented, Dec 1, 2022

I’ve been banging my head against the wall with this error. It appears that returning void like the documentation shows is causing the error. When returning void, Vite will chunk synchronous modules with asynchronous modules, causing the chunk to be preloaded. If you return a default value to catch everything else, then Vite will not do this. Thankfully, that default return value will still pass over asynchronous components you define with defineAsyncComponent, but it will catch everything else, possibly causing large builds. There may be a work around, I’m still playing with a solution.

I also finally found a workaround that allows for custom chunk names similar to webpack’s magic comments. I developed this because the plugin vite-plugin-webpackchunkname was throwing errors. Please note the last line and comment of the example

  manualChunks: (id) => {

      // This is how I do dynamic chunk naming.
      // Example uses:
      // import("some/module/index?chunkName=my-custom-chunk-name")
      // import MyComponent from "some/component.vue?chunkName=restricted_path/my-custom-chunk-name"
      if(id.includes("?chunkName=") || id.includes("&chunkName=")){
          let name = id.match(/(?<=chunkName=)(.*)(?=&)|(?<=chunkName=)(.*)/gm)
          if(name[0]) return name[0];
      }

      // Vendor Chunks
      if(id.includes('node_modules')) return 'vendor';

      // Here's the odd fix. You cannot return void, it must return a string
      return "index";
  },

I’m still cleaning this up and will post updates as it develops. Noteable issues:

  1. Typescript is throwing errors with the query in the url string. It’s possible that Javascript will too.
  2. Chunking does not work if you are importing from a generic package in node_modules. You must import a file. Does not work: “node_module_package_name?chunkName=package” Does work: “node_module_package_name/index?chunkName=package”
2reactions
nicoopratcommented, Apr 5, 2022

No change with Vite 2.9.1 unfortunately, all chunks are still loaded via <link rel="modulepreload" href="xxx"> tags in <head>.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Lazy loading - Web performance | MDN
Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the ......
Read more >
Use lazy loading to improve loading speed - web.dev
Lazy loading is a technique that defers loading of non-critical resources at page load time. Instead, these non-critical resources are loaded ...
Read more >
rollup.js
Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library...
Read more >
Features | Vite
Vite will detect such bare module imports in all served source files and perform the following: Pre-bundle them to improve page loading speed...
Read more >
What is Lazy Loading | Lazy vs. Eager Loading - Imperva
Lazy loading is the practice of delaying load or initialization of resources or objects until they're actually needed to improve performance and save...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found