Skip to content

ci(benchmark/react): add benchmark for various attribute update#1650

Merged
hzy merged 1 commit intolynx-family:mainfrom
hzy:p/hzy/bench_5
Sep 4, 2025
Merged

ci(benchmark/react): add benchmark for various attribute update#1650
hzy merged 1 commit intolynx-family:mainfrom
hzy:p/hzy/bench_5

Conversation

@hzy
Copy link
Copy Markdown
Collaborator

@hzy hzy commented Sep 3, 2025

Summary by CodeRabbit

  • New Features

    • Added a new React benchmark case that exercises a variety of attribute updates with runtime timing, enabling more granular performance insights.
    • Introduced dedicated scripts to run and profile this benchmark case for quicker benchmarking and trace capture.
  • Chores

    • Updated benchmark configuration to register the new case in the build and run pipeline.
    • Exposed utilities for determining execution context to support benchmark behavior across environments.

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).

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Sep 3, 2025

⚠️ No Changeset found

Latest commit: dcb2fcd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 3, 2025

📝 Walkthrough

Walkthrough

Adds a new React benchmark case (004-various-update) that instruments SnapshotInstance.setAttribute for named keys to record Codspeed benchmarks, renders a component exercising various attribute updates and spreads, and integrates the case into build/config via lynx.config.js, package scripts, and exports new helpers (PREFIX, isMainThread) in hook.ts.

Changes

Cohort / File(s) Summary
New benchmark case & instrumentation
benchmark/react/cases/004-various-update/index.tsx
Introduces runtime hook to wrap SnapshotInstance.setAttribute for specific keys, recording Codspeed benchmarks with repo/chunk identifiers; implements a React test component that updates diverse attributes (direct and spread), toggles state, and renders list-item examples; mounts the component.
Build/config integration
benchmark/react/lynx.config.js, benchmark/react/package.json
Adds entry point for 004-various-update in lynx.config.js; adds scripts for running and profiling the new case in package.json.
Benchmark helpers
benchmark/react/src/hook.ts
Exports new constants: PREFIX (derived from REPO_FILEPATH) and isMainThread (boolean via typeof __CreatePage). No change to existing hook behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • upupming
  • colinaaa

Poem

A rabbit taps keys with careful delight,
Timing each twinkle of attributes’ light.
Benchmarks hop in, start… stop—neat!
Spreads and styles line up in a beat.
With PREFIX in paw and threads in sight,
I thump “004!”—the numbers feel right. 🥕⏱️

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link
Copy Markdown

codecov Bot commented Sep 3, 2025

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!

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Sep 3, 2025

Web Explorer

#4825 Bundle Size — 367.43KiB (0%).

dcb2fcd(current) vs f454292 main#4823(baseline)

Bundle metrics  Change 1 change
                 Current
#4825
     Baseline
#4823
No change  Initial JS 144.23KiB 144.23KiB
No change  Initial CSS 31.84KiB 31.84KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 8 8
No change  Assets 8 8
Change  Modules 219(+0.46%) 218
No change  Duplicate Modules 16 16
No change  Duplicate Code 3.33% 3.33%
No change  Packages 4 4
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#4825
     Baseline
#4823
No change  JS 235.43KiB 235.43KiB
No change  Other 100.16KiB 100.16KiB
No change  CSS 31.84KiB 31.84KiB

Bundle analysis reportBranch hzy:p/hzy/bench_5Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented Sep 3, 2025

React Example

#4834 Bundle Size — 237.5KiB (0%).

dcb2fcd(current) vs f454292 main#4832(baseline)

Bundle metrics  no changes
                 Current
#4834
     Baseline
#4832
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 160 160
No change  Duplicate Modules 65 65
No change  Duplicate Code 45.83% 45.83%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#4834
     Baseline
#4832
No change  IMG 145.76KiB 145.76KiB
No change  Other 91.74KiB 91.74KiB

Bundle analysis reportBranch hzy:p/hzy/bench_5Project dashboard


Generated by RelativeCIDocumentationReport issue

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Sep 3, 2025

CodSpeed Performance Report

Merging #1650 will not alter performance

Comparing hzy:p/hzy/bench_5 (f790d5d) with main (af2d59b)

Summary

✅ 20 untouched benchmarks
🆕 22 new benchmarks

Benchmarks breakdown

