tabler-icons icon indicating copy to clipboard operation
tabler-icons copied to clipboard

Slow experience in SvelteKit

Open MrAmericanMike opened this issue 1 year ago • 26 comments

I wonder if I'm doing something wrong, but I noticed that page reload is really slow while using @tabler/icons-svelte

I created a repo with the bare minimum example to reproduce the behavior. It's a SvelteKit project using my own starting template in which I add @tabler/icons-svelte and then each page that has some icon on it becomes really slow to refresh.

https://github.com/MrAmericanMike/svelte-tabler-icons-test The readme in this repo has a simple explanation also.

Not sure what the issue could be, I am using @tabler/icons-svelte in a different project that runs as an electron app and haven't noticed this behavior. The differences with that project are many, but I will try to do some experiments. (My first suspect was pnpm but using npm is the same. I'll try to experiment with different versions)

Well anyway I report it here in case anyone wants to take a look or have a clue as to what may be going on.

MrAmericanMike avatar Feb 17 '23 12:02 MrAmericanMike

Ok after some testing and looking for differences among my projects I noticed that having:

export const ssr = true;

in the +layout.js file causes the slow behavior (I need that set to true so @sveltejs/adapter-static can generate a fully static site)

Modifying the value to

export const ssr = false;

makes everything work faster.

I guess that's a workaround as for now, but at the same time not ideal.

Is this something I should report on SvelteKit instead?

Thanks in advance.

MrAmericanMike avatar Feb 17 '23 13:02 MrAmericanMike

I had & still have the same problem with the last deprecated and current version.

ostadomid avatar Feb 21 '23 14:02 ostadomid

I am having the same problem using @tabler/icons-svelte in a SvelteKit project. This happens in dev mode when there is at least one icon in a page.

First time I navigate or refresh a page, it taks ages to load:

13:32:40 [vite-plugin-svelte] prebundle libraries in progress ...
13:34:08 [vite-plugin-svelte] prebundle libraries done.
package   	files	  time	   avg
admin-ui	 3412	50.86s	14.9ms
13:34:08 [vite] ✨ new dependencies optimized: @tabler/icons-svelte

If I remove the icon in that page, restart the process and go to that page again, the load time goes back to normal:

13:36:13 [vite-plugin-svelte] ssr compile in progress ...
13:36:19 [vite-plugin-svelte] ssr compile done.
package   	files	 time	   avg
admin-ui	   23	0.77s	33.6ms

rubenvar avatar Feb 22 '23 12:02 rubenvar

Also experiencing this issue. I thought prebundleSvelteLibraries being enabled by default would have solved this issue but doesn't seem to be the case.

matmoxam avatar Feb 22 '23 14:02 matmoxam

It's a little annoying, but importing the icon .svelte file directly resolves all these issues.

// Instead of
import {IconCheck} from '@tabler/icons-svelte';
// use
import IconCheck from '@tabler/icons-svelte/dist/svelte/icons/IconCheck.svelte';

Still haven't figured out how to fix the types though.

bryanmylee avatar Feb 28 '23 15:02 bryanmylee

I think its a bug in vite. I had the same issue with a icon library for solidjs, where it built all icons, even if i only import one. When i do a release build of my sveltekit app, vite builds all >3000 tabler-icons too.

...
transforming (3354) node_modules/@tabler/icons-svelte/dist/svelte/icons/IconWeight.svelte
...

chjlsch avatar Mar 10 '23 19:03 chjlsch

Not only Sveltekit but any Vite-related project.

I have a project using Astro + svelte, and a package that uses Vite + tabler icons react, and both have the same issue.

I think that's due to the nature of the import itself:

import { IconSomething } from '@tabler/icons-svelte'
                                    ^ "AKA import the whole thing"

raulfdm avatar Mar 15 '23 07:03 raulfdm

Not only Sveltekit but any Vite-related project.

I have a project using Astro + svelte, and a package that uses Vite + tabler icons react, and both have the same issue.

I think that's due to the nature of the import itself:

import { IconSomething } from '@tabler/icons-svelte'
                                    ^ "AKA import the whole thing"

