Closed mheinzerling closed 4 months ago
I think the first thing to do here is to isolate SSR + hydration from just purely client side rendering, i.e. disabling SSR entirely. Also Lighthouse doesn't really do any justice here as it's just giving scores, it would be far more helpful to use the dev tools in Chrome to record a startup trace in the performance tab – as this can also indicate where the time is being spent.
Also are you testing DEV or prod here?
Also are you testing DEV or prod here?
Both. Build is PROD and Dev ist DEV. I added dev just for reference.
I think the first thing to do here is to isolate SSR + hydration from just purely client side rendering, i.e. disabling SSR entirely.
This is plain Svelte, not SvelteKit. I was under the impression that there is no SSR. Otherwise, how can I disable it?
Also Lighthouse doesn't really do any justice here as it's just giving scores, it would be far more helpful to use the dev tools in Chrome to record a startup trace in the performance tab – as this can also indicate where the time is being spent.
The numbers are actually not the scores, but the details some clicks deeper :) Nevertheless they are obviously just a starting point, but they are a reliable way the get reproducible numbers between the different runs and versions.
I guess you are faster if you just check the linked sample at your own? But I could also export some profiles - the tabs are still open.
Ah thanks for that. I checked out your github repo and see these results from the perf trace on DEV:
Svelte 4:
Svelte 5:
I'm using Chrome v124 on an M2 MacBook Pro.
Yes, as I mention, DEV is only for reference and Svelte 4 is really slow for me, too.
For prod:
Svelte 5:
Svelte 4:
I don't see anything here that stands out as problematic?
I do see this in Svelte 5, which doesn't look like something Svelte 5 has in its runtime:
This is what is adding the majority of the overhead vs Svelte 4 by the looks of it.
That is from vite's "modulepreload" helper afaik, it should be in both if you're using the same bundler unless the css modes are different maybe.
@gtm-nayan It is in both, it just seems to majorly affect Svelte 5 compared to Svelte 4. Not sure why.
Interestingly, avoiding using document fragments internally from doing this:
<div class="card">
{#each {length: 50000} as _}
<div>
<Counter/>
</div>
{/each}
</div>
Has a noticeable impact on performance for Svelte 5.
Hmm could it be the templates are triggering MutationObserver or making it do some unnecessary checks somehow?
@gtm-nayan You're on to something:
Svelte 5 logs of DOM mutations:
(2) [MutationRecord, MutationRecord]
Svelte 4 logs of DOM mutations:
(200019) [MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, MutationRecord, …]
Ah maybe it's not that on reflection. It seems we early return and don't add the mutation observer at all.
Can you update to the latest version of Svelte 5? This should include some improvements.
The sample seems to get slightly faster in DEV mode between next.131 and next.132: 575ms vs. 644ms. In PROD mode this is similar 308ms vs 358ms. Although this looks like a 10% improvement, we should take it with a grain of salt, as this is from my work PC and no isolated environment.
For my original code I started recreating my measurements, as this was still next.123 and the results are not that impressive.
version | run | parse html/css | script evaluation |
---|---|---|---|
next.123 PROD | 1 | 8.862 | 2.217 |
next.123 PROD | 2 | 8.222 | 2.020 |
next.123 PROD | 3 | 8.689 | 2.189 |
next.131 PROD | 1 | 8.525 | 2.220 |
next.131 PROD | 2 | 8.576 | 2.182 |
next.131 PROD | 3 | 8.431 | 2.165 |
next.132 PROD | 1 | 8.398 | 2.136 |
next.132 PROD | 2 | 8.403 | 2.140 |
next.132 PROD | 3 | 8.403 | 2.153 |
I guess my sample was not good/specific enough. I will try to create a new one later this week. In the meantime please find attached a profile from my original page load.
@mheinzerling Yeah I think we need a better example. For me Svelte 5 is faster in script time and parse html/css time than Svelte 4.
Which browsers (including version) are you both testing on? Is this a possible cause for the difference?
I'm running on Chrome v124.
Chrome Version 124.0.6367.118
@mheinzerling I'm not sure what more we can action in regard to this without more information or data.
Sorry, currently I have no time to continue here. Feel free to close the ticket, and I might create a follow-up later.
Describe the bug
By accident I created a document in Svelte 4 with 130000 DOM Elements. Essentially I'm converting a large JSON test report into a HTML structure, mapping the data to ~20 components for the test classes, with each having ~5 methods and each having again ~3 steps and finally each having a grid with up to 4100 Divs. So there are in general 4 different Svelte components. I'm totally aware that this is just wrong, and they should not be rendered all on initial load. Nevertheless, out of curiosity, I converted this project to Svelte 5 and for reference also to Vue.
Lighthouse results - original
The script execution time doubles in Svelte 5 and the HTML parsing and CSS is even worst.
At least for the script execution, I see a similar factor in my minimal reproducable example. I just used the initial template projects and added the counter 50000. I guess for reproducing the HTML performance the example needs to be extended by more complex templates. Due the simplicity I might have also lost other details that add the to execution time, but as the factor is pretty close to my original performance the examples seems to be good enough.
Lighthouse results - sample
Reproduction
https://github.com/mheinzerling/svelte11576
Logs
No response
System Info
Severity
blocking an upgrade