javascript 性能优化

来源:互联网 发布:淘宝账号可以卖东西吗 编辑:程序博客网 时间:2024/04/23 22:02

看了 比较多的 文章

顺便把这些东西归纳一下。

各位看客,如果发现错误请指正.........

1.尽量用全局变量代替局部变量

以前看道这句话的时候  以为是用巧妙的方法来减少全局变量的 次数

 

其实他还有一层意思

如下 面一个函数

function c(){

    document.body.appendChild(document.createElement('div'));

};

 

有2个地方 用到了 document  而document是全局变量 (test    alert('document' in window))

根据作用域链的查找机制, 上面的写法就比较的慢了

可以拿一个局部变量作为引用

function c(){

    var d = document;  //用个局部变量来引用全局的对象;

    d.body.appendChild(d.createElement('div'));

}

 

 

2.尽量的减少dom操作

在Web开发中,JavaScript的一个很重要的作用就是对DOM进行操作。可你知道么?对DOM的操作是非常昂贵的,因为这会导致浏览器执行回流(reflow)操作。而执行了过多的回流操作,你就会发现自己的网站变得越来越慢了。我们应该尽可能的减少DOM操作。


回流操作主要会发生在几种情况下:

* 改变窗体大小
* 更改字体
* 添加移除stylesheet块
* 内容改变哪怕是输入框输入文字
* CSS虚类被触发如 :hover
* 更改元素的className
* 当对DOM节点执行新增或者删除操作或内容更改时。
* 动态设置一个style样式时(比如element.style.width="10px")。
* 当获取一个必须经过计算的尺寸值时,比如访问offsetWidth、clientHeight或者其他需要经过计算的CSS值(在兼容DOM的浏览器中,可以通过getComputedStyle函数获取;在IE中,可以通过currentStyle属性获取)。

 

解决问题的关键,就是限制通过DOM操作所引发回流的次数:

1.在对当前DOM进行操作之前,尽可能多的做一些准备工作,保证N次创建,1次写入。



2.在对DOM操作之前,把要操作的元素,先从当前DOM结构中删除:
        1. 通过removeChild()或者replaceChild()实现真正意义上的删除。
        2. 设置该元素的display样式为“none”。
修改操作完成后,将上面这个过程反转过来,建议使用第2种方式。

 

这是 yahoo的 其中的 一条准则

我觉得说的很有道理  但是我重来没有这么做过 。。。。 先记录在这里

 


3 定义变量的时候尽量一次写完,中间用逗号隔开

据说是执行的时候效率要快.

 

4.尽量用原生的方法,因为原生的都是用c/c++编译而成的他们执行的要比用js写的方法快多了.

 

5.避免Javascript事件绑定出现内存泄漏

这个有个例子  很经典的  (看的是51版主winter的 blog)

他的原文地址

function  A()... {
    
var  a = document.createElement( " div ");
    a.onclick
= function () ... {
        alert(
" hi " );
    }

}


A();

这个上面已经产生内存泄露了    原因是产生了循环引用

 

简单的循环说一下 (这个得对js的运行机制比较了解才能看的懂噢)

 

A()运行的时候会产生一个对象(作用域对象) 姑且叫它ScopeA 吧   所有函数里面的临时变量都是ScopeA的属性

 

所以ScopeA.a 引用着 dom元素

 

dom元素的onclick 属性引用着 function(){alert('hi')}

 

而function(){alert('hi')}.[[scope]] 引用的是当前的作用域 也就是ScopeA

这样就造成了循环引用

 

6.当有大量的字符串需要进行连接操作的时候 用array的join方法

 内置方法 就不说了 效率肯定比较快  (记得去年去深信服面试的时候就有这道题目  泪奔了)

 

7.类型转换

类型转换是大家常犯的错误,因为JavaScript是动态类型语言,你不能指定变量的类型。

1.
把数字转换成字符串,应用"" + 1 ,虽然看起来比较丑一点,但事实上这个效率是最高的,性能上来说:

("" + ) > String() > .toString() > new String()

这条其实和下面的“直接量”有点类似,尽量使用编译时就能使用的内部操作要比运行时使用的用户操作要快。