Benchmark BASE HEAD Change
🆕 004-various-update__main-thread-setAttribute__Attr N/A 36.4 µs N/A
🆕 004-various-update__main-thread-setAttribute__BatchedValues N/A 776.8 µs N/A
🆕 004-various-update__main-thread-setAttribute__Class N/A 36.1 µs N/A
🆕 004-various-update__main-thread-setAttribute__Dataset N/A 33.3 µs N/A
🆕 004-various-update__main-thread-setAttribute__Id N/A 35.3 µs N/A
🆕 004-various-update__main-thread-setAttribute__ListItemPlatformInfo N/A 111.1 µs N/A
🆕 004-various-update__main-thread-setAttribute__ListItemPlatformInfoSpread N/A 94.3 µs N/A
🆕 004-various-update__main-thread-setAttribute__MT_Event N/A 96.2 µs N/A
🆕 004-various-update__main-thread-setAttribute__MT_Ref N/A 110.8 µs N/A
🆕 004-various-update__main-thread-setAttribute__Spread N/A 354.4 µs N/A
🆕 004-various-update__main-thread-setAttribute__StyleObject N/A 98.3 µs N/A
🆕 004-various-update__main-thread-setAttribute__StyleString N/A 33 µs N/A
🆕 004-various-update__main-thread-setAttribute__TimingFlag N/A 72.8 µs N/A
🆕 003-hello-list-destroyBackground N/A 2.5 ms N/A
🆕 003-hello-list-hydrate N/A 8.2 ms N/A
🆕 003-hello-list-renderBackground N/A 18.4 ms N/A
🆕 003-hello-list__main-thread-componentAtIndex__create N/A 5.2 ms N/A
🆕 003-hello-list__main-thread-componentAtIndex__reuse N/A 3.1 ms N/A
🆕 003-hello-list__main-thread-processData N/A 22.4 µs N/A
🆕 003-hello-list__main-thread-renderMainThread N/A 15.2 ms N/A
... ... ... ... ...

ℹ️ Only the first 20 benchmarks are displayed. Go to the app to view all benchmarks.

@hzy hzy force-pushed the p/hzy/bench_5 branch 3 times, most recently from aef6f47 to f790d5d Compare September 3, 2025 09:16
@hzy hzy marked this pull request as ready for review September 3, 2025 12:53
Copilot AI review requested due to automatic review settings September 3, 2025 12:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds benchmark infrastructure for ReactLynx, including benchmarks for list rendering and attribute updates. The changes enhance the benchmarking capabilities to measure performance of different ReactLynx operations.

Key Changes

  • Added benchmarks for list operations and attribute updates
  • Refactored existing benchmark code by extracting reusable components
  • Enhanced build preparation scripts to avoid unnecessary rebuilds

Reviewed Changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/lynx/benchx_cli/scripts/prepare.mjs Added early exit optimization when build artifacts already exist
packages/lynx/benchx_cli/scripts/build.mjs Updated commit hash reference for build process
benchmark/react/src/patchUpdateListCallbacks.ts New file implementing Codspeed benchmarks for list callback operations
benchmark/react/src/patchProfile.ts Updated to use shared PREFIX constant from hook module
benchmark/react/src/hook.ts Added shared constants and utilities for benchmarking
benchmark/react/package.json Added new benchmark scripts and dependencies for list and attribute update tests
benchmark/react/lynx.config.js Added entry points for new benchmark cases
benchmark/react/cases/004-various-update/index.tsx New benchmark testing various attribute update operations
benchmark/react/cases/003-hello-list/index.tsx New benchmark testing list rendering and scrolling operations
benchmark/react/cases/002-hello-reactLynx/index.tsx Refactored to use extracted RecursiveText component
benchmark/react/cases/002-hello-reactLynx/RecursiveText.tsx Extracted reusable RecursiveText component from main benchmark
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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.

Actionable comments posted: 5

🧹 Nitpick comments (17)
benchmark/react/package.json (2)

10-11: Bench scripts should build before running to avoid missing dist bundles

