svelte
svelte copied to clipboard
chore: micro-optimizations to reduce generated bundle size
Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with
[feat]
,[fix]
,[chore]
, or[docs]
. - [x] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.
Tests
- [x] Run the tests with
npm test
and lint the project withnpm run lint
Re-work of #5702. But this time without optimizations that make the code less readable.
This PR refactors some parts of the codebase to use shared functionality instead of rewriting the same code block over and over again.
code | branch | bundle size | gzipped size |
---|---|---|---|
vite starter example | master | 5.330 bytes | 2.475 bytes |
vite starter example | optimizations (originally with {} ) |
5.266 bytes | 2.464 bytes |
vite starter example | optimizations (with Object.create(null) ) |
5.310 bytes | 2.475 bytes |
empty Svelte file | master | 3.260 bytes | 1.557 bytes |
empty Svelte file | optimizations (originally with {} ) |
3.198 bytes | 1.542 bytes |
empty Svelte file | optimizations (with Object.create(null) ) |
3.240 bytes | 1.554 bytes |
Tests are failing with following error: ReferenceError: HTMLElement is not defined
edited
Is this whole if
block just to make the tests pass? Or is there also another reason behind it?
https://github.com/sveltejs/svelte/pull/7703/files#diff-da9bae4e28c441de5ba3a074e30775fe69109100b3d921ad8f2592d93cd67b7fR180
Note that Object.create(null)
is not the same as {}
: https://stackoverflow.com/questions/15518328/is-creating-js-object-with-object-createnull-the-same-as
Note that
Object.create(null)
is not the same as{}
: stackoverflow.com/questions/15518328/is-creating-js-object-with-object-createnull-the-same-as
TIL. I wasn't aware of that difference. Thanks for posting the SO link!
I have updated the size chart above. The bundle size is 20 bytes less then the current master branch. Not that much, but something ^^.
By using {}
instead of Object.create(null)
it could be reduced even further. I stumbled across this blog post from 2017 and it seems that the raw {}
is more performant. A quick test in on my machine came to similar results.
Any reason why Object.create(null)
was chosen? Is it really needed to get rid of the prototype chain?
(Changing it will probably not have a big impact on performance since it doesn't get called a few thousand times to really feel the difference)
@ivanhofer would you be able to fix the merge conflict on this PR? We're trying to get as many outstanding PRs merged as we can in the coming weeks. Thanks!
It's hard to tell because we have no benchmarks testing these things, but how much difference does it make to have all these "is function" calls behind one more function? Also !Object.length
is probably slower than ... === 0
.
It's hard to tell because we have no benchmarks testing these things, but how much difference does it make to have all these "is function" calls behind one more function? Also
!Object.length
is probably slower than... === 0
.
The is_function
call seems to be exactly as performant as the direct usage: https://jsbench.me/ailefztu9k
Same goes for the !Object.length
vs. .length === 0
calls: https://jsbench.me/xzleg06cir
Maybe I test it wrong, please tell me If did a mistake.
@ivanhofer is attempting to deploy a commit to the Svelte Team on Vercel.
A member of the Team first needs to authorize it.
I'm done resolving the merge conflicts.
I'm giving this the "one day" label because I don't feel confident merging this without having a benchmarking setup in place (which we want to have soon). The microbenchmarks I ran had typeof function
inlined very slightly ahead.
Closing this since Svelte 5 will have reduced bundle size optimizations