javascript效能提升之路

慕斯不想說話發表於2019-04-07

  在平時工作做專案的過程中我們有時候會遇到頁面載入很久才載入出來的情況,這樣嚴重影響了使用者的體驗效果。雖然說有時候可能是因為網路問題,但有些時候確實是前端程式碼沒有足夠優化導致的。所以通過查閱相關資料並實踐後,總結出如下知識點來提升效能。有什麼寫得不對的地方還希望各路大神指出並加以指點。

1、資料訪問

1、將所有script標籤放在儘可能接近body標籤底部的位置,儘可能減少對整個頁面下載的影響。

javascript效能提升之路

2、儘量少用全域性變數。因為變數在作用域鏈中的位置越深,訪問的時間就越長。區域性變數位於作用域鏈中的第一個物件中,全域性變數總是位於作用域鏈的最後一環,所以全域性變數總是最慢的。
3、避免全域性查詢,如果一定要用到全域性變數時,並且需要在某個函式中多次用到該全域性變數時,可以定義一個區域性變數指向全域性變數,來縮短在作用域鏈中的查詢深度。

    function addTotrackData(){
    	var allChildrenNode=getAllChildrenDepartmentNodes();
    	for (var i = 0; i < allChildrenNode.length; i++) {
            for (var j=0,len=track.length;j<len;j++) {
                if (trackNode[j]["userId"] == allChildrenNode[i]) {
                    trackNode[j]["isOnMap"] = true;
                }
            }
        }
    }
複製程式碼

上面程式碼可以改寫為如下所示

    function addTotrackData(){
    	var allChildrenNode=getAllChildrenDepartmentNodes();
    	var track=trackNode;
    	for (var i = 0; i < allChildrenNode.length; i++) {
            for (var j=0,len=track.length;j<len;j++)  {
                if (track[j]["userId"] == allChildrenNode[i]) {
                    track[j]["isOnMap"] = true;
                }
            }
        }
    }
複製程式碼

4、將集合的length屬性用一個區域性變數來儲存,在迭代中使用該變數。

 for (var j=0,len=track.length;j<len;j++) 
複製程式碼

4、避免使用with表示式,因為它增加作用域鏈的長度。而且應當小心的對待try-catch的catch子句,它具有同樣效果。
5、一個屬性或方法在原型鏈中的位置越深,它的訪問速度就越慢。
6、宣告變數時,多個變數合併宣告,可以減少記憶體消耗。

    var a;
    var b;
    var c;
    //推薦
    var a,b,c
複製程式碼

2、Dom操作

  Dom(文件物件模型)是一個獨立於語言的,使用xml和html文件操作的應用程式介面。在瀏覽器中的介面卻是以javascript來實現的。Dom和javascript看成兩座島,兩者之間通過一座收費的橋連線。一般建議儘量留在javascript島上。

1、用innerHTML代替DOM操作,減少DOM操作次數,優化javascript效能。

    //dom方式
    var str=""
    var dom=document.getElementById("test");
    var start1=new Date();
    for(var j=0;j<100000;j++){
    	var div=document.createElement("div");
    	div.innerText="test";
    	dom.append(div);					
    }
    var end1=new Date();
    console.log("dom方式:"+(end1-start1));//dom方式:356
    
    //inerHTML方式
    var content="";
    var start=new Date();
    for(var i=0;i<10000;i++){
        content=content+"<div>test</div>";
    }
    document.getElementById("test").innerHTML=content;
    var end=new Date();
    console.log("innerHTML方式:"+(end-start));//innerHTML方式:35
複製程式碼

2、 如果統一個Dom元素或集合被訪問一次以上,最好使用一個區域性變數來快取此Dom成員,在迴圈中使用區域性變數快取集合引用和集合元素會提升速度。
3、遍歷children比childNodes更快。children不區分(包括)註釋節點和空文字節點,所以快一些。
4、使用element.cloneNode(bool)複製節點,bool為false表示淺複製,只複製當前節點,bool為true時,表示深複製,還會複製其子節點。這種方式比document.createElement()速度要快一些。
5、 使用document.querySelector和document.querySelectorAll("div.warning,div.notice")來快速查詢。因為它們返回一個NodeList——由符合條件的節點構成的類陣列物件,而不是HTML集合(總是表現出存在性),避免了它所固有的效能問題(以及存在的邏輯問題)。querySelectorAll("div.warning,div.notice")還可以進行聯合查詢。
6、修改樣式時,可以使用div.style.cssText來一起修改樣式,或者使用類來修改(便於維護)。

    var el = document.getElementById('mydiv');
     //修改3次Dom
    el.style.borderLeft = '1px';
    el.style.borderRight = '2px';
    el.style.padding = '5px';
    //推薦只需要修改1次Dom
    el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;'  
複製程式碼

7、儘量避免寫在HTML標籤中寫Style屬性,使用外聯樣式便於維護和修改。 8、避免圖片和iFrame等的空Src。空Src會重新載入當前頁面,影響速度和效率 9、採用事件委託。元素連線事件控制程式碼會影響頁面效能,採用委託利用事件冒泡的效能減少元素連線事件。(事件掛接過程都是發生在onload或DOMContentReady)事件中。

迴圈

1、for-in是四種迴圈方法中速度最慢的一種,一般用於迴圈物件(需要查詢自身屬性還是原型屬性)。不建議迴圈陣列。除非要迭代遍歷一個屬性未知的物件,否則一般不用for-in。
2、改變迴圈條件的順序來提高迴圈效能。

    //推薦
    for(var i=items.length;i--;){
        //todo
    }
    //不推薦
    for(var i=0,len=items.length;i<len;i++){
        //todo
    }   
複製程式碼

3、通過減少迴圈體來優化效能。

相關文章