The same question, five frameworks
Five different answers to the same set of questions: how change is detected, how much work happens at compile time, and what actually reaches the DOM. Read a row across to orient yourself — then read the last block, which is where the row stops being true.
A tidy table implies an equivalence that does not exist. These are not five implementations of one idea; they are five different positions on what a framework is for, and the cells in a row are near-neighbours at best. The where this comparison misleads block on every row is the part worth reading, and it is the reason this page does not declare a winner.
The word "reactive" covers two genuinely different mechanisms. React re-executes a component and works out what changed afterwards; Vue, Solid and modern Angular build a dependency graph and notify only what depends on the value. That difference decides what a performance problem looks like in each: in React it is a subtree that re-rendered when it did not need to, and in the signal-based systems it is a read that escaped tracking so nothing updated at all. Comparing them on a benchmark hides the fact that you debug them with different questions.
"Virtual DOM or not" is a weaker distinction than it sounds, because the DOM writes at the end are the same in all five — only the process of deciding which writes to make differs. Vue's compiler-informed virtual DOM sits between the two camps and is not well described by either label. Anyone claiming one column here is faster has to say faster at what workload, on what device: the gap is large in a rapid-update benchmark and often invisible in an ordinary form.
Compiling more is not automatically less: it moves cost from the runtime bundle into per-component generated code, so a framework with a small runtime can ship more total bytes in an application with very many components, and one with a large shared runtime amortises it. The crossover depends on the size and shape of the app, which is why "smallest framework" is a claim that changes sign as an application grows. Build-time work also has to happen on someone's machine, so it lands as CI and dev-server time instead.
The frameworks disagree about whether state is fundamentally attached to a component. React's hooks are, so sharing is an escalation with its own re-render consequences; Solid's and Vue's primitives are not, so a shared value is just a value in a module. That changes which advice is even meaningful: "lift state up" is a React sentence, and the state-ownership question underneath it is universal while the mechanics are not portable.
You are usually comparing meta-frameworks, not frameworks: the SSR experience is Next, Nuxt, SvelteKit, SolidStart or Angular's own tooling, and their routing, data-loading and caching conventions differ far more than the rendering libraries beneath them. Migration cost lives in that layer, not in the component syntax. Server components in particular are a React-ecosystem architecture with no direct equivalent in the other columns, so the row is not comparing like with like.
Baseline size is the number people quote and the least relevant one past a hello-world. What decides the shipped total is per-component output, how well your dependencies tree-shake, and whether the app is code-split at all — a single date or icon library routinely outweighs the entire framework. Comparing frameworks by their empty-app size answers a question nobody in production has.
Ecosystem size cuts both ways and the direction depends on your team. A large ecosystem means someone has solved your problem and also that there are six incompatible solutions with different maintenance states; a first-party-everything framework means fewer decisions and less choice when the built-in answer does not fit. The genuinely decisive factor is usually which one your team can maintain in three years, and that is not a property of the framework.
The curve is not one line, and "easy to start" and "easy to be correct in" are different properties that often trade against each other. Svelte and Solid are quick to pick up and have a specific rule you must internalise before anything works reliably; Angular front-loads the difficulty and then holds a large team to consistent conventions. Whether that is a cost or a benefit depends on how many people are in the codebase.
This is the row that best shows why there is no winner: each framework has a characteristic bug that is a direct consequence of its model, and they are not the same bug. Re-render-too-much and never-update-at-all sit at opposite ends — the first is a performance problem you can see in a profile, the second is a correctness problem that looks like nothing happening. Choosing a framework is choosing which of these your team will spend the next three years learning to recognise.