前端性能之js代码优化点

作用域

JavaScript执行时会构建一个作用域链,用来进行变量解析,全局执行上下文只有一个object变量,定义了js中所有变量和函数。当创建一个函数时,会出现产生一个新的局部作用域,以this、arguments和命名的形参以及其他局部变量和函数初始化。整个作用域链的顶端是活动的作用域,变量解析的顺序是首先从当前作用域查找,当查找到结果后就终止查询,否则就继续往上一层作用域查询,直到全局作用域为止。因此,一个比较大的变量如果在解析的过程中跨越多层作用域,就会比较影响性能。作用域在性能上的改进就是要减少跨越的层级。

使用局部变量

对于读写局部变量的速度是最快的,他们存在当前激活的作用域下,不过这个特性在Google的chrome浏览器和Safari4+的浏览器上并不明显,因为他们使用的v8和Nitro引擎的变量解析速度非常快,变量解析的层数的减少在速度上的提升较少。但是其他浏览器都是非常

明显的,特别是IE8、FireFox浏览器。

一个好的原则是:将任何不在当前作用域内的变量,且要使用2次及以上的,使用局部变量进行存储。

作用域变换

with语句在JavaScript中会将当前执行的作用域进行切换,在这个语句块内可以访问相应的对象属性。但实际上,这种方式是在执行上下文的作用域链前面插入了新的作用域,因此,当开始进入到with语句中时,对于当前执行上下文中的局部变量的解析会跨越多个作用域,会造成性能上的损失。因此需要避免使用with语句。

数据访问

读取和写入数据的方式一共有下面四种:

- 字面量

- 变量

- 数组

- 对象属性

字面量和局部变量基本可以忽略,对这些数据的访问基本对性能的提升占比可以不考虑。真正的区别是从数组和对象的属性中读取和写入数据。从这两个方式获取数据需要进行位置的搜索,包括使用索引下标和属性名称。在进行搜索时,最耗时的就是对象的属性,特别是多级属性的寻找非常耗时。

针对这个问题,最佳的方法就是使用局部变量将任何使用1次及以上的对象属性或者数组元素存储下来。

//原始版本
function procee(data){
    if(data.count > 0)
        for(var i = 0; i < data.count; i++)
            processData(data.item[i]);
}

//优化版本
function(){
    var cnt = data.count;
    if(cnt > 0)
        for(var i = 0; i < cnt; i++)
            processData(data.item[i]);
}

另外,在处理与DOM相关的对象时,使用局部变量存储特别重要,因为每个与DOM相关的对象的属性访问实际上都是一个DOM查询,需要尽量减少这种大的对象的属性访问,必要使用局部变量暂存。

流程控制

条件语句

当使用多个离散值进行比较时,使用if语句可能会造成比较次数较多,因此使用switch比较好。对于if语句可以使用二分法进行分裂也是一种加强方法,同时可以通过统计每个比较值出现的频率,将较大的频率的值放在靠前的位置。

对于上述的变更,可以使用数组下标的索引来进行快速选择,而不用进行一个一个比较。但是这个必须要保证离散值的个数不能太多,而且可以用索引值代替。

循环

JavaScript中的for、while和do-while三种循环,这些循环中的条件中如果存在对象的属性,要使用局部变量暂存,否则随着循环次数的增加,每次访问对象属性会非常耗时。

另一个加快循环的技巧就是讲循环的遍历顺序按照逆序的方式进行,这样会比顺序遍历节省50%左右的时间(取决于循环内处理的复杂性)。

JavaScript中还有一个单独为了遍历一个对象的各个属性使用的for-in循环,在遍历一个位置属性的对象时,这是非常有效的方法,但是这个方法比普通的循环慢很多,因为它要遍历对象的原型和整个原型链上的所有属性,这是非常耗时的。对于已知对象,使用三种普通的循环语句代替for-in是非常好的选择。

打散循环:

