Skip to content
forked from infernojs/inferno

A very fast, light-weight, isomorphic component building framework

License

Notifications You must be signed in to change notification settings

iclanzan/inferno

 
 

Repository files navigation

InfernoJS

Build Status Coverage Status Dependency Status devDependency Status npm version

Inferno is a lightweight isomorphic framework for building shockingly performant user interfaces. Unlike typical virtual DOM libraries like React, Mitrhil, Cycle and Om, Inferno does not rely on diffing DOM virtual elements, but instead it differentiates static content from dynamic content and only diffs the values that change within a given fragment of virtual DOM elements (we call them virtual fragments).

In addition to this, we've painstakingly optimized the code to make sure that there is as little overhead as possible. We believe that Inferno is currently the fastest vDOM implementation on out there - as shown by some of our benchmarks. Inferno is all about performance, whilst keeping a robust API that replicates the best features from libraries such as React.

In principle, Inferno is compatible with the standard React API, allowing for painless transition from React to Inferno in most use cases. Furthermore Inferno has a Babel plugin allowing JSX syntax to transpile to optimised Inferno templates.

Algorithm

  1. On startup, templates are generated, identifying static and dynamic nodes
  2. Per update, virtual fragments are created based on each template
  3. Values for dynamic nodes are diffed and updated if necessary
  4. Fragments are recycled for next render

To be more technically correct, Inferno is a "virtual fragment" framework, which provides the same flexibility as a Virtual DOM does, but with a much smaller memory footprint and greater performance.

Install

npm install --save inferno

Testing

npm run test:browser // browser tests

npm run test:server // node tests

npm run test // browser and node tests

Building

npm run build

Linting

npm run lint:source // lint the source

Overview

Let's start with some code. As you can see, Inferno intentionally keeps the same good (in our opinion) design ideas regarding components, one-way data passing and separation of concerns. In these examples, JSX is used via the Inferno JSX Babel Plugin to provide a very easy way to express virtual fragments.

const message = "Hello world";

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

Furthermore, Inferno also uses ES6 components like React:

class Component extends Inferno.Component {
  constructor(props) {
    super(props);
    this.state = {
      counter: 0
    }
  }
  render() {
    return (
      <div>
        <h1>Header!</h1>
        <span>Counter is at: { this.state.counter }</span>
      </div>
    )
  }
}

Inferno.render(<Component />, document.body);

The real difference between React and Inferno is the performance offered at run-time. Inferno can handle large, complex DOM models without breaking a sweat. This is essential for low-power devices such as tablets and phones, where users of those devices are quickly demanding desktop like performance on their slower hardware.

Key Features

  • one of the fastest front end frameworks for rendering UI
  • components have a similar API to React ES6 components
  • components can also be stateless like React components (pure functions)
  • isomorphic/universal for easy server-side rendering

Benchmarks

Inferno Top-Level API

Inferno.Component

Stateful component:

class MyComponent extends Component {
  render() {
    ...
  }
}

This is the base class for Inferno Components when they're defined using ES6 classes.

Stateless component:

const MyComponent => ({ name, age }) => 
  <span>My name is: { name } and my age is: {age}</span>  
);

Stateless components are first-class functions where their only argument is the props passed through from their parent.

Inferno.render

Inferno.render(<div />, document.body);

Render a fragment into the DOM in the supplied container and return a reference to the component. If the fragment was previously rendered into container, this will perform an update on it and only mutate the DOM as necessary to reflect the latest Inferno component.

Inferno.renderToString

Inferno.renderToString(<MyComponent />);

[Note: currently in development]

Render a fragment to its initial HTML. This should only be used on the server. Inferno will return an HTML string.

Inferno.createTemplate

const template = Inferno.createTemplate(() => ({
  tag: 'div',
  attrs: { className: 'test'},
  children: [
    'This', ' is ', 'a test!'
  ]
}));

Inferno.render(template(), document.body);

Inferno.TemplateFactory

const { createElement } = Inferno.TemplateFactory;

class BasicComponent extends Inferno.Component {
    render() {
        const template = Inferno.createTemplate((name, title) =>
            createElement('div', {
                    className: 'basic'
                },
                createElement('span', {
                    className: name
                }, 'The title is ', title)
            )
        );
        return template(this.props.name, this.props.title);
    }
}

const template = Inferno.createTemplate((Component, title) =>
    createElement('div', null,
        createElement(Component, {
            title: title,
            name: 'basic-render'
        })
    )
);

Inferno.render(template(BasicComponent, 'abc'), container);

Inferno.TemplateFactory provides a factory createElement() function that can be used to build up virtual DOM structures in a similar sense to how React.creactElement() works. It's first argument is the node, second argument is the attributes and all remaining arguments are it's children.

Inferno.createRef

const divRef = Inferno.createRef();

Inferno.render(<div ref={ divRef } />, document.body);
divRef.element.textContent = 'Modifying the DOM node directly!';

Creates a mutable object that links an Inferno rendered template node to its real DOM node upon being mounted to the DOM.

Performance

Inferno tries to address two problems with creating UI components:

  • Writing large applications in large teams is slow in terms of development and expensive in costs – it shouldn't be.
  • Writing complex applications generally gives poor performance on mobile/tablet/older machines – it shouldn't.
  • Writing intensive modern UIs that require many updates/animations falls apart and becomings overly complicated - it shouldn't be.

Writing code should be fun. Browsers are getting more advanced and the technologies being supported are growing by the week. It's about time a framework offered more fun without compromising performance.

JSX

Inferno has it's own JSX Babel plugin.

Still under development

Inferno is still under development, and there are some missing features and optimizations to be made.The high priority now is the server side rendring (SSR).

Todo

  • implement isomorphism/universal server side rendering
  • add API docs
  • add examples repo

Inferno is supported by BrowserStack

Supported by Browserstack

About

A very fast, light-weight, isomorphic component building framework

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 99.3%
  • Other 0.7%