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

feat(icon): provide splitte icon files for Vue.js #1417

Open
pinguet62 opened this issue Apr 14, 2023 · 5 comments
Open

feat(icon): provide splitte icon files for Vue.js #1417

pinguet62 opened this issue Apr 14, 2023 · 5 comments
Assignees
Labels
🎯 next Anything related to the next major version 🚀 feat A new feature

Comments

@pinguet62
Copy link
Contributor

I want to propose an evolution/improvement on

Icon set

Description

Naming convension

Currently all icons are listed in icon/js/icon.js file, where each couple of name/size has constant name with convension {name}{size} 👍
ℹ️ Name comes from catalog

Problem

In JS, the solution to load 1 icon is to load the entire file, and filter constantes following previous convension.
It's not a good practice regarding application loading: the bundle file is very big (>1Mo 😨)

SVG files

A solution is to load directly SVG from /icons/svg/*.svg.
But the problem is filename doesn't respect the previous convension: they have different prefix.

Describe the solution you would like

Create new folder, specifically for Vue.js, will create another one more name for an icon.
And there are already too many cases: icon name ≠ React/vue name ≠ Web Component name ≠ Svg file name ...

So in my opinion, rename icons to follow the same convension is the best solution 👍

Describe the alternatives you considered

No response

Additional comments

⚠️ There is a difference between inline SVG in icons/js/icons.js who declare the size attribute, and icons/svg/*.svg who don't declare this size attribute.

@pinguet62 pinguet62 added the 🚀 feat A new feature label Apr 14, 2023
@pinguet62
Copy link
Contributor Author

@tiloyi pour les icones et SVG :

<component :is="icon" />
const iconName = computed(() => `Device_${props.name}_${props.size}px`);

⚠️ C'est ici que le préfix sur le filename du SVG pose soucis

Version directe :

const icon = defineAsyncComponent(() => {
  return import(`/node_modules/@mozaic-ds/icons/svg/${iconName.value}.svg`);
});

Version "distionnaire" :

const modules = import.meta.glob('/node_modules/@mozaic-ds/icons/svg/*.svg')
const icon = defineAsyncComponent(async () => {
  const moduleName = `/node_modules/@mozaic-ds/icons/svg/${iconName.value}.svg`
  return await modules[moduleName]()
});

⚠️ Nécessite vite-svg-loader, mais à mon avis il y aurait moyen de s'en passer en chargeant dynamiquement les modules différemment ou en affichant le <component différement

@pinguet62
Copy link
Contributor Author

pinguet62 commented May 5, 2023

⚠️ Nécessite vite-svg-loader, mais à mon avis il y aurait moyen de s'en passer en chargeant dynamiquement les modules différemment ou en affichant le <component différement

Je suis bête, je l'avais fait sans plugin :

<template>
  <img :src="svg"/>
</template>
import {onBeforeMount, ref} from 'vue'

const props = defineProps({
  svgFile: {
    type: String,
    required: true,
  },
  // native attributes
  alt: String,
})

const svg = ref<string>();

onBeforeMount(async () => {
  const svgModuleFactories = import.meta.glob('/node_modules/@mozaic-ds/icons/svg/*.svg')
  const svgModuleFactory = svgModuleFactories[`/node_modules/@mozaic-ds/icons/svg/${props.svgFile}`]
  const svgModule = await svgModuleFactory() as { default: string }
  svg.value = svgModule.default
})

@mohamedMok mohamedMok self-assigned this May 11, 2023
@pinguet62
Copy link
Contributor Author

pinguet62 commented Jul 5, 2023

https://github.com/adeo/pricely/tree/main/sspm-front/src/mozaic/MIcon
✅ tree shaking
✅ pas de plugin supplémentaire
✅ 0 breaking change

ℹ️ serait idéal : harmoniser les noms d'icone entre fichiers SVG, Vue.js, WebComponents, React

@anthony-melique
Copy link

Hello,
je viens de tester cette solution avec un composant de test et à priori, il y a encore un surpoids significatif, même le gain est déjà très appréciable.

Voici les différents chiffres obtenu lors de mes tests :

Sans icônes dans l'application (54kB) :
image

Avec le composant MIcon original (1169 kB) :
image

Avec cette solution (261 kB) :
image

Est ce que tu remarque le même genre de chiffre ?

@pinguet62
Copy link
Contributor Author

pinguet62 commented Jul 24, 2023

Effectivement j'ai également un surplus de 200kB :

  • en important MIcon cela rajoute 200kB au fichier l'incluant
  • "surplus", """entre guillemet""", est relatif : avant c'était >1Mo :trollface:

Si je ne dis pas de bêtise :

  • cela correspond à la "base" du composant MIcon : il ne fait pas 0 ligne de code
  • tout de même 200kB : il stocke le dictionnaire associatif entre le nom de l'icone et le fichier .js à importer

Sachant qu'il y a 1441 icones : c'est cohérent 👍
Et ça, à part n'utiliser qu'1 seul SVG pour toutes les tailles (plutôt qu'1 par taille) il n'y a pas réellement de solution !

@mohamedMok mohamedMok linked a pull request Dec 4, 2023 that will close this issue
4 tasks
@tiloyi tiloyi added the 🎯 next Anything related to the next major version label Feb 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎯 next Anything related to the next major version 🚀 feat A new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants