Why you shouldn`t use Preact, Fast-React, etc. to replace React today

本文作者:IMWeb nixzheng 原文出处:IMWeb社区 未经同意,禁止转载

生命在于折腾,Coder的折腾就在于造各种轮子。React在前端圈大火之后,轮子层出不穷。而其中的一些轮子,由于专注于解决很多人诟病的React过大、过慢的问题(然而不并不觉得),也相当出名。关注最多的莫过于PreactInferno等以「轻量化」为特色的库了,Github Star数也超过10000。另外由于React广泛应用于同构应用上,并且 rendertoStringrenderToStaticMarkup 也存在同步执行、速度慢等问题,一些专注于React服务器端渲染的库也颇受关注。如Preact产出的preact-render-to-string还有我现在的团队在用的fast-react-render,都是这个思路。

然而我一直都不喜欢这些替代库,特别是在同构的场景下。有以下几个简单的原因:

Checksum

React通过 renderToString 生成的DOM Content除了在每个节点上都有 data-reactid 属性外,在根节点上还生成了一个 checksum 的属性。浏览器端的React会在第一次render时校验节点内容与服务器生成内容的一致性,如果不一致则需要做很多DOM的增删改操作。理论上一致的checksum会节省大量JavaScript执行、Reflow时间(可查看Benchmark)。而preact-render-to-string、fast-react-render都没有加入checksum的逻辑。其生成的代码,不管前端使用Preact还是React,都需要将整个DOM树重渲染一次。由于浏览器端的render也是同步的,意味这段重渲染的时间里是无法与页面交互的。

兼容性

Preact, Inferno并没有实现对React的100%兼容(即便使用了xxx-compat包)。姑且不论你可能无法使用React社区里无数针对React深度定制的包,你也无法使用大家都喜欢的ant-design

不做过早优化

「程序员工具箱中最强大的优化技术就是不做优化。」——《Unix编程艺术》

关注我们的软件核心问题是什么,性能瓶颈是什么。网站加载速度慢真的是由于React框架过大?很多工程师往往为了优化而优化,而且结合自身背景只做自己分内的优化,却忘记了优化的最终目的是什么。花更多的时间去解决更关键的问题,而不是花在各种使用替换方案和解决其兼容性上。

可维护性

我个人最喜欢Facebook开源项目的一点是,他们的项目是真的用在了自己的核心产品上。不单依靠那些五花八门的测试用例、没有那些天花乱坠的推广软文,React的稳定性已经得到数十亿网民的验证。而且,Facebook在React 16还没有release的情况下已经在主站开始使用React Fiber,并通过完整的测试用例保证其向后兼容性,让React的使用者很安心。

而其他的项目,多为个人开发的项目。开源社区里过个一两年之后就停止维护的事情也是常有的,这些替代库的bug修复是否及时,是否能跟上React的更新节奏,我个人也是很持怀疑态度的。

面向未来

接上文的React更新节奏说起,React Team一直保持着高效、专注的产出,围绕着提升Web开发体验、表现性能等持续优化。Fiber在调度上做了相当多的优化,实际动画性能需要进一步了解,不过之前饱受诟病的 renderToStringrender 的性能同时也得到了较大的提升(可以在Benchmark中看到),一下子拉近了和其他强调渲染性能的替代者的距离。

另外倍受关注的流式渲染也终于合并到主干了!我们之前甚至考虑过使用react-dom-stream来替换掉 ~renderToString~,这下可以直接使用官方的异步方案了。效果如何不好说,但起码增加了更多可能性。而同时Preact等并没有Stream方案。

再次,从优化的角度来看,框架都是在演化的。今天我们可以为了性能换上Preact,明天也许就要为了性能去换上Xreact。然而不管摩尔定律有没有失效,硬件、网络环境终归是在不断发展的,这些通过换库带来的一些体积、执行时间上的节省,半年、一年之后也许就微乎其微,而我们之前的工作也就没有任何意义。

Benchmark

最后口说无凭,对React、React@15、Fast React、Preact做了一个benchmark。react-static是指调用 renderToStaticMarkup 时的数据。结果如下:

Server

-

fast-react

preact

react

react-static

react15

1000 times

3.00

4.00

7.00

3.25

7.75

200000 times

311.00

443.00

557.00

297.50

805.50

可以看到React@16相比React@15已经提升了1/3,接近Preact的成绩了。

另外值得注意的是 renderToStaticMarkup 其实性能相当不错。如果你确定可以放弃checksum,希望寻找一个更快的服务器端渲染方式,不如直接使用 renderToStaticMarkup

你也可以clone https://github.com/raxjs/server-side-rendering-comparison 来对比React@16 & React@15,相信会得到类似的结论。

Client

Client是使用Chrome Headless模式来测试的。

Fast-React的浏览器端直接使用React@16来渲染。Preact的render方法因为默认是append行为,所以增加了一个preact-replace来和React行为做对比。

parse时长是调用 renderToString , renderToStaticMarkup, preact.render 方法的时间。load时间为 performance.timing.responseStart 到render结束后的时间。

-

fast-react

preact

preact-replace

react

react-static

react15

1000 times

parse: 14.00,load: 79.75

parse: 10.75,load: 39.25

parse: 15.25,load: 34.00

parse: 10.25,load: 79.00

parse: 14.50,load: 80.25

parse: 18.00,load: 93.75

200000 times

parse: 1312.00,load: 9219.50

parse: 1805.25,load: 9571.50

parse: 1808.75,load: 9573.50

parse: 708.75,load: 9604.50

parse: 1350.00,load: 9256.25

parse: 2144.25,load: 11130.50

React@16在浏览器端渲染性能提升了一倍多,成绩相当不错。而且得益于checksum的加持,如果checksum是一致的(react栏),React的渲染时间在DOM节点较少的时候与Preact一致,在节点很多的情况下比Preact、其他方案的成绩要好一大截。

而由于Preact体积的优势,在节点较少的情况下load时长相当短,相信在低速网络、低端设备下会有更好的性能表现。

其中还有一个有意思的一点,在200000节点的情况下,虽然React的render时间很短,但最后的load时间却不是最短的。自然是由于每个DOM节点上增加的 data-reactid 导致HTML下载、解析时间变长。不过React Team也考虑过彻底移除data-reactid,也许未来某个版本会得到修改,而那时直接使用React渲染同构应用将肯定是性能最佳的选择之一。

小结

很兴奋React@16在性能方面做了这么多优化,相信绝大多数情况下我已经不用考虑其他的替代方案了。当然也有例外:

  • 当你的目标用户网络环境比较糟糕时:之前的测试主要是基于执行速度来考察的。然而React毕竟有40多K,比起Preact还是要大不少。在开发m.uber里,提到了多次2G网络,我觉得也是影响Uber工程师选择Preact的关键因素。如果你的用户主要使用2G网络,可以考虑一些替代方案。(当然这也是违反我们「面向未来」的观点的,uber工程师也有可能也是为了替换Preact而找的理由……
  • 从零开始一个项目,不喜欢React:这种情况下,请随意……

(完)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网杂技

IOS 10锁屏界面不好用?来看这份严肃的交互分析!

iOS说:“清晰度,咱俩分手吧”。以往的iOS锁屏界面非常简单直接,但是来到今年的iOS10,情况发生非常大的变化,在开始认真严肃地为大家分析(tucao)之前...

3177
来自专栏腾讯社交用户体验设计

滑屏 H5 开发实践九问 - 腾讯ISUX

作为一个 UI工程师,接过很多类似的项目,也曾写过滑屏的插件,在经历了不同的需求的“洗礼”并踩过若干个坑之后,不禁反问自己...

3664
来自专栏杨建荣的学习笔记

Bootstrap相关项目推荐

Bootstrap这些年火得如日中天,去招聘网站一搜,非常的多,前端已经不是传统意义上的前端技术了,而是大前端技术,原来的DW这些工具也走到了历史的尽头。现在的...

3587
来自专栏C语言及其他语言

一张图看懂一个知识点

一段 While 说明了程序员的每一天 ? ? 压缩的原理 ? 很想找几根网线插上 ? CSS 的作用 ? ? 客户想要 VS 客户预算 ? 关于浏览器。。。 ...

2876
来自专栏腾讯大讲堂的专栏

滑屏 H5 开发实践九问 - 腾讯ISUX

滑屏的交互形式自从在 H5 中流行起来,便广泛应用在产品宣传、广告、招聘和活动运营等场景中,作为微信朋友圈广告惯用的形式,其影响力更是得到了强化与放大。如今滑屏...

5307
来自专栏Android 开发者

为长屏幕设备做好准备

1663
来自专栏分子生物和分子模拟计算

如何建立膜蛋白体系的动力学模型

1724
来自专栏互联网杂技

一个独立开发者总结的App 迭代设计思路

Overcast3发布了,这是一个巨大的版本迭代,主要体现在界面的设计和流程。根据两年多的测试、使用和用户反馈,从上个夏天开始,我一直在为这个版本而努力工作。 ...

3619
来自专栏玉树芝兰

Markdown懒办法排版微信公众号文章

写微信公众号的人群里面,不乏十分勤奋者。看看他们使用的排版工具,便知道为了排版一篇文章,他们要耗费多少辛劳了。

2492
来自专栏非著名程序员

AndroidTShare Weekly No.8

非著名程序员技术周报第八期,我们今天来回顾一下本周技术文章的分享和哪些热点开源项目,以及相关技术新闻。看过上期的同学都知道,周报改版了,不仅仅只是回顾重复的技术...

2037

扫码关注云+社区

领取腾讯云代金券