文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

Inferno是一个可构建高性能用户界面的同构库,这类库针对移动设备尤其关键。Inferno和典型的虚拟DOM库不同,比如React、Mithril、Cycle和Om等,Inferno采用了智能技术来区分静态和动态的内容,这让Inferno仅仅“区分”渲染那些有动态值的内容。

除此之外,我们精心优化代码以确保它的开销尽可能的少,我们相信Inferno是当前业界最快的虚拟DOM实现框架 —— 如我们的基准测试所示,Inferno完全是为性能而生,同时还提供了一个健壮的API库,复制了诸如React等库的最佳特性。

第 1 段(可获 2 积分)

原则上,Inferno兼容标准React API,可以毫不费劲的从React转到Inferno。此外,Inferno还有一个Babel插件,支持JSX语法,可用于优化Inferno的虚拟DOM。

关键特性

  • 最快的DOM UI渲染前端框架之一
  • 拥有类似React ES2015 API的组件inferno-component
  • 完全支持无状态组件,感谢Inferno的hooks系统提供了更多可用性
  • 同构(或通用)使得服务端渲染在Inferno-server上更简易

基准测试

第 2 段(可获 2 积分)

安装

和React很相似,Inferno需要引入inferno包和inferno-dom包,用于浏览器DOM内的消费,还有一个用于服务端渲染的inferno-server包,用于将虚拟DOM变为HTML字符串(和React的route不一样,它是用react-dom/server做服务端渲染)。此外,组件在一个独立的inferno-component包内,具有更好的模块化,而不是像React那样通过类在核心内引入ES2015组件。

第 3 段(可获 2 积分)

NPM:

核心包:

npm install --save inferno

ES2015有状态组件包(带生命周期事件):

npm install --save inferno-component 

浏览器DOM渲染包:

npm install --save inferno-dom 

创建Inferno的VNotes (和React.createElement相同):

npm install --save inferno-create-element

服务端渲染包:

npm install --save inferno-server 

浏览器的预加载文件:

http://infernojs.org/releases/0.7.8/inferno.min.js
http://infernojs.org/releases/0.7.8/inferno-create-element.min.js
http://infernojs.org/releases/0.7.8/inferno-component.min.js
http://infernojs.org/releases/0.7.8/inferno-dom.min.js
http://infernojs.org/releases/0.7.8/inferno-server.min.js
第 4 段(可获 2 积分)

概述

让我们看些代码。正如你所见,Inferno在组件上有意保持了和React一致的良好设计思想:单向数据流和关注点分离。下面这些例子里,JSX通过Babel插件提供了一种展现Inferno的虚拟DOM的简单方法。

import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';

const message = "Hello world";

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

此外,Inferno和React一样也使用了ES6组件:

第 5 段(可获 2 积分)
import Inferno from 'inferno';
import { Component } from `inferno-component`;
import InfernoDOM from 'inferno-dom';

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

InfernoDOM.render(<MyComponent />, document.body);

React和Inferno的真正区别是运行时的性能差异,Inferno能轻松处理大量复杂的DOM模型,这对于平板或手机一类的低配设备是至关重要的,用户往往要求他们的低速设备像桌面设备那样性能快速。

第 6 段(可获 2 积分)

Inferno顶层API

Inferno.createVNode

创建一个具有链式方法的Inferno VNode对象

import createVNode from `inferno`;

InfernoDOM.render(createVNode().setTag('div').setClassName('foo').setAttrs({ id: 'test' }).setChildren('Hello world!'), document.body);

Inferno.createBlueprint

创建一个具有预定义蓝图的Inferno VNode,使用该蓝图的引用可以减少开销,提高性能。

import InfernoDOM from 'inferno-dom';

const myBlueprint = Inferno.createBlueprint({
    tag: 'div',
    attrs: {
        id: 'foo'
    },
    children: { arg: 0 }
});

