svelte icon indicating copy to clipboard operation
svelte copied to clipboard

perf: inline default imports into template

Open benmccann opened this issue 1 year ago • 1 comments

https://github.com/sveltejs/svelte/pull/13075 reduced the size of the compiled output on my site quite a lot. However, there are still hundreds of lines (~8kb) of output remaining created as the result of referencing a pair of imported SVGs that can be removed from my site by also inlining imports with this PR

benmccann avatar Sep 13 '24 21:09 benmccann

🦋 Changeset detected

Latest commit: 84d1cfb2b27885692c880d37511a0267f97ae2a6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Sep 13 '24 21:09 changeset-bot[bot]

Technically this is unsafe. There's nothing special about default imports that makes them non-live, it's purely about the way that they're conventionally exported. When you do something like this...

export default foo;

...you're effectively declaring a hidden variable and exporting that as the default:

const __default = foo;
export { __default as default };

Since __default is initialized to the current value of foo and never subsequently updated, it doesn't change when foo changes. But you could equally do this, and it would be live:

export { foo as default };

The consequence is that when you see import foo from './foo.js' you can usually expect that it's not a live binding. But you can't guarantee it. As such, I'm nervous about making this change.

Rich-Harris avatar Sep 16 '24 03:09 Rich-Harris

hmm. yeah. I'm glad we have your arcane knowledge of JS because I had no idea that was a thing

I'll try to solve this on the Vite side then: https://github.com/vitejs/vite/issues/18119

benmccann avatar Sep 16 '24 17:09 benmccann

Realised we couldn't do this even if we didn't have to worry about live bindings — this button won't be enabled on hydration, because the button.disabled = server is moved into the template (which is disregarded during hydration):

<script>
  import server from './is-server.js';
</script>

<button disabled={server}>
  {server ? "can't click me yet" : 'click me!'}
</button>

The text is updated, but you still can't click the button.

Rich-Harris avatar Sep 16 '24 18:09 Rich-Harris