Thanks to visit codestin.com
Credit goes to github.com

Skip to content

perf(web,babel-plugin,compiler): merge adjacent sibling templates - #3342

Open
nickshiro wants to merge 1 commit into
solidjs:nextfrom
nickshiro:feat/3055-merge-sibling-templates
Open

perf(web,babel-plugin,compiler): merge adjacent sibling templates#3342
nickshiro wants to merge 1 commit into
solidjs:nextfrom
nickshiro:feat/3055-merge-sibling-templates

Conversation

@nickshiro

Copy link
Copy Markdown

Summary

ref #3055

Merge adjacent fully static DOM elements in a JSX fragment into a single template.

Previously:

<>
  <div>First</div>
  <div>Last</div>
</>

created and cloned two independent templates. It now compiles to a single multi-root template:

  const template = _$template(
    `<div>First</div><div>Last</div>`,
    4
  );

  const view = template();

Implementation

  • Detect maximal runs of adjacent, fully static DOM roots during fragment lowering.

  • Combine those roots into one template while explicitly closing every non-void root.

  • Preserve the external fragment shape by returning the cloned roots as a Node[].

  • Add bit 4 to the internal template() flag:

    • 1: use document.importNode
    • 2: wrapped namespace template
    • 4: multi-root template
  • Flags remain composable, so 5 represents a multi-root template that requires importNode.

  • Keep the existing single-root cloning path unchanged and select the cloning strategy when the factory is created rather than branching for every clone.

  • Implement the same lowering in both the Babel plugin and the native Oxc compiler.

  • Support both generate: "dom" and generate: "dynamic" when the selected renderer is DOM.

The optimization is deliberately limited to safe static runs. Expressions, components, meaningful text, dynamic attributes, effects, refs, spreads, and wrapped SVG/MathML partials break the group. Hydratable
output is unchanged.

Added coverage for:

  • adjacent static fragment roots;
  • groups separated by an expression;
  • dynamic roots remaining independent;
  • adjacent void elements;
  • combined importNode and multi-root flags;
  • preservation of the fragment array shape;
  • cloning each root on every factory call;
  • HTML and SVG namespace preservation;
  • Babel/Oxc output parity.

How did you test this change?

  • Babel plugin: 255 tests passed
  • Native compiler: 5360 tests passed, 28 skipped
  • Rust feature matrix: 141 tests passed
  • Web client: 738 tests passed
  • Web server: 785 tests passed, 2 skipped
  • Web hydration: 168 tests passed
  • Web runtime through both Babel and Oxc: 9 tests passed in each mode
  • Babel typecheck passed
  • Web build and declaration generation passed
  • Full workspace build passed

@changeset-bot

changeset-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 7db338d

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

This PR includes changesets to release 11 packages
Name Type
@solidjs/babel-plugin Patch
@solidjs/compiler Patch
@solidjs/web Patch
test-integration Patch
@solidjs/element Patch
@solidjs/h Patch
@solidjs/html Patch
@solidjs/diagnostics Patch
@solidjs/signals Patch
solid-js Patch
@solidjs/universal 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

@codspeed-hq

codspeed-hq Bot commented Sep 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 151 untouched benchmarks


Comparing nickshiro:feat/3055-merge-sibling-templates (7db338d) with next (fe3ab92)

Open in CodSpeed

@ryansolid

Copy link
Copy Markdown
Member

Quick note on timing so this isn't read as being ignored: this and #3320 are both compiler/runtime-behavior changes carried over from the dom-expressions backlog, and they need a real design-level review rather than a quick pass — the babel plugin and the native compiler have to move together, and the size scenarios will shift. Ryan is prioritizing rc release-stability fixes right now, so these are deliberately queued behind that work. No action needed on your side in the meantime.

Claude via Cursor

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