对于循环次数较少的循环语句,可以直接重复调用循环快语句来消除循环语句。但是对于次数较多的循环,Tom Duff最先在C语言中提出了打散循环的方法,被称为Duff’s Device。JavaScript语言的第一版发布者Jeff Greenberg改写了JavaScript版本的Duff’s Device:

var iter = Math.ceil(values.length / 8);
var left = values.length % 8;
var i = 0;
if (left > 0){
    do{
        process(values[i++]);
    }while(--left > 0);
}
do{
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
    process(values[i++]);
}while(--iter > 0);

上述方法将循环次数减少到除8的个数,这个数值8是多次试验得到的最优值。当遍历对象的个数特别大时,使用上述方法优化之后会比普通循环快很多。

字符串优化

字符串连接

所有浏览器在处理20个字符以下,1000个连接操作以下的情形时,都是非常快速的,这种情况下一般不需要考虑。

当字符串过长,或者连接操作太多时,就需要考虑性能问题。对于IE浏览器,字符串连接的运算符“+”会比较损耗性能,因此一般使用如下方式进行优化:

var buf = [], i = 0;
buf[i++] = "Hello";
buf[i++] = " ";
buf[i++] = "world";

var text = buf.join("");

但是,FireFox开始引入浏览器对字符串操作的优化之后,Chrome、Opera、Safari以及IE 8+都对字符串操作做了优化,因此不必考虑上述方式。特别地,Chrome和Opera优化之后的“+”操作符非常的快速。

字符串的trim操作

由于JavaScript没有原生的trim函数,因此一般都是用正则表达式进行上述操作:

function trim (s){
    return s.replace(/^\s+|\s+$/g, "");
}

这里的正则表达式使用了或者,实际上有两个模式,同时还有一个g修饰符,表示全局搜索。为了加快速度,Steven Levithan给出了优化的trim函数:

function trim(s){
    s = s.replace(/^\s+/, "");
    for(var i = s.length - 1; i >= 0; i--){
        if (/\S/.test(s.charAt(i))){
            s = s.substring(0, i+1);
            break;
        }
    }
    return s;
}

这里简化了正则表达式,同时对于末尾空字符使用逐个检查的方式去除。

上述这些优化的前提都是他们使用的频率非常大时,对性能的提升才比较大。另外,新的ECMAScript 3.1定义了内置的trim函数,速度会非常快。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 07-29

前端性能之js代码优化点的相关文章

新产品为了效果,做的比较炫,用了很多的图片和JS,所以前端的性能是很大的问题,分篇记录前端性能优化的一些小经验。

第一篇:HTTP服务器 因tomcat处理静态资源的速度比较慢,所以首先想到的就是把所有静态资源(JS,CSS,image,swf) 提到单独的服务器,用更加快速的HTTP服务器,这里选择了nginx了,nginx相比apache,更加轻量级, 配置更加简单,而且nginx不仅仅是高性能的HTTP服务器,还是高性能的反向代理服务器. 目前很多大型网站都使用了nginx,新浪.网易.QQ等都使用了nginx,说明nginx的稳定性和性能还是非常不错的. 1. nginx 安装(linux) htt

大话WEB前端性能优化基本套路

前言 前端性能优化这是一个老生常谈的话题,但是还是有很多人没有真正的重视起来,或者说还没有产生这种意识. 当用户打开页面,首屏加载速度越慢,流失用户的概率就越大,在体验产品的时候性能和交互对用户的影响是最直接的,推广拉新是一门艺术,用户的留存是一门技术,拉进来留住用户,产品体验很关键,这里我以美柚的页面为例子,用实例展开说明前端优化的基本套路(适合新手上车). WEB性能优化套路 基础套路1:减少资源体积 css 压缩 响应头GZIP js 压缩 响应头GZIP html 输出压缩 响应头GZI

让你页面速度飞起来 Web前端性能优化

百度网盘下载 第1章 课程简介 对课程做简单的介绍. 第2章 资源合并与压缩 通过本章,我们学习和理解了web前端的概念,以及性能优化的意义所在,并且通过实战中的压缩与合并,深入理解了减少http请求数和减少http请求资源大小两个优化要点,并且通过实战,帮助学生掌握如何通过网站进行压缩与合并,如果使用半自动化的gulp脚本进行压缩与合并,最终通过优化前后的性能对比,更加量化地去理解了性能... 第3章 图片相关的优化 通过本章,帮助学员学习和掌握图片相关的优化方法,理解不同图片格式分别是什么以

web前端性能&amp;SEO优化

前端性能优化 浏览器请求处理流程如下图: 1.减少http请求,合理设置 HTTP缓存 http协议是无状态的应用层协议,意味着每次http请求都需要建立通信链路.进行数据传输,而在服务器端,每个http都需要启动独立的线程去处理.这些通信和服务的开销都很昂贵,减少http请求的数目可有效提高访问性能. 减少http的主要手段是合并CSS.合并javascript.合并图片.将浏览器一次访问需要的javascript和CSS合并成一个文件,这样浏览器就只需要一次请求.图片也可以合并,多张图片合并

web前端性能优化

前言:  在同样的网络环境下,两个同样能满足你的需求的网站,一个“Duang”的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒,99%的用户会关闭这个网页.也许这样讲,各位还不会有太多感触,接下来我列举一组数据:Google网站访问速度每慢400ms就导致用户搜索请 求下降0.59%;Amazon每增加100ms网站延迟将导致收入下降1%;雅虎如果有400ms延迟会导致流量下降5-9%.网站的加载速度严重影响了用户体验,也决

性能测试(六)前端性能优化方法

日常工作和生活中,我们经常利用浏览器去打开一些URL来获取我们所需的资源,那么作为一个开发者或者性能测试工程师,如何去测试并提升优化前端的性能呢? 一.浏览器打开URL和方式和过程 不同浏览器工作方式不完全一样,大体来讲,浏览器的核心是浏览器引擎:不同浏览器对W3C的规范支持不尽相同,在具体功能的实现上也不完全一致. 1.连接到URL所在的服务器 用户在浏览器地址栏输入URL,打开URL时,浏览器首先寻找该URL所在的服务器.通过向DNS服务器查询,获取该URL所在网站的IP地址,然后浏览器向该

CSS3与页面布局学习总结(八)——浏览器兼容与前端性能优化

目录 一.浏览器兼容 1.1.概要 1.2.浏览器内核 1.3.浏览器市场份额(Browser Market Share) 1.4.兼容的一般标准 1.5.CSS Reset 1.6.CSS Hack 1.6.1.条件注释法 1.6.2.样式内属性标记法 1.6.3.选择器前缀法 1.7.文档模式 (X-UA-Compatible) 1.8.javascript兼容 二.前端性能优化 2.1.概要 2.2.减少HTTP请求数量 2.2.1.图片地图 2.2.2.精灵图片(Sprite) 2.2.

WebPack实例与前端性能优化

[前端构建]WebPack实例与前端性能优化 计划把微信的文章也搬一份上来. 这篇主要介绍一下我在玩Webpack过程中的心得.通过实例介绍WebPack的安装,插件使用及加载策略.感受构建工具给前端优化工作带来的便利. 壹 | Fisrt 曾几何时,我们是如上图的方式引入JS资源的,相信现在很少遇见了.近年来Web前端开发领域朝着规范开发的方向演进.体现在以下两点: MVC研发构架.多多益处(逻辑清晰,程序注重数据与表现分离,可读性强,利于规避和排查问题...) 构建工具层出不穷.多多益处(提

前端性能优化归纳总结

关于前端性能优化的总结,随处都可以看到这方面的文章,而优化方法,也无外乎那些"固定"方面,当然,有些方面已经过时,所以,在这里,我自己也总结一遍吧,加深理解,也希望是一种不同的总结形式. -----------------------正文总这里开始------------------------------------ 一.什么是前端性能优化(what)? 从用户访问资源到资源完整的展现在用户面前的过程中,通过技术手段和优化策略,缩短每个步骤的处理时间从而提升整个资源的访问和呈现速度.