mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-08 00:43:54 +00:00
perf(cuesheet): revert lazy-autosize (Exp B) — metrics show it regresses
Measured baseline vs lazy-autosize at CPU 4x (median of 3, ~1140 row mounts): - cell.autosize eliminated (15.2s -> 0) BUT - EventRow.mount avg +39% (179 -> 248ms), longtask +32%, longFrames 201->219, and per-row re-renders ~2x (getVisibleCells renders 4648 -> 8902). Deferring autosize destabilises virtuoso row-height measurement (rows=1 textareas), causing more re-render churn, and collapses note display. Net negative — not merged. Keeping instrumented baseline.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// @ts-expect-error no types from library
|
||||
import autosize from 'autosize/dist/autosize';
|
||||
import { FocusEvent, RefObject, useCallback, useEffect } from 'react';
|
||||
import { RefObject, useEffect } from 'react';
|
||||
|
||||
import { timeSync } from '../../../devtools/cuesheet-metrics/usePerfMark'; // PERF-METRICS
|
||||
import Textarea, { type TextareaProps } from '../textarea/Textarea';
|
||||
@@ -10,41 +10,18 @@ interface AutoTextAreaProps extends TextareaProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* A textarea that automatically resizes based on its content.
|
||||
*
|
||||
* `autosize()` forces a synchronous reflow (reads scrollHeight) and installs a MutationObserver.
|
||||
* Doing that on mount makes it expensive when many of these are mounted at once (e.g. virtualised
|
||||
* table rows during scroll), so we only attach autosize while the field is focused for editing and
|
||||
* keep it in sync with the value during that time.
|
||||
* A textarea that automatically resizes based on its content
|
||||
*/
|
||||
export function AutoTextarea({ value, inputref, onFocus, onBlur, ...textAreaProps }: AutoTextAreaProps) {
|
||||
const handleFocus = useCallback(
|
||||
(event: FocusEvent<HTMLTextAreaElement>) => {
|
||||
timeSync('cell.autosize', () => autosize(inputref.current)); // PERF-METRICS
|
||||
onFocus?.(event);
|
||||
},
|
||||
[inputref, onFocus],
|
||||
);
|
||||
|
||||
const handleBlur = useCallback(
|
||||
(event: FocusEvent<HTMLTextAreaElement>) => {
|
||||
if (inputref.current) {
|
||||
autosize.destroy(inputref.current);
|
||||
}
|
||||
onBlur?.(event);
|
||||
},
|
||||
[inputref, onBlur],
|
||||
);
|
||||
|
||||
// while focused, keep the height in sync as the value changes
|
||||
export function AutoTextarea({ value, inputref, ...textAreaProps }: AutoTextAreaProps) {
|
||||
// when the value changes, we use the ref to reapply autosize
|
||||
useEffect(() => {
|
||||
const node = inputref.current;
|
||||
if (node && document.activeElement === node) {
|
||||
autosize(node);
|
||||
}
|
||||
timeSync('cell.autosize', () => autosize(inputref.current)); // PERF-METRICS
|
||||
|
||||
return () => {
|
||||
autosize.destroy(node);
|
||||
};
|
||||
}, [inputref, value]);
|
||||
|
||||
return (
|
||||
<Textarea ref={inputref} value={value} onFocus={handleFocus} onBlur={handleBlur} {...textAreaProps} />
|
||||
);
|
||||
return <Textarea ref={inputref} value={value} {...textAreaProps} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user