Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make an icon component specifically for tree shaking #475

Open
jpengelbrecht opened this issue Sep 4, 2023 · 8 comments
Open

make an icon component specifically for tree shaking #475

jpengelbrecht opened this issue Sep 4, 2023 · 8 comments

Comments

@jpengelbrecht
Copy link

jpengelbrecht commented Sep 4, 2023

fontawesome-svg-core/index.mjs comes in at a whooping 60.187 KiB . so if i am using the treeshaking method by importing the icons i need and using the "@fortawesome/vue-fontawesome" component the display component makes up about 3% of my entire bundle size. i would imagine if you make a sleeker version that is only made for explicitly passing through the imported icon as a prop we can do away with a lot of the logic bulking up this component

@jasonlundien
Copy link
Member

jasonlundien commented Sep 5, 2023

@jpengelbrecht ---

make a sleeker version that is only made for explicitly passing through the imported icon as a prop

Do you have a repo where you have done this, a PR, or some code perhaps that I could see/review on this ?

@jpengelbrecht
Copy link
Author

I don't have a repo for this no. but using this method, https://fontawesome.com/docs/apis/javascript/tree-shaking
essentially you already have the icon. I am just saying that import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; is huge for something you only need to pass a prefetched icon

@jasonlundien
Copy link
Member

jasonlundien commented Sep 5, 2023

@jpengelbrecht ---

I think I get what you are saying then...

So currently to use the Font Awesome icons in vue we do have to import FontAwesomeIcon:
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

This allows us to use icons in our vue components:
<font-awesome-icon icon="fa-solid fa-user-secret" />

But we also need to import icons or at least 1 icon (via tree shaking):
import { faUserSecret } from '@fortawesome/free-solid-svg-icons'

So how do we still use Font Awesome icons without importing the FontAwesomeIcon component:
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

I think that is what you are questioning/asking?

@jpengelbrecht
Copy link
Author

@jasonlundien exactly. you can still use
<font-awesome-icon class="push-icon-2" :icon="faUserSecret" />
however it I think some of the components bulk comes from having to support this as well
<font-awesome-icon icon="fa-solid fa-user-secret" /> so maybe a specific component for tree shaking might be a lot skinner if that makes sense?

@WhyNotHugo
Copy link

I've measured the size of my bundle.

Without any font-awesome:

assets/product-variant-selector-9e4e1ee7.js            1.97 kB │ gzip:  0.94 kB

Merely registering the component like this

import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
Vue.component('font-awesome-icon', FontAwesomeIcon)

Increases the bundle size:

assets/product-variant-selector-392a0bd2.js           70.75 kB │ gzip: 19.95 kB

Adding the library itself

import { library } from '@fortawesome/fontawesome-svg-core'
library.add()

This has almost no impact in bundle size:

assets/product-variant-selector-30f78efb.js           70.77 kB │ gzip: 19.97 kB

Importing a single icon

And finally, importing a single icon seems to only increase the bundle every so slightly:

import { faShoppingBasket } from '@fortawesome/free-solid-svg-icons'
library.add(faShoppingBasket)
assets/product-variant-selector-4e0332cb.js           71.43 kB │ gzip: 20.28 kB

I'm really not sure what's happening when importing the FontAwesomeIcon type. I suspect that some unnecessary files are getting pulled in too. But the component with a single icon end up representing 97% of my bundle size.

@robmadole
Copy link
Member

Hello @WhyNotHugo we have some docs on using the plugin system to pick-n-choose features:

https://fontawesome.com/docs/apis/javascript/plugins

This helps to reduce size but it may not get the bundle size down as small as you would like. It's worth a look though!

@WhyNotHugo
Copy link

My main issue is that each script ends up bundling the same component, so each output script jumps in size by 60kB just by using a single icon.

I've managed to somewhat improve the situation by making sure that Vite puts the icon component into its own file, and different pages will just load the same one (this will often be a cache hit, so it'll only be loaded once).

I just added this into rollupOptions.output invite.config.js:

output: {
  manualChunks: {"fa": ["@fortawesome/vue-fontawesome"]},
}

Bundle sizes:

product-variant-selector-b281f8f7.js              2.72 kB │ gzip:   1.30 kB
fa-e8ca04d2.js                                   68.76 kB │ gzip:  19.11 kB

@WhyNotHugo
Copy link

Thanks, @robmadole, but that seems to only reduce the size of the core svg bundle. What's really bumping my modules size is this specific bit:

import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

In order to reduce the size of that one, I think I'd need my own build of the Vue component, which depends on my own build of svg-core as described in https://fontawesome.com/docs/apis/javascript/plugins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants