javascript 性能優化

看了 比較多的 文章

順便把這些東西歸納一下。

各位看客,如果發現錯誤請指正.........

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的好了

發佈了10 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章