BEST way to handle ICONS in your VITE APPS!

Sdílet
Vložit
  • čas přidán 1. 06. 2024
  • Today we go over the best way to handle icons in any web application project built on top of Vite.
    This works for React, Vue, Svelte, you name it. As long as it's in Vite it works and it cuts your bundle size by up to 99%
    🔗 Resources and Links:
    GitHub Repo: github.com/AlemTuzlak/remix-e...
    Jacob Paris article: www.jacobparis.com/content/sv...
    Package Repo: github.com/forge42dev/vite-pl...
    👍 Don't forget to like, comment, and subscribe for more episodes in this series! Join our coding community and let's build something amazing together.
    📌 Stay Connected:
    Twitter: / alemtuzlak
    GitHub: github.com/AlemTuzlak
    Company Github: github.com/forge42dev
    ⏱️ Timestamps:
    00:00 - Intro
    00:20 - How it works
    01:41 - Why the JSX approach is horrible and why we use this one
    03:42 - How it works
    03:51 - The package that we use
    03:58 - Setting it up
    04:17 - Going over the manual approach
    05:39 - Modifying the vite.config.ts
    07:03 - Seeing the plugin in action
    08:27 - Preloading the icon
    08:49 - The final result
    09:47 - Final thoughts
    10:09 - Outro
    🔖 Tags:
    Remix framework, Vite, Remix Vite, web development, frontend development, Remix tutorial, coding tutorial, Remix Vite tutorial, open source, coding community, Vue, Angular, icons, spritesheet, bundle size, Vite