I though that is what the destructuring part was supposed to do so when we do import { IconSomething } Using the curly braces is what tells the (compiler?) that we are only importing that specific icon and not the whole library. (At least that's how I though things work)

MrAmericanMike avatar Mar 15 '23 19:03 MrAmericanMike

I though that is what the destructuring part was supposed to do so when we do import { IconSomething } Using the curly braces is what tells the (compiler?) that we are only importing that specific icon and not the whole library. (At least that's how I though things work)

It's an indication indeed, but it'll depends on how the bundle is created and how vite (in this case), understands and parse it.

I'll try this weekend to run this repository locally and do some experiments but tweaking the rollup configuration, switching to vite, instead and see if it gets any better. Otherwise I'll ask Vite's community some help to see if there's any extra configuration we could do to enable this behaviour.

As @bryanmylee said, the best workaround for now is import the icons from absolute path. By doing this, the compiler knows for sure that only that small bit should be included (and its dependencies).

raulfdm avatar Mar 16 '23 11:03 raulfdm

+1 here.

We are also encountering the same slowness (due to vite rebuilding the entire set of icons on every page reload) when importing via import { IconX } from '@tabler/icons-svelte'. Switching all of our imports to import IconX from '@tabler/icons-svelte/dist/svelte/icons/IconX.svelte' avoids this issue, but we're keen to find a better solution.

radubl avatar Mar 16 '23 16:03 radubl

Hey @codecalm 👋

Do you mind if I do a PoC with some changes on how you're bundling the files? 🤔

My idea is:

  • switch from Rollup to vite, which has a very rich ecosystem and uses Rollup under the hood;
  • changing how the bundle is generated (e.g. single file to multiple files);
  • change from jest to vitest. This is a bit out, but once we have vite in place, we need 0 extra dependencies (such as babel, babel jest, whatever) to run the tests.

My idea isn't to impose any tech but demo how the package bundling process would look in an attempt to fix that problem.

Let me know what you think 😄

raulfdm avatar Mar 16 '23 17:03 raulfdm

for me it's okay, but @SyntaxJoker working on new build process in #556

@SyntaxJoker look at this ideas from @radubl

codecalm avatar Mar 16 '23 17:03 codecalm

In the new build process we will change how the bundle is generated, it should resolve this issue

SyntaxJoker avatar Mar 16 '23 18:03 SyntaxJoker

In the new build process we will change how the bundle is generated, it should resolve this issue

Amazing... really looking forward to it! 🙌

raulfdm avatar Mar 16 '23 18:03 raulfdm

@SyntaxJoker do you have any idea on how long the new build process will take to roll out?

gabrielnvian avatar Mar 17 '23 09:03 gabrielnvian

This log appears to be from a Vite build process that is using the vite-plugin-svelte plugin.

The log shows that the plugin is pre-bundling libraries, which takes approximately 1 minute and 28 seconds to complete. After pre-bundling the libraries, the build process optimizes a new dependency called @tabler/icons-svelte.

The package admin-ui has 3412 files, and it takes approximately 50.86 seconds to process each file, with an average processing time of 14.9 milliseconds per file.

Overall, it seems like the build process is successful, and the dependencies are optimized.

Ebuka636 avatar Apr 02 '23 00:04 Ebuka636

Any updates on this? I am using the deep import in a project and while it works I am not happy with this.

  • No/Insufficient/Wrong Autocomplete
  • Multiple lines of import that could be avoided @SyntaxJoker Can I do something / commit something and help you update the build process?

RealSocius avatar Apr 22 '23 06:04 RealSocius

Hello @codecalm ,

do you have any information about state of this?

PudottaPommin avatar Jun 27 '23 06:06 PudottaPommin

I couldn't wait for it. Moved to https://github.com/antfu/unplugin-icons

anatoliy-t7 avatar Jun 27 '23 09:06 anatoliy-t7

I found a temporary solution to the slow experience in dev mode. It works by rewriting the entry files internally using the plugin "vite-plugin-entry-shaking". I used the following vite.config.ts

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import EntryShakingPlugin from 'vite-plugin-entry-shaking';

export default defineConfig({
	plugins: [
		sveltekit(),
		await EntryShakingPlugin({
			targets: ['@tabler/icons-svelte'],
			extensions: ['svelte'],
		})
	]
});

gooodev avatar Jul 06 '23 00:07 gooodev

Hey @codecalm 👋

Do you mind if I do a PoC with some changes on how you're bundling the files? 🤔

My idea is:

  • switch from Rollup to vite, which has a very rich ecosystem and uses Rollup under the hood;
  • changing how the bundle is generated (e.g. single file to multiple files);
  • change from jest to vitest. This is a bit out, but once we have vite in place, we need 0 extra dependencies (such as babel, babel jest, whatever) to run the tests.

My idea isn't to impose any tech but demo how the package bundling process would look in an attempt to fix that problem.

Let me know what you think 😄

@codecalm I was tracking this issue, and it seems @SyntaxJoker can't finish it... maybe they're busy with something else.

Are you up to my previous proposal? I think I have the bandwidth to enhance the building process and attempt to solve this.

raulfdm avatar Aug 01 '23 18:08 raulfdm

Adding to the discussion. I love the ease of use of this module but the minute-long packaging times really are a nuisance. Let alone the extremely long dev reloads, but @gooodev's solution worked perfectly, so at least that's patched.

MrVauxs avatar Aug 18 '23 21:08 MrVauxs

Instead of changing the build process, you could create a preprocessor like Carbon design did for their icons. Essentially the preprocessor would replace the imports with direct ones.

Example: https://github.com/carbon-design-system/carbon-preprocess-svelte/blob/main/src/preprocessors/optimize-imports.ts

taythebot avatar Aug 22 '23 01:08 taythebot

I really hope this will get fixed sooner or later because this is in my opinion the best icon library to use with SvelteKit. It has pretty much everything you could need and works very well with TypeScript/VSCode auto import. I am using https://github.com/antfu/unplugin-icons as well in the meantime, as the solution proposed by @gooodev does not seem to work at all for me

YummYume avatar Sep 02 '23 19:09 YummYume

Temporary fix :

Set to this version in package.json :

"@tabler/icons-svelte": "2.30.0",

MarArMar avatar Feb 23 '24 18:02 MarArMar

I think worth mentioning that this problem seems to be related only to the @tabler/icons-svelte package in conjunction with a Vite setup and not necessarily bound to SveteltKit, but Vite + @tabler/icons-svelte.

To test this, you can do the following:

  1. create a vite - react project
  2. add @tabler/icons-react
  3. Named import an icon to the main page
  4. run build

You'll see the build is relatively fast, and in the final bundle, it included only the Icon we've imported.

Now if you do this with Svelte:

  1. create a vite - svelte project
  2. add @tabler/icons-svelte
  3. Named import an icon to the main page
  4. run build

The build will take longer, and all icons will be included in the final bundle.

raulfdm avatar Mar 10 '24 08:03 raulfdm