Closed EvandroLucas closed 1 year ago
This breaks tree shaking; it means that all components need to be available at runtime, I think
This breaks tree shaking; it means that all components need to be available at runtime, I think
Well, I don't know, a bunch of other icon plugins have implemented this functionality and it works quite well.
I'm curious how build tools can handle that without making their bundles huge? Maybe they're more advanced that I thought. I wouldn't expect they would know how to figure out what icons to drop by arbitrary strings.
Well, apparently they do load everything on memory, sometimes. I don't know how Vuetify's v-icon
or BootstrapVue's b-icon
work internally, there's more complexity involved there, but this plugin right here seems to just declare every single icon as an svg in a 30KB file and that's it.
I tried creating my own dynamic component in Vite like:
<script
setup
lang = "ts">
import {computed, defineAsyncComponent} from 'vue'
const iconProps = withDefaults(defineProps<{
name : string
}>(), {
name: null
})
const dynamicIcon = computed(() => {
return defineAsyncComponent(() => {
return import(`../../node_modules/vue-material-design-icons/${iconProps.name}.vue`)
})
})
</script>
<template>
<component
v-bind:is = "dynamicIcon"/>
</template>
White it includes all files in a separate folder based on my Vite config:
it also includes the "paths" of all these files in the index.js
file - which is why the size went to over 1 MB. So bundle size is definitely taking a hit here. Not to mention, my build time rose exponentially too.
Note that, this is how it's working even without the library. I tried using @mdi/svg
directly using vite-svg-loader
. Unless I manually copy the required icons into a separate folder, it will include all the icons in the chunks
folder. That part is fine, but the bundle size increased due to:
... Vite embedding all paths in the JavaScript file. The bundle size is lower in @mdi/svg
than vue-material-design-icons
though.
I got 821 KB without GZip as compared to 1313 KB.
@EvandroLucas 30kb seems like a pointless hit if you're using a single icon, to me 🤷🏻 That icon library isn't particularly big either; MDI would be hundreds if in a single file I think.
@Hrishikesh-K Yeah, isn't this an argument for single components then?
Yup, I think the best way is to manually copy all required SVGs to assets and use a component like I shared above to load the icons that one needs. This is possibly the only way to keep bundle size to the minimum.
Closing this. I don't think anything suggested here is beneficial over slightly more import lines. They all add significant build time (or worse, runtime) slowdowns and complexity.
It's simple
import * as icons from '@mdi/js'
icons[iconName]
icons['mdiEye']
@charleston10 Yeah, but I think in that case you've just imported every single icon into your final build, which will inflate it a lot.
It would be nice if I could do something like:
And have only this
mdi-icon
component imported globally. This helps specially if I need to somehow dynamically change the icon.