Skip to content

fix(ssr): massive compiled outputs when nested slots are present#5379

Merged
divmain merged 17 commits intomasterfrom
divmain/W-18501805
Jun 3, 2025
Merged

fix(ssr): massive compiled outputs when nested slots are present#5379
divmain merged 17 commits intomasterfrom
divmain/W-18501805

Conversation

@divmain
Copy link
Contributor

@divmain divmain commented May 28, 2025

Details

The problem: It was observed that certain templates, when compiled in SSRv2, resulted in massive compiled outputs. There was no functional issue - the generated code worked properly - but sometimes the SSRv2 bundles would be 100x the size of SSRv1 bundles.

It was determined that this related to how we generate code when nesting many layers of slots. After arriving at a reduced repro (like the example template provided below), it became clear that the interplay of shadow-slot functions and light-slot functions results in a O(2^n) space complexity, where each new layer of nesting doubles the number of functions that are generated related to those slots.

The solution: There was not an easy way to fix this; this PR contains my third attempt. The semantics of LWC shadow and light slots simply make the problem very difficult to ameliorate. However, while the approach in this PR does add some new complexity, it successfully avoids the massive compiled outputs that we were seeing before.

The short explanation is that the shadow-slot-content functions require less contextual information compared to the light-slot-content functions. Therefore, it is possible to hoist these shadow-slot functions to the top of the template function, defining them once rather than defining them repeatedly at each layer of nesting. This short-circuits the exponential output sizes, resulting in roughly linear growth rather than exponential.

Example template

<template lwc:render-mode="light">
    <x-ancient-one>
        <x-great-grandparent>
            <x-grandparent>
                <x-parent slot="grandparentSlot">
                    <x-child slot="parentSlot">
                        <x-grandchild slot="childSlot">
                            <x-zygote>
                                <x-nascent>
                                    <div id="test"></div>
                                </x-nascent>
                            </x-zygote>
                        </x-grandchild>
                    </x-child>
                </x-parent>
            </x-grandparent>
        </x-great-grandparent>
    </x-ancient-one>
</template>

Output sizes, before and after

The following table demonstrates the compiled output sizes, both before (on master branch) and after (on this branch) as a function of levels of nesting. The example provided above has eight levels of nesting; for the rows in this table representing fewer levels of nesting, one or more levels of nesting were commented out from the template before compiling, e.g. <x-nascent> and </x-nascent> were commented out for 7 layers of nesting.

levels of nesting before after
0 1,984 1,984
1 4,320 4,149
2 9,177 7,582
3 19,538 12,352
4 41,941 18,587
5 89,798 26,341
6 192,385 35,876
7 406,964 46,962
8 861,801 59,903

The difference becomes quite dramatic as increased nesting occurs. As one might expect based on the O(2^n) size complexity described from the original implementation, the size of the SSR-compiled-outputs on master branch roughly doubles (plus change) with every additional layer of nesting added.

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.

Does this pull request introduce an observable change?

  • 🤞 No, it does not introduce an observable change.

GUS work item

W-18501805

@divmain divmain marked this pull request as ready for review May 28, 2025 06:37
@divmain divmain requested a review from a team as a code owner May 28, 2025 06:37
Copy link
Contributor

@wjhsf wjhsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

divmain and others added 2 commits June 2, 2025 12:45
Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com>
Co-authored-by: Will Harney <62956339+wjhsf@users.noreply.github.com>
@divmain divmain force-pushed the divmain/W-18501805 branch from 025b1de to af2815f Compare June 3, 2025 22:23
@divmain divmain enabled auto-merge (squash) June 3, 2025 22:47
@divmain divmain merged commit 32770e5 into master Jun 3, 2025
6 checks passed
@divmain divmain deleted the divmain/W-18501805 branch June 3, 2025 22:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants