Skip to content

Commit 8fa8059

Browse files
author
Shi Shu
committed
Move code over
1 parent acbf08b commit 8fa8059

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

src/ink.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export type Options = {
2727
debug: boolean;
2828
exitOnCtrlC: boolean;
2929
patchConsole: boolean;
30+
onRender?: (renderTime: number) => void;
3031
isScreenReaderEnabled?: boolean;
3132
waitUntilExit?: () => Promise<void>;
3233
maxFps?: number;
@@ -280,12 +281,17 @@ export default class Ink {
280281
</AccessibilityContext.Provider>
281282
);
282283

284+
const start = Date.now();
283285
// @ts-expect-error the types for `react-reconciler` are not up to date with the library.
284286
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
285287
reconciler.updateContainerSync(tree, this.container, null, noop);
286288
// @ts-expect-error the types for `react-reconciler` are not up to date with the library.
287289
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
288290
reconciler.flushSyncWork();
291+
if (this.options.onRender) {
292+
const end = Date.now();
293+
this.options.onRender(end - start);
294+
}
289295
}
290296

291297
writeToStdout(data: string): void {

src/render.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ export type RenderOptions = {
4242
*/
4343
patchConsole?: boolean;
4444

45+
/**
46+
Function to call after each render.
47+
*/
48+
onRender?: (renderTime: number) => void;
49+
4550
/**
4651
Enable screen reader support. See https://github.com/vadimdemedes/ink/blob/master/readme.md#screen-reader-support
4752

test/render.tsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as path from 'node:path';
44
import {createRequire} from 'node:module';
55
import FakeTimers from '@sinonjs/fake-timers';
66
import test from 'ava';
7-
import React from 'react';
7+
import React, {useEffect} from 'react';
88
import ansiEscapes from 'ansi-escapes';
99
import stripAnsi from 'strip-ansi';
1010
import boxen from 'boxen';
@@ -273,3 +273,48 @@ test.serial('throttle renders to maxFps', t => {
273273
clock.uninstall();
274274
}
275275
});
276+
277+
test.serial('outputs renderTime when onRender is passed', t => {
278+
const clock = FakeTimers.install(); // Controls timers + Date.now()
279+
let lastRenderTime = -1;
280+
let tickTime = 100;
281+
282+
const onRender = (renderTime: number) => {
283+
lastRenderTime = renderTime;
284+
};
285+
286+
function Nested() {
287+
clock.tick(tickTime);
288+
return <Text>Nested</Text>;
289+
}
290+
291+
function Test() {
292+
useEffect(() => {
293+
clock.tick(tickTime);
294+
}, []);
295+
296+
return (
297+
<Box borderStyle="round">
298+
<Text>Test</Text>
299+
<Nested />
300+
</Box>
301+
);
302+
}
303+
304+
const {unmount, rerender} = render(<Test />, {
305+
debug: true,
306+
onRender,
307+
});
308+
309+
t.is(lastRenderTime, 200);
310+
311+
tickTime = 200;
312+
rerender(<Test />);
313+
314+
// Component props haven't changed for Nested so it doesn't trigger tick
315+
t.is(lastRenderTime, 200);
316+
317+
unmount();
318+
319+
clock.uninstall();
320+
});

0 commit comments

Comments
 (0)