ReactJS修炼之路(四):组件的性能优化及开发思路

来源:互联网 发布:上海淘宝设计速成班 编辑:程序博客网 时间:2024/05/17 23:33

少年,加油

昨天周五,那个喊我“少年”的朋友离职了去新加坡了,我的实习生涯又错过了一位大神,不过短短一个月还是被影响不少,例如入坑happy hacking keybord同时学习各类软件的快捷键,例如开始用sass,例如初次使用
flexbox…

人生何处不相逢,谢谢你的指导,我会更加努力,也祝你更进一步,加油。


回看,事情总有千丝万缕的联系,但是往前,都是迷雾,保持迷茫,保持思考,做好现在,是我最大的感悟。

之所以要说上面那些,是和这篇博客相关的,写React也有半年多了,虽然都是零零散散地写并没有太多提高,但实践总是好的,例如今天在做一个项目的首屏性能优化的时候,就顿悟了一些开发思路,感觉过去看到各种博客,与人交流的各种想法都零星地串联了起来。

下面简单分享一下我的组件优化思路及开发思路,不是最佳实践,只是个人一些感触。


缘由

昨晚开始看React后端渲染的内容,其实项目的第一版就是纯后端渲染的,后来使用React-router改版成SPA,再后来进行了前后端分离,方便前端人员开发,因为后台是Rails,虽然也可以搞同构,不过支持rails的react-router版本太低(现在前端部分是webpack构建的),不好往回迁。

也想了一些方案,例如使用首屏后端模板渲染,同时加载前端资源,前端渲染完毕后替换首屏内容,实现起来不优雅,放弃了。

忽然想到,产品最重要的是体验,说不定加载慢(2.5s)并不是体验的最短板呢?

于是先不考虑后端渲染,但也做了一些微小的改进,后端页面返回显示loading效果(svg实现loading),前端渲染完成后,会有一个缩放渐现的过程,整体体验还不错,gif制造帧率低看着效果一般,在手机上超赞,安卓手机SVG动画有点卡,待调研解决。
web app首页加载效果

在拿不同手机测试这个首屏加载效果的时候,无意中发现,这个web应用首屏操作不够流畅,于是就甩开手上的6s,借了舍友淘汰下来安卓机做测试,真是卡到不行。

忽然觉得前端工程师就应该用落后两年左右的手机,这样才能真正确保产品质量。(开个玩笑,别在意)


优化思路

最近在网上看到一份谷歌的web app开发教程,内容比较多,还没看完,所以还不知道怎么评测性能,目前最直观的就是,加载速度(白屏时间),操作流畅度。

我的思路很简单,也很有效,直接在各个组件的render函数里console.log("xxx render")到控制台,观察每个组件的渲染次数,减少不必要的渲染。

下面总结一下,什么情况下会出现不必要的render,怎么减少。

  1. 父组件里面的子组件排序引起子组件render,其实这个时候子组件的内容是没有任何改变的,只是子组件所在的位置改变而已,按理说子组件是不需要render的。解决方法:shouldComponentUpdate,判断内容不变就跳过更新,如果内容是一直不变的,推荐直接return false,省去判断的成本。

  2. 有些组件会先加载,再异步请求数据,再重新渲染,会出现两次render(不推荐这种做法,下文将开发思路会讲到),解决方案,在render函数里面进行判断,如果没有数据,直接return <div>没有数据时候的提示信息</div>

还有一个小小的点:

  • React组件render很频繁,所以render函数里面尽量减少操作,例如:
//每次都会循环生成相同的内容,性能差<div className="swiper-pagination">{  [1,2,3].map( function(i) {    return <span className="swiper-pagination-bullet"></span>  } )}</div>//性能要好一些<div className="swiper-pagination">  <span className="swiper-pagination-bullet"></span>  <span className="swiper-pagination-bullet"></span>  <span className="swiper-pagination-bullet"></span></div>

上面只提到了两种情况和方案,把这两个做好性能应该不是大的问题了,总之,核心还是,找到不必要的render,尽量避免


开发思路

simple is the best.

正因为做性能优化才有了组件开发思路的感悟和改进,真觉得以前是随便乱写,哈哈,不过厉害的地方在于,随便乱写的代码竟然能运行,但人终归要成长,标准也在提高。

说开发思路之前,有空的同学先去温习React组件生命周期,这个非常重要。

之前看过一段时间Redux,对于里面的容器组件和展示组件并不是太了解,然而今天好像有点能体会什么是容器组件和展示组件了,简而言之,展示组件只做展示,容器组件封装了数据获取和数据操作的逻辑(没有上手redux,望指正)

下面直接上展示组件的代码(旧的react代码风格,别吐槽):

var component = React.createClass({  getInitialState: function() {    //状态初始化(第一轮执行)    //可用于类型检查  },  componentDidMount: function() {    //组件加载完成执行的动作(第一轮执行)  },  componentWillReceiveProps: function(nextProps) {    //props更新,用于设置state(第二轮开始执行)    //注意,这里setState并不会引发新的一轮更新  },  shouldComponentUpdate: function() {    //决定组件是否更新(第二轮开始执行)    return false/true;  },  render: function() {    //渲染内容    console.log("render");  }});

上面几个生命周期函数摆放的位置是特意调整的,现在我们来走一遍流程,父组件通过设置子组件的props传递数据,此时组件调用getInitialState,初始化状态,然后组件执行render完成渲染,展示组件就是那么简单,到这里只是渲染了一次,这个时候,父组件要是再次render,会影响到子组件,子组件会调用componentWillReceiveProps来更新组件状态,再调用shouldComponentUpdate来确定是否跳过render。遵循这个开发思路不仅能使开发的时候保持清晰的逻辑,也在开发的时候保证了组件的性能,不用想我上面那样修修补补。


总结

  • 多看官博,了解核心思想
  • 多写代码,不止于demo,去写项目,去解决问题

以前总喜欢问别人最佳实践,后来发现,如果你去问别人,那别人告诉你多半也听得一知半解。

规划重要,实践也重要,最重要的是在已有前提下想办法做到自己想要的效果,而不是抱怨自己当初没考虑周全,生活也是如此。

写码路上没有捷径,去创造,去超越,少年。

0 0
原创粉丝点击