inferno.js简述

我们先来看看 inferno.js 是什么:
An extremely fast, React-like JavaScript library for building modern user interfaces
好吧,注意用词 :extremely;
同时还有:
Inferno is an insanely fast, 9kb React-like library for building high-performance user interfaces on both the client and server.
这时候的用词:insanely;
当然,最基本的是 React-like,如果你还不了解它是什么,可以自己先看下,不再过多介绍。

对于其高性能的展现以及 benchmark,其官方从四个维度展示了样例:
Virtual DOM Benchmark
UI Bench
dbmonster
JS Web Frameworks Benchmark - Round 6

自从诞生起,inferno.js 的定位就是高性能,高效率。作为 react-like 类库,做到高效的最重要一环当然就是对于 virtual dom 的 diff,这个 diff 算法的优劣,以及虚拟 dom 相关周边的一切(包括 batching 等)非常重要。
这方面内容,我觉得
@司徒正美
非常有发言权。
如果司徒大大有时间,可以亲自来说说。下面回答前半部分内容,源自司徒正美的积累和分享(出处:去哪儿网迷你React的研发心得 - javascript魔法师 - SegmentFault)。

虚拟DOM库是分为两大派系:算法派与拟态派。

最开始出现的是 virtual-dom (Matt-Esch/virtual-dom) 这个库。它的实现是非常学院风格,通过深度优先搜索与 in-order tree 来实现高效的 diff。它与React后来公开出来的算法是很不一样。
因为我们知道 React diff 算法的一个核心假设就是逐层,从上到下一级一级的比较。DFS 算法显然和这个假设是相违背的。不过 virtual-dom 这个库文件组织良好,代码注释清晰,有时间还是建议看一下的。

然后是 cito.js (joelrich/citojs) 的横空出世,这对今后所有虚拟DOM的算法都有重大影响。它采用两端同时进行比较的算法,将diff速度拉高到几个层次。
紧随其后的是 kivi.js,在 cito.js 的基础上提出两项优化方案,
使用 key 实现移动追踪;
基于key的编辑长度矩离算法应用(算法复杂度 为O(n^2));

但这样的 diff 算法太过复杂了,于是后来者 snabbdom 将 kivi.js 进行简化,去掉编辑长度矩离算法,调整两端比较算法。速度略有损失,但可读性大大提高。再之后,就是著名的 vue2.0 把 sanbbdom 整个库整合掉了。当然这都是后话。

紧接着,我们的主角就要上场了:算法派的老大是 inferno,它使用多种优化方案将性能提至最高,最终其作者便邀请进 react core team,负责 react 的性能优化。
从下图中,可以看到 inferno.js 的衍生思路:

继承自 cito.js,如果你有细心看上面一段,就会明白 inferno.js 所谓“师承”的基础。

另外,当然还有很多细节,进行了更大程度的优化。总结一下,包括但不限于:
Inferno 避免使用存在 prototype/constructors 的对象,而是支持对象字面量形式,保证对象本身拥有最小化的属性。同时采用特有的 utility/helper 函数,对这些对象进行访问或 mutate;这样的做法对于不支持 JIT (just in time) 编译的情况,或者手机低电量的情况,能够显著提升效率;
与其维护两套 virtual DOM 进行 diff,inferno 直接将当前 virtual dom 和真实 dom 对象 diff。对于性能的提升也是一定程度上有帮助的;
Inferno 试图最大化重复利用对象属性、对象本身、DOM 节点。这种例子非常的多,就不列举了,源码里面都可以发现。感兴趣可以再问,我展开来说。
Inferno 避免过多的操作 DOM。同时避免使用类似诸如 childNodes 和 innerHTML 的 DOM API,它们的共同特点都是开销大。同理,在清除 DOM 节点内容时,更高效的做法永远是:textContent(’’);
一系列关于 JIT 编译的优化和最佳实践。说多了有些无聊,不再详细介绍。同样感兴趣可以再问,我展开来说。
另外一个爆点就是 Inferno 使用了自己的 event system 来处理事件。这样做可以自己把控是否需要代理事件,还是使用 inline event;合适的事件代理能带来性能和内存使用的极大提升。
最后提一下 Inferno 对于使用 key 子节点的算法优化吧。React 在这方面并没有做到极致。使用动态规划等算法,在对于存在 key 的子节点位置变换(增删乱序)等还是比较有必要的。

还有业务代码要做,PM 要来改需求了。先说这么多吧,相关细节还有很多非常有趣的。
另外题主对于这个问题有疑问,说明对于前端性能关注比较多。
我觉得这是非常好的习惯,同时建议下可以先自己找一下答案。
比如在 Inferno.js GitHub 仓库中 (infernojs/inferno),搜索关于 performance 的 issues,我看到一共有 102 条之多:

扫描二维码关注公众号,回复: 5950095 查看本文章

每一个 issue 的讨论,自己看下来都会有收获。


https://www.jianshu.com/p/c6d77080eefe

猜你喜欢

转载自blog.csdn.net/TENCENTSYS/article/details/89017654