个人常用JavaScript及React常用优化总结

零信任架构
• 阅读 3051

JavaScript 插件性能优化及个人react常用优化方法


JavaScript 经常会触发视觉变化。有时是直接通过样式操作,有时是会产生视觉变化的计算,例如搜索数据或将其排序。时机不当或长时间运行的 JavaScript 可能是导致性能问题的常见原因。您应当设法尽可能减少其影响。

JavaScript 性能分析可以说是一门艺术,因为您编写的 JavaScript 代码与实际执行的代码完全不像。现代浏览器使用 JIT 编译器和各种各样的优化和技巧来尝试为您实现尽可能快的执行,这极大地改变了代码的动态。

注:如果您真的想了解 JIT 的实例,应当查看 Vyacheslav Egorov 提供的 IRHydra2。它显示了当 Chrome 的 JavaScript 引擎 V8 对 JavaScript 代码进行优化时,JavaScript 代码的中间状态。

尽管如此,您肯定还是可以做一些事情来帮助您的应用很好地执行 JavaScript。但 Javascript 性能优化绝不是一种书面的技术,借鉴别人的意见和自己平时项目的总结给出以下几条建议:

变量问题

当一个变量被引用的时候,JavaScript将在作用域链中的不同成员中查找这个变量。作 用域链指的是当前作用于下可用变量的集合,它在各种主流浏览器中至少包含两个部分:局部变量的集合和全局变量的集合。

简单地说,如果JavaScript引擎在作用域链中搜索的深度越大,那么操作也就会消耗更多的时间。引擎首先从 this 开始查找局部变量,然后是函数参数、本地定义的变量,最后遍历所有的全局变量。

因为局部变量在这条链的起端,所以查找局部变量总是比查找全局变量要块。所以当你想要不止一次地使用一个全局变量的时候,你应该将它定义成局部变量,就像这样:

var dom1 = document.getElementById('id1'),
dom2 = document.getElementById('id2');

改写成

var document = document,
demo1 = document.getElementById('id1'),
demo2 = document.getElementById('id2');

小心的使用闭包

虽然你可能还不知道“闭包”,但你可能在不经意间经常使用这项技术。闭包基本上被认为是JavaScript中的new,当我们定义一个即时函数的时候,我们就使用了闭包,比如:

document.getElementById('dom').onclick = function(ev) { };

闭包的问题在于:根据定义,在它们的作用域链中至少有三个对象:闭包变量、局部变量和全局变量。这些额外的对象将会导致第1和第2个建议中提到的性能问题。

闭包对于提高代码可读性等方面还是非常有用的,只是不要滥用它们(尤其在循环中)。

对象的属性和数组元素影响

谈到JavaScript的数据,一般来说有4种访问方式:数值、变量、对象属性和数组元素。在考虑优化时,数值和变量的性能差不多,并且速度显著优于对象属性和数组元素。

因此当你多次引用一个对象属性或者数组元素的时候,你可以通过定义一个变量来获得性能提升。(这一条在读、写数据时都有效)

虽然这条规则在绝大多数情况下是正确的,但是Firefox在优化数组索引上做了一些有意思的工作,能够让它的实际性能优于变量。但是考虑到数组元素在其他浏览器上的性能弊端,还是应该尽量避免数组查找,除非你真的只针对于火狐浏览器的性能而进行开发。

不要乱碰DOM

不使用DOM是JavaScript优化中另一个很大的话题。经典的例子是添加一系列的列表项:如果你把每个列表项分别加到DOM中,肯定会比一次性加入所有列表项到DOM中要慢。这是因为DOM操作开销很大。

Zakas对这个进行了细致的讲解,解释了由于回流(reflow)的存在,DOM操作是非常消耗资源的。回流通常被理解为浏览器重新选渲染DOM树的处理过程。比如说,如果你用JavaScript语句改变了一个div的宽度,浏览器需要重绘页面来适应变化。

任何时候只要有元素被添加到DOM树或者从DOM树移除,都会引发回流。使用一个非常方便的JavaScript对象可以解决这个问题——documentFragment,我并没有使用过,但是在Steve Souders也表示同意这种做法之后我感觉更加肯定了。

DocumentFragment 基本上是一种浏览器以非可视方式实现的类似文档的片段,非可视化的表现形式带来了很多优点,最主要的是你可以在 documentFragment 中添加任何结点而不会引起浏览器回流。

不要在数组中挖得太深

另外,程序员应该避免在数组中挖得太深,因为进入的层数越多,操作速度就越慢。

简单地说,在嵌套很多层的数组中操作很慢是因为数组元素的查找速度很慢。试想如果操作嵌套三层的数组元素,就要执行三次数组元素查找,而不是一次。

因此如果你不断地引用 foo.bar, 你可以通过定义 var bar = foo.bar 来提高性能。

定时器的使用

如果针对的是不断运行的代码,不应该使用setTimeout,而应该是用setInterval,因为setTimeout每一次都会初始化一个定时器,而setInterval只会在开始的时候初始化一个定时器。

        var timeoutTimes = 0;
        function timeout() {
            timeoutTimes++;
            if (timeoutTimes < 10) {
                setTimeout(timeout, 10);
            }
        }
        timeout();
        //可以替换为:
        var intervalTimes = 0;
        function interval() {
            intervalTimes++;
            if (intervalTimes >= 10) {
                clearInterval(interv);
            }
        }
        var interv = setInterval(interval, 10);

React上的性能优化

对于小型react前端应用,最好的优化就是不优化因为React本身就是通过比较虚拟DOM的差异,从而对真实DOM进行最小化操作,小型React应用的虚拟DOM结构简单,虚拟DOM比较的耗时可以忽略不计。而对于复杂的前端项目,我们所指的渲染性能优化,实际上是指,在不需要更新DOM时,如何避免虚拟DOM的比较。

  1. react组件的生命周期

    工欲善其事,必先利其器。理解react的组件的生命周期是优化其渲染性能的必备前提。我们可以将react组件的生命周期分为3个大循环:挂载到DOM、更新DOM、从DOM中卸载。React对三个大循环中每一步都暴露出钩子函数,使得我们可以细粒度地控制组件的生命周期。
    
    • 挂载到DOM

      组件首次插入到DOM时,会经历从属性和状态初始化到DOM渲染等基本流程,可以通过下图所示
      

      个人常用JavaScript及React常用优化总结

必须注意的是,挂载到DOM流程在组件的整个生命周期只有一次,也就是组件第一次插入DOM文档流时。在挂载到DOM流程中的每一步也有相应的限制:
  • 更新DOM

     组件挂载到DOM后,一旦其props和state有更新,就会进入更新DOM流程。同样我们也可以通过一张图清晰的描述该流程的各个步骤:
    
    //getDefaultProps()和getInitialState()中不能获取和设置组件的state。
    //render()方法中不能设置组件的state。

    个人常用JavaScript及React常用优化总结

    componentWillReceiveProps()提供了该流程中更新state的最后时机,后续的其他函数都不能再更新组件的state了。我们尤其需要注意的是shouldComponentUpdate函数,它的结果直接影响该组件是不是需要进行虚拟DOM比较,我们对组件渲染性能优化的基本思路就是:在非必要的时候将shouldComponentUpdate返回值设置为false,从而终止更新DOM流程中的后续步骤。
    
  • 从DOM中卸载

     从DOM中卸载的流程比较简单,React只暴漏出componentWillUnmount,该函数使得我们可以在DOM卸载的最后时机对其进行干预。
    

2、性能分析


   合理的使用shouldComponentUpdate()可以在很大程序上优化应用。但在实际情况下,应用往往在沙箱或是开发环境中运行的非常快,但生产环境则表现的不尽人意。这时,我们需要对应用进行性能分析,然后再有针对性的在shouldComponentUpdate()中进行优化。

React 提供了性能分析插件React.addons.Perf,它让我们可以在需要检测的代码起始位置分别添加Perf.start()和Perf.stop(),并可以通过Perf.printInclusive()方法打印花费时间,然后我们可以结合数据做进一步的分析。

React.addons.Perf插件的详细用法,可以查看官方文档。

