Migrating from React to Inferno

Florian Rappl, iQuest

Inferno.js

Migration Strategy From React.js

Cover Inferno

Florian Rappl

Solution Architect

  • IoT / Embedded Computing
  • .NET Communication Systems
  • Web Technologies

Writer and consultant

  • Microsoft MVP for C# / Development Tools
  • Active contributions to open-source projects
  • Articles for CodeProject, SitePoint, tuts+, ...

Agenda

  1. What is Inferno?
  2. Motivation to Discard React
  3. Similarities and Differences
  4. Migration Strategy
  5. Pitfalls and Mitigation

Inferno?

Inferno in a Nutshell

  • Component driven view framework
  • React-like API incl. concepts and component lifecycle events
  • Lightweight filesize
  • Isomorphic rendering
  • Highly modular
  • Focus on performance (on mobile)

Discover more at infernojs.org.

Frontend Framework Comparison

JS Framework Benchmark Shootout

Frontend Framework Comparison

Looks familiar?

import Inferno from 'inferno';

const message = 'Hello world';

Inferno.render(
  <MyComponent message={ message } />,
  document.getElementById('app')
);

Looks familiar?

import { Router, Route } from 'inferno-router';
import createHistory from 'history/createBrowserHistory';
const routes = (
	<Router history={ createHistory() }>
		<Route component={ App }>
			<Route path="/" component={ Home } />
			<Route path="/users" component={ Users }>
				<Route path="/:username" component={ User } />
			</Route>
			<Route path="*" component={ NoMatch } />
		</Route>
	</Router>
);

Motivation?

Problem Description (1)

  • Hybrid app using Cordova
  • Output needs to be compatible for Web, iOS, and Android
  • About 300 kLOC
  • Roughly 230 different components
  • Extensible via plugins
  • Reflux as state container

Problem Description (2)

  • Uses third-party components, e.g., React Bootstrap
  • Startup time on recent phones is about 3 seconds
  • Very dynamic system coupled to a live data feed
  • Some UI changes are quite heavy and have a noticable lag
  • Overall, battery usage is far too high

Comparison?

Performance

  • Inferno was designed for mobile
  • Uses more lightweight virtual DOM
  • Events are directly attached
  • Very fast diffing, barely any overhead

Modularity

  • Modularity is the practically identical to React
  • Less powerful ref attribute
  • Integration with other DOM manipulation libraries possible
  • Lifecycle events also exist on functional components

API

  • One-way data flow architecture
  • Bindings also supplied for Redux, MobX and Cerebral
  • React-like API
  • Concepts and component lifecycle events like in React
  • linkEvent to remove the need for manually binding callbacks

Size

  • 10 kB instead of 42 kB for the core part
  • DOM extension already integrated
  • Routing is external like in React

Rendering

  • Performance is key here
  • Same lifecycle as in React
  • Direct DOM integration
  • No possibility to use React Native
  • Server-side rendering supported

How fast does it render?

Inferno Performance

Demo

Binding

  • Same uni-directional dataflow
  • One-way binding as the default
  • Two-way binding manually
  • Like React, but faster

Migration?

Migration Steps

  1. Replace React w. Inferno, use inferno-compat
  2. Analyze library situation (identify strong dependency on React)
  3. Find suitable replacements that work w. Inferno
  4. Drop the notation of React and replace w. Inferno

Migration Step 1: Replace

  • Remove the React core libraries from the code
  • Add the Inferno core library
  • Add the Inferno/React compatibility shim
  • Try to run the application
  • Fix the problems
  • Revert if too many incompatibilites

Migration Step 1: Replace

npm install --save inferno inferno-component inferno-compat inferno-router
npm install inferno-test-utils --save-dev

// Webpack
{
	resolve: {
		alias: {
			'react': 'inferno-compat',
			'react-dom': 'inferno-compat'
		}
	}
}

Migration Step 2: Analyze

  • Which external libraries are we using?
  • Shape of the external libraries - is React necessary?
  • What features of React are required by these libraries?
  • Often a simple trial run is sufficient

Migration Step 3: Find

  • What are the alternatives to a given library?
  • Can the library be made compatible with a simple change?
  • Evaluate the effort of a custom implementation per component

Migration Step 4: Drop

  • Drop the inferno-compat library
  • Adjust Webpack to use module alias (React leading to Inferno)
  • Replace incompatible modules with their alternatives

Pitfalls?

Potential Problems

  • No alternatives to some libraries
  • Custom implementation is difficult to maintain
  • Hidden behavior change for some components
  • Less flexibility in the future

Results!

Demo

Thanks for your attention

  • Feel free to contact me