[关闭]
@ghostcdy 2016-01-29T05:42:23.000000Z 字数 3462 阅读 396

移动端ReactJS应用实践报告

未分类


说到React,已经不是什么新名词了。组件化、单向数据流、虚拟DOM、JSX语法模板,听起来都很高大上,对这些就是React的特性,改变了我们的编码习惯,给我们带来了很多好处:

  1. JSX的模板语言,方便的从重构稿转化为模板,同时支持服务端渲染,完全解决了SEO长期困扰JavaScript单页应用的问题;
  2. 简单的写前端逻辑,可完全忘掉DOM的依赖操作;
  3. 组件化和单向数据流极大的简化了前端架构的理解难度。

夸了ReactJS那么多,我们也要用用。目前,我们的移动端业务“公会总大厅”终于上线。duang!duang!duang!坑,用新东西总是有坑嘀。下面总结一下使用ReactJS做业务的一些坑和解决方案:

学习成本

又到PK的时候了,React好不好?
1.jpg-171kB
ReactJS学习成本对比:

框架 特性 学习成本
ReactJS 专注UI层,只做渲染,组件化,单向数据流 API少,有新感念,有门槛
AngularJS 严格的模型层次,双向绑定 API多,完整的体系,学习曲线陡

简单来说,新东西上手有门槛。不过学会的真的很好用,真的很好用,真的很好用。看,React的入门书籍,很薄,快速上手:
images.jpg-10kB

开发成本

由于有生命周期,开发过程分组件,开发成本比使用普通的js模板开发量略大。但组件化思路清晰,开发体验还是不错的。附上,一个组件的大致结构:
QQ截图20160128115555.png-32.7kB
QQ截图20160128115454.png-78.7kB
ps:React专注渲染层。开发过程中,为了提高开发效率降低维护成本,我们为React制造了身体Reduck。
QQ截图20160128150040.png-17.4kB

维护成本

性能

加载

先看下React的库大小,gzip压缩后为39k
react大小.png-29.2kB

渲染性能

React有虚拟节点,强大的更新对比算法,仅变更实际发生变化的部分。听上去很酷很强大,下面我们来做一下实验。
我们首先来看下渲染10000个结点长列表页面的耗时对比:

渲染用例 PC端10000个节点 iPhone 6plus 10000个节点
React 106ms 6056ms
React直出DOM 137ms 9784ms
ejs 64ms 905ms
原生js 11ms 325ms
渲染用例 PC端10000个节点 iPhone 6plus 10000个节点
React 578ms 6056ms
React直出DOM 137ms 9784ms
ejs 64ms 905ms
原生js 517ms 11049ms

可见React初次渲染并不是那么的快,在移动端上更加形势更加恶劣。直出React模板,在终端中也还需要生成虚拟DOM。但从用户体验的角度上来说,用户React还没建立虚拟DOM时页面就已经显示了。因此初次渲染我们需要使用直出方式优化渲染。
React实验代码见下图:

  1. var max = 10000;
  2. window.time = [];
  3. //记录第一个时间点,开始执行React代码
  4. time[0] = new Date();
  5. //创建一个React组件(JSX写法)
  6. var List = React.createClass({
  7. //渲染组件
  8. render: function(){
  9. var lis = [];
  10. for(var i=0; i<max; i++){
  11. lis.push(
  12. <li>{i}</li>
  13. );
  14. }
  15. return (
  16. <ul>
  17. {lis}
  18. </ul>
  19. )
  20. },
  21. //React生命周期:渲染完成
  22. componentDidMount: function(){
  23. //打印渲染完成时间点
  24. setTimeout(function(){
  25. time[1] = new Date();
  26. console.log('React渲染完成:'+ (Number(time[1]) - Number(time[0])) );
  27. },0);
  28. }
  29. });
  30. ReactDOM.render(<List />, document.getElementById('container'));

React编译后代码:

  1. var max = 10000;
  2. window.time = [];
  3. time[0] = new Date();
  4. var List = React.createClass({
  5. render: function(){
  6. var lis = [];
  7. for(var i=0; i<max; i++){
  8. lis.push(React.createElement("li",{},i));
  9. }
  10. return (
  11. React.createElement('ul', React.__spread({}), lis)
  12. )
  13. },
  14. componentDidMount: function(){
  15. setTimeout(function(){
  16. time[1] = new Date();
  17. console.log('React渲染完成:'+ (Number(time[1]) - Number(time[0])) );
  18. },0);
  19. }
  20. });
  21. ReactDOM.render(React.createElement(List), document.getElementById('container'));

普通JS生成DOM代码:

  1. var max = 10000;
  2. window.time = [];
  3. time[2] = new Date();
  4. (function(){
  5. var a = '';
  6. for(var i=0; i< max; i++){
  7. a += '<li>' + i + '</li>';
  8. }
  9. document.getElementById('inner').innerHTML = '<ul>' + a + '</ul>';
  10. })();
  11. setTimeout(function(){
  12. time[3] = new Date();
  13. console.log('DOM innerHTML:'+ (Number(time[3]) - Number(time[2])));
  14. },0);

针对合适的场景使用ReactJS

上面说了那么多,ReactJS擅长的是更新组件,但生成一个react组件的成本其实挺高的。

不适合的场景:

适用场景:

使用ReactJS如何优化

  1. 【预编译JSX】本地计算JSX模板很耗时,建议使用webpack等构建工具先构建成原生js。
  2. 【shouldComponentUpdate优化】使用React生命周期中的shouldComponentUpdate人工控制是否更新,比React自动对比更高效。
  3. 【分离复杂逻辑减少组件复杂度】减小组件更新遍历范围,减小计算量。
    db349605c2f4e266387c39ffa191a9b51449538094.png-14.8kB
  4. 【嵌套组件延迟渲染】复杂组件内部可以延迟渲染。
    d8aca84e667a8a5ae9760fccbc509a03.png-32.8kB

优化方法请参考:http://km.oa.com/group/20251/articles/show/248609

总结

公会总大厅使用React后,开发成本和维护成本有一定程度的降低。组件化方便扩展,代码复用提高可维护性。React提供了一套完善的生命周期,让代码结构更加清晰。高效的虚拟DOM对比算法,自动变更变化区域,减少渲染成本。

但是,在移动端项目中使用还存在以下的问题:

  1. ReactJS库文件较大,如使用React必须结合直出、本地缓存等优化方式来提高加载体验。
  2. 操作需谨慎,扬长避短。ReactJS具有虚拟DOM比对算法,适合做DOM频繁变化的场景。计算开销来代替DOM渲染开销,可实现快速的小范围更新。但React初次生成DOM比普通innerHTML要慢。
  3. React很智能,不要妄想让他渲染看不到的结点。display=none的结点React不会渲染。曾经我们使用display:none脱离DOM树渲染的优化方式不奏效。

当然,在PC的项目中,CPU和网络都比移动端强,上面的问题也将不会成为最痛的痛点。选择适合业务的才是最好的。

PS:我们在开发React的过程中,为了开发更高效,整理出一套新的框架,帮助我们组织代码。我们将它命名为【reduck-icon.png-1kBReduck】。
框架持续更新中:http://km.oa.com/articles/show/271507
后续,将分享Reduck框架,敬请期待。

最后,React项目能见到初生的太阳,离不开导师jameszuo和PM jingyang的支持,以及小伙伴sesamewen不怕坑往上爬的坚持,感谢他们。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注