InfernoDOM.render(myBlueprint('foo'), document.body);

 

第 7 段(可获 2 积分)

对于当作参数传给createBlueprint的对象中的每个属性,只要是用{ arg: X }形式定义的,都会被当成一个动态值(匹配调用该blueprint的参数),其他形式则被当成静态值。举个例子:如果对象是const blueprint = Inferno.createBlueprint({ tag: { arg: 0 } }),那么应该这样调用,blueprint('div'),即使用第一个参数作为VNode的标签。

InfernoCreateElement

创建一个Inferno VNode,这个API和React的createElement很相似

第 8 段(可获 2 积分)

InfernoServer.renderToString

import InfernoServer from 'inferno-server';

InfernoServer.renderToString(<div />, document.body);

渲染一个虚节点,并添加至HTML字符串,假定已提供虚拟DOM。

钩子

请注意:钩子由inferno-dom提供;

Inferno支持DOM节点上的多种基本事件,比如onClick、onMouseOveronTouchStart,此外Inferno允许直接将普通钩子附加到组件和DOM节点上。下列表格展示了inferno-dom中的所有可用钩子:

名称触发条件回调参数onCreated一个DOM节点被创建domNodeonAttached一个DOM节点被附加在文档domNodeonWillDetach一个DOM节点将要被从文档中移除domNodeonWillUpdate一个DOM节点将要执行潜在的更新domNodeonDidUpdate一个DOM节点已经执行潜在的更新domNodeonComponentWillMount一个无状态组件即将挂载domNode, propsonComponentDidMount一个无状态组件已经挂载domNode, propsonComponentWillUnmount一个无状态组件即将被卸载domNode, propsonComponentShouldUpdate一个无状态组件已被触发更新domNode, lastProps, nextPropsonComponentWillUpdate一个无状态组件即将执行更新domNode, lastProps, nextPropsonComponentDidUpdate一个无状态组件已经更新domNode, props

 

第 9 段(可获 2 积分)

InfernoServer.renderToString

import InfernoServer from 'inferno-server';

InfernoServer.renderToString(<div />, document.body);

渲染一个虚节点,并添加至HTML字符串,假定已提供虚拟DOM。

钩子

请注意:钩子由inferno-dom提供;

Inferno支持DOM节点上的多种基本事件,比如onClick、onMouseOveronTouchStart,此外Inferno允许直接将普通钩子附加到组件和DOM节点上。下列表格展示了inferno-dom中的所有可用钩子:

名称触发条件回调参数onCreated一个DOM节点被创建domNodeonAttached一个DOM节点被附加在文档domNodeonWillDetach一个DOM节点将要被从文档中移除domNodeonWillUpdate一个DOM节点将要执行潜在的更新domNodeonDidUpdate一个DOM节点已经执行潜在的更新domNodeonComponentWillMount一个无状态组件即将挂载domNode, propsonComponentDidMount一个无状态组件已经挂载domNode, propsonComponentWillUnmount一个无状态组件即将被卸载domNode, propsonComponentShouldUpdate一个无状态组件已被触发更新domNode, lastProps, nextPropsonComponentWillUpdate一个无状态组件即将执行更新domNode, lastProps, nextPropsonComponentDidUpdate一个无状态组件已经更新domNode, props

 

第 10 段(可获 2 积分)

InfernoServer.renderToString

import InfernoServer from 'inferno-server';

InfernoServer.renderToString(<div />, document.body);

将一个虚拟节点渲染进 HTML 字符串,并提供虚拟的 DOM 结构。

钩子

请注意:钩子是通过 inferno-dom 提供的

Inferno 支持很多 DOM 节点的基本事件,例如 onClick, onMouseOveronTouchStart。此外,Inferno 允许你直接在组件和 DOM 节点中附加通用事件。下表是 inferno-dom 提供的所有钩子:

