Skip to content

refactor: create element without ref for suspense in main thread#2426

Merged
HuJean merged 2 commits intomainfrom
p/suspense-mainthread
Apr 7, 2026
Merged

refactor: create element without ref for suspense in main thread#2426
HuJean merged 2 commits intomainfrom
p/suspense-mainthread

Conversation

@HuJean
Copy link
Copy Markdown
Collaborator

@HuJean HuJean commented Apr 7, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Updated Suspense component to optimize element reference handling on the main thread.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

@HuJean HuJean requested review from Yradex and hzy as code owners April 7, 2026 03:03
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 7, 2026

🦋 Changeset detected

Latest commit: 1faef9f

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

This PR includes changesets to release 2 packages
Name Type
@lynx-js/react Patch
@lynx-js/react-umd 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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Walkthrough

This PR introduces a patch-level change to the @lynx-js/react package that makes the Suspense component conditionally handle the ref prop based on the __MAIN_THREAD__ flag. When running on the main thread, the ref prop is omitted from the wrapper VNode; on background threads, the ref is preserved for tracking element state.

Changes

Cohort / File(s) Summary
Changeset
.changeset/legal-zebras-sit.md
New changelog entry documenting patch-level behavior change for Suspense ref handling on main thread.
Suspense Implementation
packages/react/runtime/src/lynx/suspense.ts
Modified ref prop assignment to be conditional on __MAIN_THREAD__ flag for both children and fallback wrapper VNodes, suppressing ref callbacks when running on main thread.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

framework:React

Suggested reviewers

  • Yradex
  • hzy

Poem

🐰 A rabbit threads through the main and background lanes,
Conditionally dropping refs like rain on the plains,
Suspense now knows where to hold on tight,
And when to let go—what a beautiful sight! 🌿

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: conditionally omitting the ref prop when creating Suspense elements on the main thread, which is the core modification across both the changeset and the implementation file.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch p/suspense-mainthread

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/react/runtime/src/lynx/suspense.ts (1)

21-47: Please add regression tests for thread-gated Suspense wrapper refs.

Given the split behavior between main/background threads, add targeted tests to lock this contract and prevent ref-related regressions in future refactors.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react/runtime/src/lynx/suspense.ts` around lines 21 - 47, Add
regression tests that assert the thread-gated ref contract around the Suspense
wrapper implemented via __createElement: when __MAIN_THREAD__ is false the
wrapper should attach refs (verify childrenRef.current becomes a
BackgroundSnapshotInstance after rendering and that
globalBackgroundSnapshotInstancesToRemove is updated/cleared when newFallback's
ref runs), and when __MAIN_THREAD__ is true no ref callbacks should be invoked.
Create tests that toggle __MAIN_THREAD__, render the Suspense wrapper that uses
newChildren and newFallback (or import the Suspense wrapper behavior), simulate
mounting of children then fallback to trigger the ref callbacks, and assert
childrenRef mutations and globalBackgroundSnapshotInstancesToRemove changes to
lock this behavior against regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/react/runtime/src/lynx/suspense.ts`:
- Around line 21-47: Add regression tests that assert the thread-gated ref
contract around the Suspense wrapper implemented via __createElement: when
__MAIN_THREAD__ is false the wrapper should attach refs (verify
childrenRef.current becomes a BackgroundSnapshotInstance after rendering and
that globalBackgroundSnapshotInstancesToRemove is updated/cleared when
newFallback's ref runs), and when __MAIN_THREAD__ is true no ref callbacks
should be invoked. Create tests that toggle __MAIN_THREAD__, render the Suspense
wrapper that uses newChildren and newFallback (or import the Suspense wrapper
behavior), simulate mounting of children then fallback to trigger the ref
callbacks, and assert childrenRef mutations and
globalBackgroundSnapshotInstancesToRemove changes to lock this behavior against
regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a2a4c4f8-61c3-4962-ab57-a9972058c943

📥 Commits

Reviewing files that changed from the base of the PR and between 55602e2 and 8e504f2.

📒 Files selected for processing (2)
  • .changeset/legal-zebras-sit.md
  • packages/react/runtime/src/lynx/suspense.ts

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Apr 7, 2026

Merging this PR will improve performance by 17.23%

⚡ 1 improved benchmark
✅ 71 untouched benchmarks
⏩ 21 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 47.3 ms 40.4 ms +17.23%

Comparing p/suspense-mainthread (1faef9f) with main (a822afc)2

Open in CodSpeed

Footnotes

  1. 21 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (8c0e483) during the generation of this report, so a822afc was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@relativeci
Copy link
Copy Markdown

relativeci bot commented Apr 7, 2026

React External

#213 Bundle Size — 591.38KiB (-0.02%).

1faef9f(current) vs a822afc main#212(baseline)

Bundle metrics  Change 1 change
                 Current
#213
     Baseline
#212
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 31.04% 31.03%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Improvement 1 improvement
                 Current
#213
     Baseline
#212
Improvement  Other 591.38KiB (-0.02%) 591.5KiB

Bundle analysis reportBranch p/suspense-mainthreadProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci bot commented Apr 7, 2026

Web Explorer

#8669 Bundle Size — 728.84KiB (0%).

1faef9f(current) vs a822afc main#8668(baseline)

Bundle metrics  no changes
                 Current
#8669
     Baseline
#8668
No change  Initial JS 43.31KiB 43.31KiB
No change  Initial CSS 2.16KiB 2.16KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 8 8
No change  Assets 10 10
No change  Modules 149 149
No change  Duplicate Modules 11 11
No change  Duplicate Code 34.69% 34.69%
No change  Packages 3 3
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#8669
     Baseline
#8668
No change  Other 384.62KiB 384.62KiB
No change  JS 342.07KiB 342.07KiB
No change  CSS 2.16KiB 2.16KiB

Bundle analysis reportBranch p/suspense-mainthreadProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci bot commented Apr 7, 2026

React Example

#7094 Bundle Size — 237.68KiB (0%).

1faef9f(current) vs a822afc main#7093(baseline)

Bundle metrics  no changes
                 Current
#7094
     Baseline
#7093
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 0% 38.71%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 179 179
No change  Duplicate Modules 70 70
No change  Duplicate Code 46.12% 46.12%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#7094
     Baseline
#7093
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.92KiB 91.92KiB

Bundle analysis reportBranch p/suspense-mainthreadProject dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci bot commented Apr 7, 2026

React MTF Example

#227 Bundle Size — 207.26KiB (0%).

1faef9f(current) vs a822afc main#226(baseline)

Bundle metrics  Change 1 change
                 Current
#227
     Baseline
#226
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 0% 46.36%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 173 173
No change  Duplicate Modules 67 67
Change  Duplicate Code 45.78%(-0.02%) 45.79%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#227
     Baseline
#226
No change  IMG 111.23KiB 111.23KiB
No change  Other 96.03KiB 96.03KiB

Bundle analysis reportBranch p/suspense-mainthreadProject dashboard


Generated by RelativeCIDocumentationReport issue

@HuJean HuJean enabled auto-merge (squash) April 7, 2026 06:12
@HuJean HuJean merged commit 9d3e6e3 into main Apr 7, 2026
59 of 61 checks passed
@HuJean HuJean deleted the p/suspense-mainthread branch April 7, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants