最专业的八方代购网站源码!

资讯热点
高级技术:通过调整JavaScript性能来提高Web应用程序性能

发布时间:2019-12-17 分类: 行业资讯

前言

在当今的Internet应用程序中,Web开发中经常遇到性能问题,尤其是当今的Web 2.0+应用程序。 JavaScript是当今使用最广泛的Web开发语言。 Web应用程序的许多性能问题是由程序员编写的JavaScript脚本性能不佳引起的,包括JavaScript语言本身的性能问题及其与DOM的交互。性能问题。本文重点介绍如何尽可能多地避免这些问题,以最大限度地提高Web应用程序的性能。

1.JavaScript性能调优

由于其双线程和解释执行功能,JavaScript语言确定它在许多地方存在性能问题,因此有许多方面需要改进。

1.1评估问题:

比较以下代码:

清单1. eval的问题

带有'eval'的代码比没有'eval'的代码慢100倍。

主要原因是JavaScript代码在执行之前将执行类似'precompilation'的操作:首先在当前执行环境中创建一个活动对象,并将那些用var声明的变量设置为活动对象的属性,但此时变量的赋值是未定义的,函数定义的函数也作为活动对象的属性添加,它们的值正是函数的定义。但是,如果使用'eval','eval'(实际上是字符串)中的代码无法预先识别其上下文,也无法提前解析和优化,即无法进行预编译。因此,它的性能将大大降低。

1.2功能的使用

比较以下代码:

清单2.函数的用法

这与前面提到的'eval'方法类似,其中'func1'的效率远低于'func2',因此推荐使用第二种方法。

1.3函数的范围(范围链)

JavaScript代码解释执行。进入该功能时,它会预先分析当前变量并将它们分配到不同的级别。一般来说:

局部变量放在1级(轻)中,全局变量放在2级(深层)。如果您输入'with'或'try–捕获'代码块,将添加一个新级别,将变量放入“with”或“catch”到最浅层(第1层)并加深之前的级别。 。

请参阅以下代码:

清单3.函数作用域链

在这里我们可以看到'images','widget','combination'属于局部变量,在第1层''document','myObj'属于全局变量,在第2层。

变量所在的层越浅,访问(读取或修改)速度越快,层越深,访问速度越慢。所以这里的'images','widget','组合'访问速度比'document','myObj'快。因此,建议尽可能使用局部变量,请参阅以下代码:

清单4.使用局部变量

我们用局部变量'doc'替换了全局变量'document',这提高了性能,特别是对于广泛使用全局变量的函数。

请查看以下代码:

清单5.谨慎使用

使用'with'关键字,我们可以使代码更简洁明了,但性能会受到影响。正如我之前所说,当我们进入'with'代码块时,'组合'从原始的第1层变为第2层,因此效率大大降低。所以比较一下,仍然使用原始代码:

清单6.使用

进行改进

但这不是最好的方法。 JavaScript有一个功能。对于对象对象,属性访问级别越深,效率越低。例如,'myObj'在这里可以访问第3层,我们可以像这样改进它:

清单7.缩小对象访问级别

我们用局部变量替换'myObj'第2层的'container'对象。如果您对对象的深层属性有大量此类访问权限,则可以参考上述内容来提高性能。

1.4字符串(字符串)相关

字符串拼接

我经常看到这段代码:

清单8.简单拼接字符串

Str +='str1'+'str2'

这是我们拼接字符串的常用方法,但这样会创建和销毁一些临时变量,从而影响性能,因此建议使用以下方式:

清单9.字符串数组拼接

Var str_array=[];

Str_array.push( 'STR1');

Str_array.push( 'STR2');

Str=str_array.join('');

这里我们使用数组的'join'方法来实现字符串连接,特别是在旧版本的Internet Explorer(IE6)上运行时,会有显着的性能提升。

当然,最新的浏览器(如Firefox Firefox 3 +,IE8 +等)优化字符串连接,我们也可以写:

清单10.字符串拼接

Str +='str1'

Str +='str2'

新浏览器针对'+='进行了优化,并且执行速度略快于数组的'join'方法。在不久的将来更新版本浏览器也可以优化'+',所以那时我们可以直接写:str +='str1'+'str2'。

隐式类型转换

请参阅以下代码:

清单11.隐式类型转换

这里我们在每个循环中调用字符串'charAt',但由于我们将常量'12345678'赋值给'str','str'实际上不是一个字符串对象,每次调用'charAt'函数时,它暂时构造一个值为'12345678'的字符串对象,然后调用'charAt'方法,最后释放字符串临时对象。我们可以做一些改进:

清单12.避免隐式类型转换

这样,作为字符串对象的变量'str'将不具有这种隐式类型转换过程,并且效率将显着提高。

字符串匹配

JavaScript有一个RegExp对象,支持对字符串进行正则表达式匹配。这是一个很棒的工具,但它的性能不是很好。相反,字符串对象(String)的一些基本方法非常有效,例如'substring','indexOf','charAt'等,当我们需要将字符串与正则表达式匹配时,你可以考虑:

1)问题是否可以通过字符串对象本身支持的基本方法来解决。

2)是否可以缩小'substring'所需的正则表达式的范围。

这些方法可以有效地提高程序的效率。

对于正则表达式对象,还有一点需要注意,请参考以下代码:

清单13.正则表达式

在这里,我们将'/^ s * extras /'传递给'match'方法,这会影响效率。它将构建一个临时值为'/^ s * extras /'的正则表达式对象,并执行'match'方法。然后销毁临时正则表达式对象。我们可以这样做:

清单14.使用变量

这不会有临时对象。

setTimeout和setInterval

两个函数'setTimeout'和'setInterval'可以接受字符串变量,但会带来类似于前面提到的'eval'的性能问题,所以建议直接传递函数对象本身。

使用提前退出

请参阅以下两段代码:

清单15.利用提前退出

代码2对'name.indexOf(…)'有更多的判断,它使程序在每次进入本节时执行'indexOf'判断,然后以'indexOf'比率执行以下'匹配' 。在“匹配”效率更高的前提下,这样做会减少“匹配”的执行次数,从而在一定程度上提高效率。

2. DOM操作性能调优

JavaScript的开发与DOM的操作密不可分,因此DOM操作的性能调优在Web开发中也非常重要。

2.1重绘和回流

重绘也称为重绘,它指的是不影响当前DOM的结构和布局的重绘动作。以下操作将生成重绘操作:

可见(可见性样式属性)

颜色或图像更改(背景,边框颜色,颜色样式属性)

不会更改页面元素的大小,形状和位置,但会更改其外观更改

回流是一个比重绘更重要的变化。它主要发生在操作DOM树时,对DOM结构和布局的任何更改都会产生Reflow。但是,当元素的Reflow操作发生时,它的所有父元素和子元素都将被重排,最后Reflow将不可避免地导致重绘。例如,以下操作将生成重绘操作:

浏览器窗口更改

添加和删​​除DOM节点的操作

一些触发器可以改变页面元素的大小,形状和位置

2.2减少回流

根据Reflow和Repaint的介绍,每次Reflow带来的资源消耗都比Repaint多,我们应该尝试减少Reflow的发生,或者将其转换为仅触发Repaint操作的代码。

请参阅以下代码:

清单16.重排简介

这是我们经常联系的代码,但是这段代码会产生3次回流。请查看以下代码:

清单17.减少重排

这里只有一个reflow,所以我们推荐这个DOM节点的运行方式。

对于上述解决方案,还有一些模式可以参考,以减少回流操作:

清单18.使用display来减少reflow

首先隐藏pDiv,然后显示它,以便隐藏和显示之间的操作不会产生任何Reflow,从而提高效率。

2.3特殊测量属性和方法

DOM元素中有一些特殊的测量属性访问和方法调用,它们也会触发Reflow,它通常是'offsetWidth'属性和'getComputedStyle'方法。

图1.特殊测量属性和方法

这些测量属性和方法大致如下:

· offsetLeft

·的offsetTop

·的offsetHeight

· offsetWidth

· scrollTop的/左/宽度/高度

· clientTop /左/宽度/高度

·的getComputedStyle()

· currentStyle(在IE中))

访问和调用这些属性和方法将触发Reflow的生成。我们应该最小化这些属性和方法的访问和调用,请参考以下代码:

清单19.特殊测量属性

在这里,我们可以使用临时变量缓存'offsetWidth'的值,这样我们就不必每次都访问'offsetWidth'属性。这种方法在循环中运行良好,可以大大提高性能。

2.4风格相关

我们肯定会看到以下代码:

清单20.与样式相关的

但是你可以看到这里的每个样式更改都会产生Reflow。我们需要减少这种情况,我们可以这样做:

解决方案1:

清单21. className解决方案

通过将class替换为样式,可以将所有先前的Reflow或Repaint的数量减少为1。

解决方案2:

清单22. cssText解决方案

一次设置所有样式也是降低Reflow性能的一种方法。

2.5 XPath

页面通常包含超过1000个页面元素,并且通常需要一定的时间来定位特定元素。如果您使用id或name来定位它可能不会太慢​​,如果您使用该元素的某些其他属性(例如className等)进行定位,则可能效率较低。有些人可能只能通过遍历所有元素(getElementsByTagName)然后过滤它们来找到所有元素。这甚至更低效。在这里,我们建议使用XPath来查找元素,这是许多浏览器支持的功能。

清单23. XPath解决方案

Browser XPath的搜索引擎可以优化搜索效率并大大缩短结果的返回时间。

2.6 HTMLCollection对象

这是一种特殊的对象,它们有点像数组,但不完全是数组。以下方法的返回值通常是HTMLCollection对象:

· document.images,document.forms

·的getElementsByTagName()

· getElementsByClassName方法()

这些HTMLCollection对象不是固定值,而是动态结果。它们是一些特殊查询的返回值。在下列情况下,它们将重新执行上一个查询以获取新的返回值(查询结果),尽管在大多数情况下它将与前一个或多个返回值相同。 :

·长度属性

·特定成员

因此,HTMLCollection对象对这些属性和成员的访问速度比数组慢得多。当然也有例外。 Opera和Safari可以很好地处理这种情况,并且没有太多的性能问题。

请参阅以下代码:

清单24. HTMLConnection对象

代码的上面两端,下面的效率比上面的段慢得多,因为每个循环都会有一个'items.length'触发器,这将导致'document.getElementsByTagName(..)'方法被再次调用,这就是为什么效率会急剧下降的原因。我们可以这样解决:

清单25. HTMLConnection对象解决方案

这样,效率基本上与普通阵列相同。

2.7动态创建脚本标记

加载和执行JavaScript脚本需要时间。在我们的程序中,有时一些JavaScript脚本在加载后基本上不使用(例如,脚本中的函数从不被调用,等等)。加载这些脚本只会占用CPU时间并增加内存消耗,从而降低Web应用程序的性能。因此,建议动态加载JavaScript脚本文件,尤其是那些内容更多且消耗更多资源的脚本文件。

清单26.创建脚本标记

写在最后

本文介绍了有关Web开发性能的一些小细节。从JavaScript本身开始,我介绍了JavaScript中需要避免的一些函数的使用和编程规则,例如eval的缺点,函数作用域链和String的用法。等等,还共享了一些推荐的实践,并扩展到JavaScript以调整DOM操作的性能调优,例如使用Repaint和Reflow机制,如何使用特殊测量属性,与样式相关的性能调整以及HTMLCollection对象的原理。使用提示。在开发过程中,可以尽可能多地采用这些小细节,以最大限度地提高Web应用程序的性能。

« 如何根据SEO优化在新代购源码网站上发表文章 | 如何写移动终端的内容?这是BBC为您提供的6个优化提示2 »