名称触发提交回调参数
onCreatedDOM 节点创建时domNode
onAttachedDOM 节点被附加到文档时domNode
onWillDetachDOM 节点将被文档移除时domNode
onWillUpdateDOM 节点将要执行任何潜在的更新domNode
onDidUpdateDOM 节点已经支持完更新操作domNode
onComponentWillMount将要安装无状态的组件domNode, props
onComponentDidMount已经成功安装无状态组件domNode, props
onComponentWillUnmount将要卸载无状态组件domNode, props
onComponentShouldUpdate无状态组件被触发用于更新domNode, lastProps, nextProps
onComponentWillUpdate无状态组件将要更新domNode, lastProps, nextProps
onComponentDidUpdate无状态组件完成更新操作domNode, props
第 11 段(可获 2 积分)

使用钩子

为DOM节点和无状态组件隐式的分配钩子是很简单的,请注意:从inferno-component来的有状态组件(ES2015类)不支持钩子。

function createdCallback(domNode, props) {
    // [domNode] will be available for DOM nodes and components (if the component has mounted to the DOM)
    // [props] will only be passed for stateless components
}

InfernoDOM.render(<div onCreated={ createdCallback } />, document.body);

function StatelessComponent({ props }) {
    return <div>Hello world</div>;
}

InfernoDOM.render(<StatelessComponent onComponentWillMount={ createdCallback } />, document.body);

 

第 12 段(可获 2 积分)

钩子为无状态组件提供了强大的生命周期事件支持,这样就不必被迫使用ES2015的类来构建新的组件。

性能

Inferno尝试处理创建UI组件时的两大难题:

  • 在大团队中编写大的应用程序是很慢的,尤其在开发效率和成本开销方面 —— 其实不应该
  • 通常在手机、平板或老设备上编写复杂的应用程序会导致很差的性能 —— 其实不应该
  • 编写加强的现代UI界面需要进行多次更新和加入许多动画,很容易崩溃,界面变得过于复杂 —— 其实不应该
第 13 段(可获 2 积分)

写代码应该是件很好玩的事,随着浏览器越来越先进,技术日新月异,是时候选择一个既不对性能妥协又能提供许多乐趣的框架了。

JSX

Inferno有自己的JSX Babel plugin

和React的区别

Inferno努力保持和React基本API的兼容,只是在某些地方做了替代式的实现,当这些替换的解决方法容易采用,不用做太多改变时,一些非永久的特性就被彻底去除或是取代了。

自定义命名空间

Inferno一直想交付高性能的框架并计划如此,因此不得不对DOM状态和元素的可变性做出明智的假设,但自定义命名空间与此冲突,它可能会改变元素和属性的工作模式,所以Inferno不打算试图支持命名空间。相反,SVG的命名空间是自动应用到元素和属性上的,根据它们自身的标签名称。

第 14 段(可获 2 积分)

有状态的ES2015组件位于独立包内

React的ES2015组件一般是作为React引用,为了减少Inferno核心的膨胀,我们提取了ES2015组件放入它自身的独立包内,具体点是inferno-component而非Inferno.Component,很多用户选择和Inferno的钩子一起使用无状态组件,它和ES2015组件具有同样的功能。

属性间的自动单位插入

Inferno不会试图在数值属性或特性上添加单位,但React会自动添加。举个例子:React处理样式<div style={ { left: 10 } }/>时将会造成px被自动添加。为保证Inferno的简洁和快速,代码中并不包含这些昂贵的检查开销,也无需维护代价,完全让用户自己指定属性。因此,你可以用Inferno进行如下操作达到相同的结果<div style={ { left: '10px' } } />。

第 15 段(可获 2 积分)

参考

测试

npm run test:browser // browser tests
npm run test:server // node tests
npm run test // browser and node tests
npm run browser // hot-loaded browser tests

编译

npm run build

检查

npm run lint:source // lint the source

Inferno由BrowserStack支持

第 16 段(可获 2 积分)

文章评论