Three real apps, each in its own iframe with its own Vue. Same grid of 25,000 blocks, same component tree, same block clicked. Only the Vue version and the rendering mode change.
Each panel is a separate app, running in its own iframe with its own Vue. The three are identical apart from the Vue version and the rendering mode.
Each app renders Grid, which renders N copies of
GridCell, each of which renders a BlockFace. So at 25,000
blocks there are 50,000 component instances, and that is deliberate:
it is the part of the Virtual DOM that costs the most memory.
Components switches to flat: Grid renders the
exact same DOM itself, with no child components. Squares mean one component drew the
block; a shape inside a frame means two (GridCell is the frame,
BlockFace the shape). Compare the memory of both: flat favours the Virtual
DOM, the tree favours Vapor, because Vapor saves per component, not per DOM node.
Update one block changes the value of a single cell and times how long the framework takes to settle. Not a value every row depends on. That shape is the whole point: the Virtual DOM has to rebuild and compare the entire tree to find one changed cell, while Vapor re-runs exactly the one effect that owns it.
You can also click any block directly. All three apps run the measurement one at a time, never simultaneously, five times, and report the average.
Press the button to run the comparison.
Run the comparison below.
Measuring reloads the page once per stack. Chrome only reports a heap for a document's first read after it loads, so the three have to be measured in three separate page loads. You will see each stack go by before the table comes back.