import { startTransition, useEffect, useState } from "react"; // A long page of table rows mounts in steps: the first FIRST_ROWS at once, then STEP_ROWS more per // background transition until all are in. The channel manager's "All" page (~400 rows) took // 0.7–0.9 s of one blocked frame to mount on prod, and every sort and every keystroke in its search // re-rendered all of them (300–400 ms per key). No single cell is to blame: measured column by column, // each costs its share, and all of them together cost ~9× an empty row. The first rows fill more than // a screen, so the page paints at once. The rest come in small steps because a transition yields only // while it renders: its commit (the rows' DOM, the tag cells' measuring layout effects) is one block, // and the rest in one step was a 0.7 s block of its own. Between steps a key or a click goes first, // and a new view starts over. // // Not virtualization: every row still ends up in the DOM, so browser find, keyboard nav past the screen, // and the Back focus/scroll restore (which wait for the list to grow) keep working as they did. export const FIRST_ROWS = 30; const STEP_ROWS = 40; // `view` names what the rows show (page, size, sort, filters). A new view starts over from the first // rows, so the urgent render after a click or a key stays small. New data for the same view (a refetch) // does not: it would drop the rows the reader is looking at. // // `through` is a row that must be in the DOM in THIS render: the row a page turn was made to show // (DataTable's `reveal`). Its page is a new view, and the caller focuses that row right after the // commit — at index 40 of a 50-row page it was not mounted yet, and focus fell to
. export function useProgressiveRows