@pixagram/virtualized
v10.0.5
Published
React components for efficiently rendering large, scrollable lists and tabular data. v9.22.1 OPTIMIZED BY PIXAGRAM.
Maintainers
Readme
@pixagram/virtualized — optimized
@pixagram/virtualized (a react-virtualized fork) with a set of
behavior-preserving performance optimizations applied to the core windowing
engine, the Collection spatial index, and (on by default) the Grid scroll/render path —
plus a reproducible verification suite.
source/ The library source, with optimizations applied (ships the
*.jest.js test suite too).
- CHANGES.md ............ full changelog
- NOTES_FURTHER_OPTIMIZATIONS.md ... remaining proposals
verification/ Differential harnesses + benchmarks proving the optimizations
are bit-identical / DOM-identical to the original behavior.
- README.md ............. how to run, results
- baseline/ ............. pristine files the harnesses diff against
jest.config.js / babel.config.js Run the project's own *.jest.js suite
against this optimized tree.Optimizations applied
Pure-logic layer (verified bit-identical to the original by randomized differential harnesses — 685,064 assertions, 0 mismatches):
- Fixed-size fast path (
CellSizeAndPositionManager) — constant integerrowHeight/columnWidth⇒ O(1) arithmetic geometry, no arrays/search. ~15× faster visible-range queries; ~33.5 MB → 0 backing memory on 1M cells. - Lazy Fenwick delta allocation — point-update arrays allocated only on
first
resizeCell(another ~16.8 MB saved on 1M cells). - Non-allocating scalar accessors + renderer hoist — remove the rows×columns per-render style-input allocations.
- CellMeasurerCache capacity seeding — optional
columnCount/rowCounthints avoid column-growth relayout. - Count-based rescan mitigation (
CellMeasurerCache) — a shrink skips the O(n) max-rescan unless the last max-holder is removed. - Finger (galloping) search (
CellSizeAndPositionManager) — ~1.8× faster smooth scroll on a 500k variable-height list. - Collection de-dup without string coercion (
SectionManager/Section) —getCellIndicesuses aSet<number>+ ascending sort instead of an object-as-set +Object.keys()/map(). ~2.45× faster on a 20k-cell collection.
React component layer (verified by render-differential and the project's own test suite):
Grid scroll range-gating (
Grid, on by default; disable withreuseChildrenOnScroll={false}) — while actively scrolling, when the rendered cell set and positions are unchanged, reuse the previously rendered children and skip the cell-range renderer. ~38% fewer renderer calls during scroll, with byte-identical DOM. Disable it only if yourcellRenderer/cellRangeRendererhave per-call side effects that must run on every scroll frame (with gating on they are not invoked on unchanged-range frames).Masonry transform positioning (
Masonry, opt-in viauseTransform, defaultfalse) — position cells withtransform: translate(x, y)(composited, no layout on reposition) instead oftop/left. Geometry-verified identical for LTR and RTL. Opt-in becausetransformestablishes a new stacking context (affectsposition: fixeddescendants), unlike the DOM-transparent items above.
Verification at a glance
- 685,064 logic-layer differential assertions, 0 mismatches.
- Grid range-gating: render-differential shows enabling the flag leaves the DOM byte-identical (150 steps across fixed/variable/scaled sizes, scroll/settle, prop changes, recompute mid-scroll, real CellMeasurer cache), with the gate confirmed firing.
- The project's own
*.jest.jssuite passes 568/568 on this optimized tree (and identically on the original), across every component — zero regressions.
See verification/README.md to reproduce everything.
Running the project's test suite
npm i -D jest@29 jest-environment-jsdom@29 jest-jasmine2@29 babel-jest@29 \
@babel/core @babel/preset-env @babel/preset-react @babel/preset-flow \
@babel/plugin-proposal-class-properties \
react@16 react-dom@16 react-test-renderer@16 clsx dom-helpers@5 immutable jsdom
npx jest # whole suite
npx jest Grid/Grid.jest # just Grid (126 tests)The project targets the jasmine2 runner (its TestUtils registers an
afterEach lazily on first render, which jest's default circus runner rejects);
jest.config.js sets testRunner: 'jest-jasmine2' accordingly.
Not applied (proposals)
Two further optimizations (batched DOM measurement in CellMeasurer, opt-in
transform-based positioning) remain documented proposals in
source/NOTES_FURTHER_OPTIMIZATIONS.md. Both depend on real browser layout,
which the available (jsdom) test environment does not implement, so they can't
be proven correct the way everything else here was.