Add a prebench step so CI/dev never runs against stale/missing bundles.

   "scripts": {
+    "prebench": "pnpm build",
     "bench": "pnpm run --sequential --stream --aggregate-output '/^bench:.*/'",

16-19: Perfetto runs should also build first

Mirror the bench change for perfetto to ensure bundles exist.

   "scripts": {
+    "preperfetto": "pnpm build",
     "perfetto": "pnpm run --sequential --stream --aggregate-output '/^perfetto:.*/'",
packages/lynx/benchx_cli/scripts/build.mjs (1)

100-102: Optional: make cherry-pick fetch more robust

Fetching a bare SHA can be flaky across mirrors. Consider fetching to FETCH_HEAD explicitly and cherry-picking that.

-git fetch hzy ${PICK_COMMIT}
-git cherry-pick -n ${PICK_COMMIT}
+git fetch hzy ${PICK_COMMIT}
+git cherry-pick -n FETCH_HEAD
benchmark/react/src/hook.ts (1)

18-22: Avoid // @ts-expect-error and normalize path separators

Declare ambient globals instead of suppressing, and normalize backslashes for safety.

+declare const __REPO_FILEPATH__: string;
+declare const __CreatePage: unknown;
-export const PREFIX = __REPO_FILEPATH__.split('/').slice(0, -2).join('/');
+export const PREFIX = __REPO_FILEPATH__.replace(/\\/g, '/').split('/').slice(0, -2).join('/');
-
-export const isMainThread =
-  // @ts-expect-error safely check
-  typeof __CreatePage === 'function';
+export const isMainThread = typeof __CreatePage === 'function';
packages/lynx/benchx_cli/scripts/prepare.mjs (1)

15-26: Ensure executable bit on non-Windows stubs

Set +x to avoid edge cases where copied file loses exec perms in some filesystems.

-import { copyFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
+import { copyFileSync, existsSync, mkdirSync, writeFileSync, chmodSync } from 'node:fs';
@@
 } else {
   copyFileSync('/usr/bin/true', './dist/bin/benchx_cli');
+  try { chmodSync('./dist/bin/benchx_cli', 0o755); } catch {}
 }
benchmark/react/cases/002-hello-reactLynx/RecursiveText.tsx (1)

5-18: Avoid O(n^2) string joins in recursion; keep nested structure

Joining the remainder each step reallocates the string repeatedly. Use index-based recursion over a precomputed char array; same DOM shape, better perf.

-function RecursiveText(props: { text: string }) {
-  const { text } = props;
-  const sliced = [...text];
-  const [first, ...rest] = sliced;
-
-  return (
-    sliced.length > 0 && (
-      <text>
-        {first}
-        <RecursiveText text={rest.join('')} />
-      </text>
-    )
-  );
-}
+function RecursiveText(props: { text: string }) {
+  const chars = [...props.text];
+  function R(i: number): JSX.Element | null {
+    if (i >= chars.length) return null;
+    return (
+      <text>
+        {chars[i]}
+        {R(i + 1)}
+      </text>
+    );
+  }
+  return R(0);
+}
benchmark/react/lynx.config.js (3)

35-42: Ensure 004-various-update is instrumented if you want Codspeed stats.

003 wires patchProfile.ts (and list-callback patch). 004 currently doesn’t include patchProfile.ts, so Codspeed.setExecutedBenchmark from patchProfile won’t run for that entry.

If 004 should be profiled similarly, add patchProfile:

 '004-various-update': [
-  './cases/004-various-update/index.tsx',
+  './src/patchProfile.ts',
+  './cases/004-various-update/index.tsx',
 ],

12-23: Minify flags are contradictory.

output.minify.js is true but jsOptions.minify is false. This is confusing and may lead to unexpected output.

Consider dropping one to reflect intended behavior.


24-43: Changeset reminder for CI.

Per prior repo learnings, CI may require a changeset when “src/**” is touched—even for internal tooling—often satisfied via an empty changeset file. This PR adds files under benchmark/react/src.

I used your stored learnings. If CI complains, I can generate a minimal empty changeset entry.

benchmark/react/src/patchProfile.ts (1)

36-41: Gate noisy console logs.

The nested-benchmark console.log can spam CI logs. Consider guarding behind a debug flag.

-        console.log(
+        if (process.env.LYNX_BENCH_DEBUG) console.log(
benchmark/react/cases/003-hello-list/index.tsx (2)

16-35: Harden scroll invoke with error/complete handling.

If the first invoke fails, we’ll never flip stopBenchmark. Add fail/complete handlers to keep the run bounded.

-    listRef.current!.invoke({
+    listRef.current!.invoke({
       method: 'scrollToPosition',
       params: { position: 1, smooth: false },
-      success: function() {
+      success: function() {
         listRef.current!.invoke({
           method: 'scrollToPosition',
           params: { position: 2, smooth: false },
-          success: function() {
+          success: function() {
             setStopBenchmark(true);
           },
+          fail: function() { setStopBenchmark(true); },
+          complete: function() { /* optional: metrics */ },
         }).exec();
       },
+      fail: function() { setStopBenchmark(true); },
+      complete: function() { /* optional: metrics */ },
     }).exec();

Confirm the exact callback names (e.g., fail/complete) for NodesRef.invoke in your runtime; adjust accordingly.


48-66: Add React keys to mapped children to avoid warnings.

item-key is consumed by Lynx, but React still benefits from a key prop for reconciliation.

-          <list-item
+          <list-item
+            key={index}
             item-key={`${index}`}
benchmark/react/src/patchUpdateListCallbacks.ts (1)

41-58: Guard against missing componentAtIndex when hooking.

Be defensive if componentAtIndex is undefined/null.

-      old!(
+      old!(
         list,
-        withCodspeed(componentAtIndex),
+        componentAtIndex ? withCodspeed(componentAtIndex) : componentAtIndex,
         enqueueComponent,
         componentAtIndexes,
       );
benchmark/react/cases/004-various-update/index.tsx (4)

9-15: Make the patch idempotent to prevent double-hooking under HMR/re-imports.

Guard the prototype patch with a Symbol flag.

Apply this diff:

-import { hook, isMainThread } from '../../src/hook.js';
+import { hook, isMainThread } from '../../src/hook.js';

-if (__MAIN_THREAD__) {
+const PATCH_FLAG = Symbol.for('lynx.bench.setAttribute.patched');
+if (__MAIN_THREAD__ && !(PATCH_FLAG in SnapshotInstance.prototype)) {
+  Object.defineProperty(SnapshotInstance.prototype, PATCH_FLAG, { value: true });
   hook(
     SnapshotInstance.prototype,
     'setAttribute',
     function(this: SnapshotInstance, old, key, value) {

21-68: Replace the long switch with a fast lookup to reduce overhead in the hot path.

Keeps the hook lightweight and easier to maintain.

Apply this diff (includes a small table and the in-function replacement):

@@
-import { hook, isMainThread } from '../../src/hook.js';
+import { hook, isMainThread } from '../../src/hook.js';
+
+const KEY_NAMES = [
+  'Attr',                    // 0
+  'Dataset',                 // 1
+  'Event',                   // 2
+  'MT_Event',                // 3
+  'StyleString',             // 4
+  'StyleObject',             // 5
+  'Class',                   // 6
+  'Id',                      // 7
+  'Ref',                     // 8
+  'TimingFlag',              // 9
+  'MT_Ref',                  // 10
+  'ListItemPlatformInfo',    // 11
+  'ListItemPlatformInfoSpread', // 12
+  'Spread',                  // 13
+] as const;
@@
-      let name = '';
-      switch (key) {
-        case 0:
-          name = 'Attr';
-          break;
-        case 1:
-          name = 'Dataset';
-          break;
-        case 2:
-          name = 'Event';
-          break;
-        case 3:
-          name = 'MT_Event';
-          break;
-        case 4:
-          name = 'StyleString';
-          break;
-        case 5:
-          name = 'StyleObject';
-          break;
-        case 6:
-          name = 'Class';
-          break;
-        case 7:
-          name = 'Id';
-          break;
-        case 8:
-          name = 'Ref';
-          break;
-        case 9:
-          name = 'TimingFlag';
-          break;
-        case 10:
-          name = 'MT_Ref';
-          break;
-        case 11:
-          name = 'ListItemPlatformInfo';
-          break;
-        case 12:
-          name = 'ListItemPlatformInfoSpread';
-          break;
-        case 13:
-          name = 'Spread';
-          break;
-        case 'values':
-          name = 'BatchedValues';
-          break;
-      }
+      const name =
+        typeof key === 'number'
+          ? (KEY_NAMES[key as number] ?? '')
+          : (key === 'values' ? 'BatchedValues' : '');

114-138: Preserve the tuple type on setValues to avoid accidental widening.

Minor type-safety improvement; no runtime impact.

Apply this diff:

-    setValues([
+    setValues([
       'some-other-exposure-id',
       'some-other-dataset',
       () => {},
       () => {
         'main thread';
       },
       'width: 200rpx; height: 100rpx; background-color: #FACE00;',
       {
         width: '200rpx',
         height: '100rpx',
         backgroundColor: '#FACE00',
       },
       'some-other-css-class',
       'some-other-id',
       (_e: NodesRef) => {},
       'some_other_lynx_timing_flag',
       (_e: MainThread.Element) => {
         'main thread';
       },
       'some-other-item-key',
-    ]);
+    ] as const);

11-85: Optional: avoid double-counting nested calls (e.g., when key === 'values').

If you want only the outer “BatchedValues” to be timed/recorded, gate start/stop with a simple depth counter.

Example patch (conceptual; integrate with the earlier try/finally):

+let benchDepth = 0;
@@
-      Codspeed.startBenchmark();
+      const outer = benchDepth++ === 0;
+      if (outer) Codspeed.startBenchmark();
       try {
         return old!.call(this, key, value);
       } finally {
-        Codspeed.stopBenchmark();
-        Codspeed.setExecutedBenchmark(
-          `${__REPO_FILEPATH__}::${__webpack_chunkname__}-setAttribute__${name}`,
-        );
+        if (--benchDepth === 0) {
+          Codspeed.stopBenchmark();
+          Codspeed.setExecutedBenchmark(
+            `${__REPO_FILEPATH__}::${__webpack_chunkname__}-setAttribute__${name}`,
+          );
+        }
       }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between af2d59b and f790d5d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • benchmark/react/cases/002-hello-reactLynx/RecursiveText.tsx (1 hunks)
  • benchmark/react/cases/002-hello-reactLynx/index.tsx (1 hunks)
  • benchmark/react/cases/003-hello-list/index.tsx (1 hunks)
  • benchmark/react/cases/004-various-update/index.tsx (1 hunks)
  • benchmark/react/lynx.config.js (1 hunks)
  • benchmark/react/package.json (2 hunks)
  • benchmark/react/src/hook.ts (1 hunks)
  • benchmark/react/src/patchProfile.ts (1 hunks)
  • benchmark/react/src/patchUpdateListCallbacks.ts (1 hunks)
  • packages/lynx/benchx_cli/scripts/build.mjs (1 hunks)
  • packages/lynx/benchx_cli/scripts/prepare.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-08-12T16:09:32.413Z
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1497
File: packages/react/transform/tests/__swc_snapshots__/src/swc_plugin_snapshot/mod.rs/basic_full_static.js:9-10
Timestamp: 2025-08-12T16:09:32.413Z
Learning: In the Lynx stack, functions prefixed with `__` that are called in transformed code may be injected globally by the Lynx Engine at runtime rather than exported from the React runtime package. For example, `__CreateFrame` is injected globally by the Lynx Engine, not exported from lynx-js/react.

Applied to files:

  • benchmark/react/src/patchUpdateListCallbacks.ts
📚 Learning: 2025-07-22T09:26:16.722Z
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:26:16.722Z
Learning: In the lynx-family/lynx-stack repository, CI checks require changesets when files matching the pattern "src/**" are modified (as configured in .changeset/config.json). For internal changes that don't need meaningful changesets, an empty changeset file is used to satisfy the CI requirement while not generating any release notes.

Applied to files:

  • benchmark/react/lynx.config.js
📚 Learning: 2025-07-22T09:23:07.797Z
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1330
File: .changeset/olive-animals-attend.md:1-3
Timestamp: 2025-07-22T09:23:07.797Z
Learning: In the lynx-family/lynx-stack repository, changesets are only required for meaningful changes to end-users such as bugfixes and features. Internal/development changes like chores, refactoring, or removing debug info do not need changeset entries.

Applied to files:

  • benchmark/react/lynx.config.js
📚 Learning: 2025-08-27T08:10:09.932Z
Learnt from: colinaaa
PR: lynx-family/lynx-stack#1612
File: packages/rspeedy/create-rspeedy/template-react-vitest-rltl-ts/src/tsconfig.json:3-13
Timestamp: 2025-08-27T08:10:09.932Z
Learning: In the lynx-family/lynx-stack repository, Rspeedy templates use `lynx-js/rspeedy/client` types via `rspeedy-env.d.ts` instead of `vite/client` types. Rspeedy provides its own client-side environment type definitions and doesn't require direct Vite type references.

Applied to files:

  • benchmark/react/package.json
🧬 Code graph analysis (2)
benchmark/react/src/patchUpdateListCallbacks.ts (3)
packages/web-platform/web-constants/src/types/Element.ts (1)
  • ComponentAtIndexCallback (22-28)
packages/web-platform/web-mainthread-apis/src/pureElementPAPIs.ts (1)
  • __GetChildren (73-75)
benchmark/react/src/hook.ts (2)
  • PREFIX (18-18)
  • hook (5-16)
benchmark/react/cases/004-various-update/index.tsx (1)
benchmark/react/src/hook.ts (2)
  • hook (5-16)
  • isMainThread (20-22)
🔇 Additional comments (9)
benchmark/react/package.json (1)

33-33: No changes needed: @lynx-js/type-element-api is only imported via import type (erased at compile time) and isn’t required at runtime, so leaving it as a devDependency is appropriate.

packages/lynx/benchx_cli/scripts/prepare.mjs (1)

5-13: Good idempotency guard

Early-exit on existing binary prevents redundant work in CI/local.

benchmark/react/cases/002-hello-reactLynx/index.tsx (1)

7-13: Good extraction to a reusable RecursiveText component.

This removes duplication and keeps 002 aligned with 003’s usage.

benchmark/react/src/patchProfile.ts (1)

5-5: Good: centralizing PREFIX import.

Using the shared PREFIX from hook.js keeps labels consistent across patches.

benchmark/react/src/patchUpdateListCallbacks.ts (2)

10-10: No action needed: __MAIN_THREAD__ is already declared globally.
The ambient declaration exists in packages/react/runtime/types/types.d.ts (line 20).


5-6: Confirm ComponentAtIndexCallback returns void in both upstream definitions
Both local definitions in web-constants and React’s runtime types declare the callback as returning void, so your import from @lynx-js/type-element-api aligns with the upstream signature and won’t produce unexpected undefined at runtime.

benchmark/react/cases/004-various-update/index.tsx (3)

140-142: Main-thread short-circuit is correct for this bench.

Avoids rendering on the patched thread; matches the hook placement.


166-176: Good coverage of spread vs. explicit props for list-item/view.

This should exercise keys 11/12 and 13 distinctly.

Also applies to: 178-195


1-205: Ensure global macros exist and hook is unique.

  • Ambient typings in benchmark/**/*.d.ts declare Codspeed and __REPO_FILEPATH__, but not __MAIN_THREAD__ or __webpack_chunkname__—confirm your build tooling injects those.
  • Only one hook(SnapshotInstance.prototype, 'setAttribute', …) call is present under benchmark/** (no duplicates).

Comment thread benchmark/react/cases/002-hello-reactLynx/index.tsx
Comment thread benchmark/react/cases/004-various-update/index.tsx
Comment thread benchmark/react/cases/004-various-update/index.tsx
Comment thread benchmark/react/src/patchUpdateListCallbacks.ts
Comment thread packages/lynx/benchx_cli/scripts/build.mjs
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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
benchmark/react/src/hook.ts (2)

20-22: Avoid @ts-expect-error by using globalThis for the probe.
Removes brittle expect-error while keeping behavior.

-export const isMainThread =
-  // @ts-expect-error safely check
-  typeof __CreatePage === 'function';
+export const isMainThread =
+  typeof (globalThis as any).__CreatePage === 'function';

18-18: Normalize and type-assert REPO_FILEPATH in src/hook.ts
In src/hook.ts, update to:

-export const PREFIX = __REPO_FILEPATH__.split('/').slice(0, -2).join('/');
+export const PREFIX = (__REPO_FILEPATH__ as string)
+  .replace(/\\/g, '/')
+  .split('/')
+  .slice(0, -2)
+  .join('/');

Global __REPO_FILEPATH__ is already declared in benchmark/react/rspeedy-env.d.ts, so no new ambient declaration is needed.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f790d5d and dcb2fcd.

📒 Files selected for processing (4)
  • benchmark/react/cases/004-various-update/index.tsx (1 hunks)
  • benchmark/react/lynx.config.js (1 hunks)
  • benchmark/react/package.json (1 hunks)
  • benchmark/react/src/hook.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • benchmark/react/lynx.config.js
  • benchmark/react/cases/004-various-update/index.tsx
🔇 Additional comments (1)
benchmark/react/package.json (1)

18-18: Perfetto script aligns with prior cases.
Consistent naming and flags.

Comment thread benchmark/react/package.json
Comment thread benchmark/react/cases/004-various-update/index.tsx
Comment thread benchmark/react/cases/004-various-update/index.tsx
@hzy hzy enabled auto-merge (squash) September 4, 2025 02:48
@hzy hzy merged commit 9e2c497 into lynx-family:main Sep 4, 2025
44 of 46 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Mar 27, 2026
3 tasks
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.

4 participants