Komentáře • 31

  • @rand0mtv660
    @rand0mtv660 Před 17 dny +5

    I've been using SVG sprites for years now and for the last couple of years I've had a custom Node script in my projects that does everything you described here. It looks in a folder, creates an SVG sprite from SVGs in that folder, outputs an SVG sprite and creates TS types. It only doesn't have watch mode, but it also isn't tied to any special build process like Vite for example. It's definitely nice you created this plugin so that others can benefit from this approach.
    Regarding size, sprite will definitely increase if you have 50+ or 100+ icons in your SVG sprite for some larger project, but the nice thing about it is that it's a file that can be cached by browsers. If you don't update your icons for months, that sprite will still be cached in user's browser so loading it is faster and cache won't be busted on each JS change in the project because icons aren't in JS code.
    Where JSX icons have an advantage is if you are publishing a library that needs to be consumed in React projects. Then it's easier to distribute and consume them since they are "just" components.

    • @alemtuzlak
      @alemtuzlak  Před 16 dny +1

      Thank you for the detailed explanation, it's really appreciated! These are all valid and correct points! Yeah you can actually migrate this out to a script yes, the article I linked to has the manual script in it which you can run, probably looks similar to what you have, I use this across all my projects so I decided to move it out for easier use!

    • @rand0mtv660
      @rand0mtv660 Před 16 dny

      @@alemtuzlak yeah if you use Vite all the time, makes sense to have it as a plugin. It also has watch mode which I do have to say is pretty nice.

    • @alemtuzlak
      @alemtuzlak  Před 16 dny

      @@rand0mtv660 yeah watch mode is really great when you have to work with custom icons, but then again this could be built with a custom script and ran as a parallel process along your main one though so it's not like it's impossible to build outside of Vite, or even hard to do on that matter.
      I heavily use Vite in all projects so yeah, this way i can just pop it in everywhere.
      Plus I've added a few new improvements since the video to it, and plan to add stuff like minifcation and optimizations of svgs down the line.

    • @rand0mtv660
      @rand0mtv660 Před 16 dny

      @@alemtuzlak yeah a separate process can be started, but this is just way more conventient in my opinion.

  • @shmulimargulies5462
    @shmulimargulies5462 Před 18 dny +1

    Awesome stuff, glad to see you are back. Can't wait to see what else you have in store for us

    • @alemtuzlak
      @alemtuzlak  Před 18 dny +1

      Thank you so much 🙏, new video should be up tomorrow!

  • @hodev632
    @hodev632 Před 12 dny +2

    It's a very old method . I remember doing this 10 years ago . I think react icons package only bundle ones you are using as i remember

    • @hodev632
      @hodev632 Před 12 dny +1

      It had this problem, but they fixed it,i believe

    • @alemtuzlak
      @alemtuzlak  Před 11 dny

      Yeah I think it somehoe got lost over the years and a lot of people started using JSX along the way

  • @proMehedi
    @proMehedi Před 19 dny

    Very helpful. Thanks for sharing

  • @bambooch749
    @bambooch749 Před 15 dny

    Great work!

  • @florianmatz1885
    @florianmatz1885 Před 13 dny

    Oldie but goodie :) - reminds me of the early 2000‘s were gradients were put into sprites. For icons I currently prefer using a suspense / lazy pattern as you only load exact the icon you need instead of the complete set as mentioned in one of the first comments.

    • @alemtuzlak
      @alemtuzlak  Před 13 dny

      Yeah this can be a drawback, but the good thing about the approach is that it's easier to cache and preload it so in theory it would not even matter if it's all icons together because they would be pulled from a xache anyway

    • @florianmatz1885
      @florianmatz1885 Před 13 dny +1

      @@alemtuzlak Yes, fair point. But that also is true for lazy loaded, chunked icons, where one icon equals one cachable chunk. But as always, there are multiple suitable solutions and I like your approach as well!

    • @alemtuzlak
      @alemtuzlak  Před 13 dny

      @@florianmatz1885 yeah, that's also true, as for everything in development, there's no silver bullet! Thank you for watching it's really appreciated 🙂

  • @Kopetefish
    @Kopetefish Před 15 dny +3

    Doesn’t this also mean that a page showing only one icon will take longer to render the icon because it needs to load the other 749 icons of the other pages?

    • @alemtuzlak
      @alemtuzlak  Před 15 dny

      Depends on how you set it up, you could have multiple outputs and split your icons, but the neat thing with this is that you can output it to your public directory and cache it on a CDN and preload it on the page, opposed to having jsx

    • @LtdJorge
      @LtdJorge Před 9 dny +1

      Yeah, the biggest benefit here is that caching one "icon" caches all of them. So the first is the slowest, but after that they're all cached.

  • @pokefreak2112
    @pokefreak2112 Před 5 dny

    What exactly is this "svg as jsx" method doing to include unused icons? Is it like an import * as Icon from 'icons' or something?
    I don't think any serious project doing this. From what I've seen older projects usually use icon fonts while newer projects import individual icons as SVG so all the unused icons get stripped.
    I seriously doubt that this spritesheet method is much better than an optimized icon font _or_ the regular svg method, if it's even better at all.
    The linked tweet points out how big the bundle is, but it doesn't mention the gzipped size. Usually dumber copy-paste code = better compression than code that is cleverly optimized to save bytes.

    • @alemtuzlak
      @alemtuzlak  Před 4 dny

      Optimized icon font I'm not really sure about tbh. probably the same approach as this one in theory. The biggest issue is the compiled code I believe that baloons the JSX output to a very big size. Also, a big issue is that a lot of people use 3rd party npm icon packages which bundle their whole icons package even if you import just 1. Lucide for example bundles like 300kb if you use it, at least the last time I checked, not sure if they fixed it. But you get the point. There's no silver bullet here

  • @MiDonGo
    @MiDonGo Před 18 dny

    Fantastic series. I made a sprite sheet and am testing adding tailwindcss to the icons. I'm having trouble adding theme color changes to them. After I figure that I out, I was going to try to animate them. Here is my css for a logo. It shows default black but does not switch to white when I switch to dark theme.

    • @MiDonGo
      @MiDonGo Před 17 dny

      Playing around with other icons in case it was the logo svg I loaded. None of the icons take fill color changes in tailwind. Not sure how to apply style changes.

    • @rand0mtv660
      @rand0mtv660 Před 17 dny +2

      @@MiDonGo your svg might have fill/color/stroke baked into its markup and that's why setting it using CSS doesn't work. It basically has inline styles set that way.
      For single color icons, easiest way is to set fill/color property to have value "currentColor". This is a special CSS value that will inherit the color from "color" property set on the element itself or any parent. So this way you can just set text-black in order to color the icon and don't have to worry about fill and target fill property with "fill-black" if your fill property on SVG is using currentColor.
      At 5:00 you can see his SVG has currentColor set on stroke property.

    • @MiDonGo
      @MiDonGo Před 17 dny +2

      @@rand0mtv660 thanks for the help. Yes, that was exactly the problem. I had to go in and edit the svg code. Which lead to me optimizing the data path to trim more of the fat. So glad you ran across my reply. Thank you. 🙏

    • @rand0mtv660
      @rand0mtv660 Před 17 dny +1

      @@MiDonGo yeah no worries. Glad I could help.

    • @alemtuzlak
      @alemtuzlak  Před 16 dny +1

      Thank you so much! Took me a while to get to the comment and I see your problem has already been fixed, whenever you're handling icons as svgs you should make sure that it doesn't have fixed colors, I always search for fill and stroke properties and see if they can be removed, in most cases they can but in some complex icons that's not the case and it's required, eg you need to have a fixed color on a heart or osmething like that. It's a bit of a trial and error but you get good at it after a while.

  • @user-lt8fj8ef9n
    @user-lt8fj8ef9n Před 19 dny +1

    👍👍