Search code examples
javascriptvue.jsvuejs3vite

Vitejs is loading the whole bundle size instead of the selected ones


I am using vue 3 with vite. I noticed something strage. Oh vue icons is loading something like 108 MB of bundle size and it takes a lot of time to load even in vitejs. Here's my setup

import { addIcons, OhVueIcon } from 'oh-vue-icons'
import {
  FaFacebookSquare,
  FaInstagram,
  FaLinkedin,
  FaQuora,
  FaTwitter,
  FaYoutube,
} from 'oh-vue-icons/icons'

// register the icons
addIcons(
  FaFacebookSquare,
  FaInstagram,
  FaLinkedin,
  FaQuora,
  FaTwitter,
  FaYoutube
)

const app = createApp(App)
app.component('VIcon', OhVueIcon)
app.mount('#app')

Then in my component:

<VIcon name="fa-facebook-square" />
<VIcon name="fa-youtube" />
<VIcon name="fa-instagram" />
<VIcon name="fa-quora" />
<VIcon name="fa-linkedin" />
<VIcon name="fa-twitter" />

You can see the problem below. I am conditionally controlling these six icons. That's why there are only one or two icons per card.

temp

Why is it loading 108 MB of javascript? That doesn't make any sense. Also I am using vite with vue3. Do I need to add any extra configuration?

Thanks in Advance.


Solution

  • From Vite docs:

    Performance: Vite converts ESM dependencies with many internal modules into a single module to improve subsequent page load performance.

    Some packages ship their ES modules builds as many separate files importing one another. For example, lodash-es has over 600 internal modules! When we do import { debounce } from 'lodash-es', the browser fires off 600+ HTTP requests at the same time! Even though the server has no problem handling them, the large amount of requests create a network congestion on the browser side, causing the page to load noticeably slower.

    By pre-bundling lodash-es into a single module, we now only need one HTTP request instead!

    oh-vue-icons/icons contains many files that Vite is pre-bundling at startup.

    Since you don't really need the icons to be prebundled, you can opt out of the prebundling with optimizeDeps.exclude:

    // vite.config.js
    import { defineConfig } from 'vite'
    
    export default defineConfig({
      ⋮
      optimizeDeps: {
        exclude: ['oh-vue-icons/icons']
      }
    })
    

    demo