String() 属于内部函数,所以速度很快,而.toString() 要查询原型中的函 数,所以速度逊色一些,new String() 用于返回一个精确的副本。

2.
浮点数转换成整型,这个更容易出错,很多人喜欢使用parseInt() ,其实parseInt() 是 用于将字符串转换成数字,而不是浮点数和整型之间的转换,我们应该使用Math.floor() 或者Math.round()

另外,和第二节的对象查找中的问题不一样,Math 是内部对象,所以Math.floor() 其 实并没有多少查询方法和调用的时间,速度是最快的。

3.
对于自定义的对象,如果定义了toString() 方法来进行类型转换的话,推荐显式调用toString() , 因为内部的操作在尝试所有可能性之后,会尝试对象的toString()方法尝试能否转化为String,所以直接调用这个方法效率会更高

 

 

8.CSS部分
另外一个经常引起回流操作的情况是通过style属性对元素的外观进行修改,如element.style.backgroundColor = "blue";
每次修改元素的style属性,都肯定会触发回流操作,要解决这个问题可以:
1.使用更改className的方式替换style.xxx=xxx的方式。
2.使用style.cssText = '';一次写入样式。
3. 避免设置过多的行内样式
4. 添加的结构外元素尽量设置它们的位置为fixed或absolute
5. 避免使用表格来布局
6. 避免在CSS中使用JavaScript expressions(IE only)

4.将获取的DOM数据缓存起来。这种方法,对获取那些会触发回流操作的属性(比如offsetWidth等)尤为重要。

5.当对HTMLCollection对象进行操作时,应该将访问的次数尽可能的降至最低,最简单的,你可以将length属性缓存在一个本地变量中,这样就能大幅度的提高循环的效率。

 

9.可以用map来代替swith

如a ={

    a1:1,

    a2:2,

    a3:3,

    a4:4

}  

a[X]

 

 

10.同一级别的元素帮定事件 可以绑定在他的父元素上 这个好象就事件委托

for exmple

<body >
<table width=300 height=100 border=1>
<tr id="ss">
<td id='a1' width="33%"></td>
<td id='a2' width="33%"></td>   
<td id='a3' width="33%"></td>       
</tr>   
</table>   
<script type="text/javascript">
function a(){alert(1)}
function b(){alert(2)}
function c(){alert(3)}
document.getElementById('ss').onclick = function(e){
    var evnets={
        a1 :function(){a();},
        a2 :function(){b();},
        a3 :function(){c();}
    };
    var e = e || window.event;
    evnets[(e.srcElement||e.target).id]();
};
</script>
</body>

 

11.关于dom的一些东西

当批量添加dom的时候用innerHTML比较快

添加单个dom的时候还是用append的好了

 

//过了2年  发现之前写的这些也不是很记得了 哎.............. 光阴荏苒

web 前端优化

 

尽量减少 HTTP 请求 (Make FewerHTTP Requests)

  • 1) 合并文件,比如把多个 CSS 文件合成一个;
  • 2) CSS Sprites 利用CSS background 相关元素进行背景图绝对定位;参见:CSS Sprites: Image Slicing's Kiss of Death
  • 3) 内联图象 使用 data: URL scheme 在实际的页面嵌入图像数据.

 

2. 减少 DNS 查找 (Reduce DNS Lookups)

不懂

3. 一步请求 加载资源 如 img  js    xhr

4.规划好页面结构 减少不必要的dom

5.资源划分到不用的域下面,可以增大并发数

6.gizp js css 服务端压缩文件

7.利用缓存技术 在服务端设置一些资源的过期时间 这样一些资源会缓存在本地

8.css上<body>上面 <script>放</body>下面  先加载完页面的样式  在加载js的相关的东西

9.压缩css js   我一般用jar 和 yui的那个

10.缓存ajax  对于不变的数据  请求一次就行了

11.不要让请求中有404    会有较长的等待时间,如果直接渲染在页面的东西,用户体验更不好 

12.引入外部的css 用link    而不是 @import              @import相反与吧css放在了底部..