3、 借助react Key标识组件


key属性在组件类之外提供了另一种方式的组件标识。通过key标识我们可以组件如:顺序改变、不必要的子组件更新等情况下,告诉React 避免不必要的渲染而避免性能的浪费。

如,对于如一个基于排序的组件渲染

var items = sortBy(this.state.sortingAlgorithm, this.props.items);
return items.map(function(item){
  return <img src={item.src} />
});

当顺序发生改变时,React 会对元素进行diff操作,并改img的src属性。显示,这样的操作效率是非常低的。这时,我们可以为组件添加一个key属性以唯一的标识组件:

    return <img src={item.src} key={item.id} />
点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Karen110 Karen110
4年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Sherwei Sherwei
3年前
JavaScript学习资源大全
在线文档类|名称及链接|特点|评分||||||现代JavaScript教程(https://zh.javascript.info/)|是React与MDN并列推荐的JavaScript学习教程,以最新的JavaSc
待兔 待兔
4年前
12个有用的JavaScript数组技巧
数组是Javascript最常见的概念之一,它为我们提供了处理数据的许多可能性,熟悉数组的一些常用操作是很有必要的。1、数组去重1、from()叠加newSet()方法字符串或数值型数组的去重可以直接使用from方法。varplants'Saturn','Earth','Uranus','Mercury','Venus','Earth',
Souleigh ✨ Souleigh ✨
5年前
Javascript 常用代码优化和重构的方法
简介主要介绍以下几点:1.提炼函数2.合并重复的条件片段3.把条件分支语句提炼成函数4.合理使用循环5.提前让函数退出代替嵌套条件分支6.传递对象参数代替过长的参数列表7.少用三目运算符8.合理使用链式调用9.分解大型类10.活用位操作符11.纯函数本文会不断更新,不足之处欢迎
凯特林 凯特林
4年前
安利一些强无敌的 NPM 软件包
实用工具Lodashlodash是一套现代JavaScript实用程序库,提供模块化、性能与多种附加功能。可提供关于JavaScript数组、对象及其他数据结构的多种实用功能。安装及示例yarnaddlodash不要滥用,尽量使用ES自带方法 。我常用的一些方法如下//深度比较两个对象的值是否全相等importisEqu
Stella981 Stella981
4年前
26种JavaScript优化技术
开发人员的生活总是在学习新事物。作为前端开发人员必须知道一些使我们的代码如何更优雅,工作更轻松的技巧。也许你已经进行了很长时间的JavaScript开发,但有时你可能没有使用不需要解决或编写一些额外代码即可解决问题的最新功能。这些技术可以帮助你编写干净且优化的JavaScript代码。1\.多个条件判断//lo
Stella981 Stella981
4年前
JavaScript 常用功能总结
编吐血整理加上翻译,太辛苦了~求赞!本文主要总结了JavaScript常用功能总结,如一些常用的额JS对象,基本数据结构,功能函数等,还有一些常用的设计模式。目录:众所周知,JavaScript是动态的面向对象的编程语言,能够实现以下效果:1\.丰富Web网页功能2\.丰富Web界面3\.实现本地或远程存储。4\.实
Stella981 Stella981
4年前
JavaScript性能优化
❝性能优化是一个很大的概念,性能优化的方向有很多比如底层、框架层面上、页面上等等,本篇文章介绍的是JavaScript语言的优化,了解JavaScript的运行的机制❞本片文章主要从如下几个方面讲解:内存管理垃圾回收与常见GC算法V8引擎的垃圾回收Perf
Stella981 Stella981
4年前
JavaScript 性能优化技巧分享
JavaScript作为当前最为常见的直译式脚本语言,已经广泛应用于Web应用开发中。为了提高Web应用的性能,从JavaScript的性能优化方向入手,会是一个很好的选择。本文从加载、上下文、解析、编译、执行和捆绑等多个方面来讲解JavaScript的性能优化技巧,以便让更多的前端开发人员掌握这方面知识。什么是高性能的JavaScr
Stella981 Stella981
4年前
JavaScript 性能优化
更多文章(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fwoai3c%2FFrontendarticles)