React vs Preact vs Inferno

React is an excellent web development framework. It allows one to develop a web app very quickly compared to imperative frameworks. Unfortunately, faster development has a cost: performance. React-based app perform a lot of calculations and does a lot of memory allocations. The more complex UI app has, the more CPU and RAM it uses. This is true for both declarative and imperative frameworks, but with React, CPU requirements grow faster.

There are several frameworks that promise to solve the same task as React, but are smaller and faster. In this article I will compare Preact and Inferno to React. I will test these libraries with my React-based app Watermarkly. It’s a watermarking tool that allows user to design her own watermark. Watermark editor is quite complex with lots of DOM elements in it. Watermark editor is based on SVG, hence every watermark element is a separate DOM-node.

Watermark editor with React

Application JavaScript file size is 508Kb (minified, non-compressed) + dependencies 501Kb (minified, non-compressed).

React version was 16.12.0. Inferno version was 7.4.10, and Preact version was 10.5.14.

Both Preact and Inferno are faster than React in synthetic benchmarks.

Both libraries provide React-compatibility mode which makes them a drop-in replacement for React: Switching to Inferno, Switching to Preact (from React). Compatibility mode worked well in both cases, I didn’t have to change anything in my code. There was only a small glitch with Preact: it rendered watermarks with a slight offset. I didn’t try to figure out why.

Watermark editor with Preact

Watermark editor with Inferno was indistinguishable from React: Watermark editor with Inferno

Memory and CPU usage

I switched to another tab and used browser’s task manager to see how much resources my app consumes: React memory consumption

All comparisons were made on minified production builds.

Memory JavaScript Memory GPU Memory CPU Script Cache
React 47380Kb 12608Kb (7762Kb live) 10863Kb 0 3044Kb
Preact 47984Kb 13120Kb (10675Kb live) 8259Kb 0 5758Kb
Inferno 52848Kb 14920Kb (12901Kb live) 23107Kb 21.5 2768Kb

Preact and Inferno make js files smaller, but when the app is running, it consumes more memory than a React-based app. Surprisingly Inferno consumed considerable amount of CPU even when the browser tab wasn’t active. This may be due to compatibility mode, but the app is too big to port it to Inferno just to find out what causes the problem.

We should be able to reduce memory consumption of Preact- and Inferno-based app by ditching compatibility layers. I’m not sure that a complete port from React to Preact/Inferno will be faster than React app. Preact/Inferno has to match React memory usage in compatibility mode. Then ditching compatibility layer, will make Preact/Inferno small and faster than React. Unfortunately, Preact/Inferno use more memory than React.

It seems to me, React is better optimized for large real-world applications than Preact or Inferno.