前端性能優化JavaScript篇

關於前端性能優化的討論一直都不少,包羅的知識也不少,能夠說性能優化只有更好,沒有最好。前面我寫了一篇關於css優化的總結文章,今天再從javascript方面聊一聊。javascript

1.從資源加載方面來講,瀏覽器的加載順序是按源碼從上到下加載解析的,遇到link,script等資源都會阻塞頁面渲染,因此咱們會把script放在</body>前面,咱們還能夠結合構建工具(webpack,gulp...)壓縮js文件,抽離公共js、去掉空格、註釋,儘量地讓js文件變小,防止腳本阻塞頁面渲染。css

2.在寫代碼的時候咱們還要注意如下問題。前端

(1)減小做用域鏈上的查找次數。咱們知道,js代碼在執行的時候,若是須要訪問一個變量或者一個函數的時候,它須要從當前執行環境的做用域鏈一級一級地向上查找,直到全局做用域。若是咱們須要常常訪問全局環境的變量對象的時候,咱們每次都必須在當前做用域鏈上一級一級的遍歷,這顯然是比較耗時的。java

function getTitle() {
    var h1 = document.getElementByTagName("h1");
    for(var i = 0, len = h1.length; i < len; i++) {
        h1[i].innerHTML = document.title + " 測試 " + i;
    }
}

上面這樣寫就很是耗時,咱們能夠優化一下:node

function getTitle() {
    var doc = document;
    var h1 = doc.getElementByTagName("h1");
    for(var i = 0, len = h1.length; i < len; i++) {
        h1[i].innerHTML = doc.title + " 測試 " + i;
    }
}

經過建立一個指向document的局部變量,就能夠經過限制一次全局查找來改進這個函數的性能。jquery

(2)閉包致使的內存泄露。
閉包能夠保證函數內的變量安全,能夠讀取函數內部的變量,另外一個就是讓這些變量的值始終保持在內存中,不會被自動清除。使用場合:設計私有的方法和變量。使用不當就會形成內存佔用太高。咱們須要手動銷燬內存中的變量。webpack

(3)儘可能少用全局變量,儘可能使用局部變量。全局變量若是不手動銷燬,會一直存在,形成全局變量污染,可能很產生一些意想不到的錯誤,而局部變量運行完成後,就被會被回收;web

(4)使用classname代替大量的內聯樣式修改。不少時候咱們會在用戶操做的時候,頁面元素樣式會進行相應的變化,這時候咱們就能夠把要變化的樣式寫成一個class,操做class變化,就能實現大量樣式的變化。正則表達式

(5)批量元素綁定事件,可使用事件委託。事件委託就是利用事件冒泡,只指定一個事件處理程序,就能夠管理某一類型的全部事件。好比咱們有100個li,每一個li都要綁定click點擊事件,就能夠用事件委託。舉一個例子:咱們須要給全部的button綁定click事件gulp

<div id="box">
        <input type="button" id="add" value="添加" />
        <input type="button" id="remove" value="刪除" />
        <input type="button" id="move" value="移動" />
        <input type="button" id="select" value="選擇" />
    </div>

咱們有可能會這樣寫

window.onload = function(){
            var Add = document.getElementById("add");
            var Remove = document.getElementById("remove");
            var Move = document.getElementById("move");
            var Select = document.getElementById("select");
            
            Add.onclick = function(){
                alert('添加');
            };
            Remove.onclick = function(){
                alert('刪除');
            };
            Move.onclick = function(){
                alert('移動');
            };
            Select.onclick = function(){
                alert('選擇');
            }
        }

用事件委託就能夠這樣寫:

window.onload = function(){
            var oBox = document.getElementById("box");
            oBox.onclick = function (ev) {
                var ev = ev || window.event;
                var target = ev.target || ev.srcElement;
                if(target.nodeName.toLocaleLowerCase() == 'input'){
                    switch(target.id){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('刪除');
                            break;
                        case 'move' :
                            alert('移動');
                            break;
                        case 'select' :
                            alert('選擇');
                            break;
                    }
                }
            }
            
        }

並且使用事件委託,還有一個好處就是,當你添加一個新的button,同樣的會綁定上click事件,這就是委託事件的好處。上面這樣的寫法是原生js的寫法,jquery能夠這樣寫:

$("#box").on("click","input",function(event){
             var targetId = $(this).attr('id');
              switch(targetId){
                        case 'add' :
                            alert('添加');
                            break;
                        case 'remove' :
                            alert('刪除');
                            break;
                        case 'move' :
                            alert('移動');
                            break;
                        case 'select' :
                            alert('選擇');
                            break;
                    }             
})

這樣寫就簡便得多。

(6)避免沒必要要的DOM操做,儘可能使用 ID 選擇器:ID選擇器是最快的,避免一層層地去查找節點。

(7)類型轉換:把數字轉換成字符串使用number + "" 。
雖然看起來比較醜一點,但事實上這個效率是最高的,性能上來講:

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

(8)對字符串進行循環操做,譬如替換、查找,應使用正則表達式。由於自己JavaScript的循環速度就比較慢,而正則表達式的操做是用C寫成的語言的API,性能很好。

(9)對象查詢使用[""]查詢要比.items()更快。這和前面的減小對象查找的思路是同樣的,調用.items()增長了一次查詢和函數的調用。

(10)浮點數轉換成整型使用Math.floor()或者Math.round()。parseInt()是用於將字符串轉換成數字,Math是內部對象,因此Math.floor()其實並無多少查詢方法和調用的時間,速度是最快的。

關於js性能優化來講,涉及到不少方面,特別是如今又出現不少的前端框架,優化方法又各有不一樣。上面說的這些只是很淺顯的東西,在開發中多注意一下就能夠了,儘可能精簡本身的代碼。性能優化還須要繼續深刻研究。

相關文章
相關標籤/搜索