Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions benchmark/react/cases/002-hello-reactLynx/RecursiveText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2025 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

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>
)
);
}

export default RecursiveText;
18 changes: 2 additions & 16 deletions benchmark/react/cases/002-hello-reactLynx/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,12 @@

import { root } from '@lynx-js/react';

import RecursiveText from './RecursiveText.js';
import { RunBenchmarkUntilHydrate } from '../../src/RunBenchmarkUntil.js';

function F(props: { text: string }) {
const { text } = props;
const sliced = [...text];
const [first, ...rest] = sliced;

return (
sliced.length > 0 && (
<text>
{first}
<F text={rest.join('')} />
</text>
)
);
}

root.render(
<>
<F text='Hello, ReactLynx 🎉!' />
<RecursiveText text='Hello, ReactLynx 🎉!' />
<RunBenchmarkUntilHydrate />
</>,
);
73 changes: 73 additions & 0 deletions benchmark/react/cases/003-hello-list/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2025 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

import { memo, root, useEffect, useRef, useState } from '@lynx-js/react';
import type { NodesRef } from '@lynx-js/types';

import RecursiveText from '../002-hello-reactLynx/RecursiveText.js';

const MemoedRecursiveText = /* @__PURE__ */ memo(RecursiveText);

function BenchmarkList() {
const [stopBenchmark, setStopBenchmark] = useState(false);
const listRef = useRef<NodesRef>(null);
useEffect(() => {
listRef.current!.invoke({
method: 'scrollToPosition',
params: {
position: 1,
smooth: false,
},
success: function() {
listRef.current!.invoke({
method: 'scrollToPosition',
params: {
position: 2,
smooth: false,
},
success: function() {
setStopBenchmark(true);
},
}).exec();
},
}).exec();
}, []);

return (
<list
custom-list-name={'list-container'}
style={{
height: '100rpx',
width: '500rpx',
backgroundColor: 'red',
}}
ref={listRef}
id={`stop-benchmark-${stopBenchmark}`}
>
{Array.from(
{ length: 5 },
(_, index) => (
<list-item
item-key={`${index}`}
style={{
height: '48rpx',
width: '400rpx',
backgroundColor: 'blue',
}}
>
<text style={{ color: `hsl(${index * 36}, 100%, 50%)` }}>
<MemoedRecursiveText
text={`Hello, ReactLynx 🎉! Index: ${index}`}
/>
</text>
</list-item>
),
)}
</list>
);
}

root.render(
<BenchmarkList />,
);
5 changes: 5 additions & 0 deletions benchmark/react/lynx.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export default defineConfig({
'./src/patchProfile.ts',
'./cases/002-hello-reactLynx/index.tsx',
],
'003-hello-list': [
'./src/patchProfile.ts',
'./src/patchUpdateListCallbacks.ts',
'./cases/003-hello-list/index.tsx',
],
},
},
plugins: [
Expand Down
6 changes: 5 additions & 1 deletion benchmark/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
"bench": "pnpm run --sequential --stream --aggregate-output '/^bench:.*/'",
"bench:001-fib": "benchx_cli run dist/001-fib.lynx.bundle",
"bench:002-hello-reactLynx": "benchx_cli run dist/002-hello-reactLynx.lynx.bundle --wait-for-id=stop-benchmark-true",
"bench:003-hello-list": "benchx_cli run dist/003-hello-list.lynx.bundle --wait-for-id=stop-benchmark-true",
"build": "rspeedy build",
"dev": "rspeedy dev",
"perfetto": "pnpm run --sequential --stream --aggregate-output '/^perfetto:.*/'",
"perfetto:001-fib": "benchx_cli -o dist/001-fib.ptrace run dist/001-fib.lynx.bundle",
"perfetto:002-hello-reactLynx": "benchx_cli -o dist/002-hello-reactLynx.ptrace run dist/002-hello-reactLynx.lynx.bundle --wait-for-id=stop-benchmark-true"
"perfetto:002-hello-reactLynx": "benchx_cli -o dist/002-hello-reactLynx.ptrace run dist/002-hello-reactLynx.lynx.bundle --wait-for-id=stop-benchmark-true",
"perfetto:003-hello-list": "benchx_cli -o dist/003-hello-list.ptrace run dist/003-hello-list.lynx.bundle --wait-for-id=stop-benchmark-true",
"test": "echo 'No tests specified'"
},
"dependencies": {
"@lynx-js/react": "workspace:*",
Expand All @@ -25,6 +28,7 @@
"@lynx-js/qrcode-rsbuild-plugin": "workspace:*",
"@lynx-js/react-rsbuild-plugin": "workspace:*",
"@lynx-js/rspeedy": "workspace:*",
"@lynx-js/type-element-api": "0.0.2",
"@lynx-js/types": "3.4.11",
"@types/react": "^18.3.23"
}
Expand Down
2 changes: 2 additions & 0 deletions benchmark/react/src/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ export function hook<T, K extends keyof T>(
return fn.call(this, oldFn, ...args);
} as T[K];
}

export const PREFIX = __REPO_FILEPATH__.split('/').slice(0, -2).join('/');
3 changes: 1 addition & 2 deletions benchmark/react/src/patchProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

import { hook } from './hook.js';
import { PREFIX, hook } from './hook.js';

const PREFIX = __REPO_FILEPATH__.split('/').slice(0, -2).join('/');
const ignored: Record<string, boolean> = {};
const stack: string[] = [];
let depth = 0;
Expand Down
80 changes: 80 additions & 0 deletions benchmark/react/src/patchUpdateListCallbacks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2025 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

import '@lynx-js/react';
import type { ComponentAtIndexCallback } from '@lynx-js/type-element-api';

import { PREFIX, hook } from './hook.js';

if (typeof Codspeed !== 'undefined' && __MAIN_THREAD__) {
function withCodspeed(
componentAtIndex: ComponentAtIndexCallback,
): ComponentAtIndexCallback {
return (
list,
listID,
cellIndex,
operationID,
enableReuseNotification,
) => {
const ids = __GetChildren(list).map(e => __GetElementUniqueID(e));
Codspeed.startBenchmark();
const sign = componentAtIndex(
list,
listID,
cellIndex,
operationID,
enableReuseNotification,
)!;
Codspeed.stopBenchmark();
Codspeed.setExecutedBenchmark(
`${PREFIX}::${__webpack_chunkname__}-componentAtIndex__${
ids.includes(sign) ? 'reuse' : 'create'
} `,
);

return sign;
};
}

hook(
globalThis,
'__UpdateListCallbacks',
(
old,
list,
componentAtIndex,
enqueueComponent,
componentAtIndexes,
) => {
old!(
list,
withCodspeed(componentAtIndex),
enqueueComponent,
componentAtIndexes,
);
},
);

hook(
globalThis,
'__CreateList',
(
old,
id,
componentAtIndex,
enqueueComponent,
info,
componentAtIndexes,
) => {
return old!(
id,
withCodspeed(componentAtIndex),
enqueueComponent,
info,
componentAtIndexes,
);
},
);
}
2 changes: 1 addition & 1 deletion packages/lynx/benchx_cli/scripts/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ console.log('noop')
}

const COMMIT = 'd6dd806293012c62e5104ad7ed2bed5c66f4f833';
const PICK_COMMIT = '1524ac02060bfc2e354e1865c989bc6f7a9882b1';
const PICK_COMMIT = '78493ae8581046275f6333ce16004666560ce058';

function checkCwd() {
try {
Expand Down
9 changes: 8 additions & 1 deletion packages/lynx/benchx_cli/scripts/prepare.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.

import { copyFileSync, mkdirSync, writeFileSync } from 'node:fs';
import { copyFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';

mkdirSync('./dist/bin', { recursive: true });

if (existsSync('./dist/bin/benchx_cli')) {
// File already exists
// eslint-disable-next-line n/no-process-exit
process.exit(0);
}

if (process.platform === 'win32') {
writeFileSync(
'./dist/bin/benchx_cli',
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading