国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[ JS 進階 ] 如何改進代碼性能 (3)

young.li / 2693人閱讀

摘要:這樣就改進了代碼的性能,看代碼將保存在局部變量中所以啊,我們在開發中,如果在函數中會經常用到全局變量,把它保存在局部變量中避免使用語句用語句延長了作用域,查找變量同樣費時間,這個我們一般不會用到,所以不展開了。

  

本來在那片編寫可維護性代碼文章后就要總結這篇代碼性能文章的,耽擱了幾天,本來也是決定每天都要更新一篇文章的,因為以前欠下太多東西沒總結,學過的東西沒去總結真的很快就忘記了,記錄一下在你腦力留下更深的印象,特別是這些可維護性代碼,性能什么的,當在你腦子里形成一種習慣了,那你就牛了!這里也要給初學者一個建議:多總結你學過的東西,因為這其實也是在學習新知識! 好,進入我們的主題:如何提高JS代碼的性能。

在今天的web應用中,應用了大量的Javascript,因此代碼的執行效率變得尤為重要,也就是性能!為了提高JS的性能,我們應該掌握一些基本的性能優化方式,并讓它成為我們書寫代碼的習慣。下面介紹幾種優化性能的方式,很多初學者甚至有經驗的開發者也會忽略,希望對你有幫助!

1.優化DOM交互

DOM與我們的頁面緊密相關,瀏覽器渲染頁面也就是在渲染解析后的DOM元素,DOM操作與交互要消耗大量的時間,因為它們往往需要重新渲染整個頁面或者一部分。進一步說,看似細微的一些操作也可能需要花很多時間來執行,因為DOM要處理的信息非常多,因此我們應該盡可能地優化與DOM相關的操作,加快瀏覽器對頁面的渲染!為什么有些DOM操作會影響頁面性能,可以查看我寫的一些關于瀏覽器原理的文章:

ok,優化DOM操作,我們主要有一些幾種方式:

1.1 最小化現場更新

什么是DOM的現場更新:需要對DOM部分已經顯示的頁面的一部分的顯示立即更新。但是,每一個更改,不管是插入單個字符,還是一處整個片段,都有一定的性能懲罰,因為瀏覽器需要重新計算無數尺寸以進行更新(相關知識請閱讀:)。所以,現場更新進行的越多,代碼執行所花的時間就越長,反之代碼執行越快,如下:

var list = document.getElementById("mylist"),
           item,
           i;
for(i = 0; i < 10; i++){
    item = document.creatElement("li");
    list.appendChild(item);
    item.appendChild(document.creatTextNode("item" + i));
}

這段代碼為列表mylist添加了10個項目,沒添加一個項目都要進行2次的現場更新:添加元素和添加文本節點,所以這個操作一個需要完成20個現場更新,每個更新都會損失性能,可見這樣的代碼運行起來是相對緩慢的。

解決的方法是使用文檔碎片間接地更改DOM元素:

var list = document.getElementById("mylist"),
           fragment = document.creatDocumentFragment(),
           item,
           i;
for(i = 0; i < 10; i++){
    item = document.creatElement("li");
    fragment .appendChild(item);
    item.appendChild(document.creatTextNode("item" + i));
}
list.appendChild(fragment);

像這樣的代碼只需進行一次的現場更新。記住,當給appendChild()傳入文檔碎片是,只有文檔碎片中的子節點才會被添加到目標元素,碎片本身不會被添加。

現在,你應該明白你用循環直接進行DOM節點的增刪查改是多么對不起瀏覽器的事了吧 `(∩_∩)′ 。

1.2 使用 innerHTML

除了上面代碼中使用的creatElement()appendChild()結合的方法創建DOM元素之外,還有通過給innerHTML賦值來創建。對于小的DOM更改而言,兩種方法的效率其實差不多,但對于大量的DOM節點的更改,后者要比前者快得多!為啥捏?

因為當我們給innerHTML賦值時,后臺會創建一個HTML解析器,然后使用內部的DOM調用來創建DOM結構,而非基于JavascriptDOM調用,由于內部方法是編譯好的而非解釋執行的,所以執行代碼的速度要快很多!

innerHTML改寫上面的例子:

   var list = document.getElementById("mylist"),
              html = "", //聲明一個空字符串
               i;
    for(i = 0; i < 10; i++){
        html += "
  • item" + i + "
  • "; } list.innerHTML = html; // 這里記得innerHTML后面的HTML四個字母都要大寫!

    這種方式同樣也只進行了一次的現場更新,并且性能要比上一種方式要好!雖然在字符串的鏈接上有點性能損失。

    1.3 使用事件代理/事件委托

    事件處理程序為web應用提供交互能力,因此許多開發人員會不分青紅皂白地向頁面中添加大量的處理程序,有個問題就是一個頁面上的事件處理程序數量將直接關系到頁面的整體運行性能。為什么捏?

    首先,事件處理程序對應至少一個函數,JS中每個函數都是對象,都會占用內存,內存中的對象越多,性能就越差。

    其次,我們必須事先指定所有事件處理程序,這就導致了DOM訪問次數增多,會延遲整個頁面的交互就緒時間,頁面響應用戶操作變得相對緩慢。

    所以減少事件處理程序同樣也可以讓我們的頁面更牛暢!使用事件委托勢在必得?。?/p>

    事件委托的原理其實就是事件冒泡,只指定一個事件處理程序就可以管理某一類型操作的所有事件。例如:click事件會一直冒泡到document層次,也就是說我們不必為每個元素添加事件,只需在較高的層次的元素上添加事件處理程序即可,然后利用事件對象(event)的屬性或方法去判斷當前點擊的元素,然后做出相應的響應。這個我就不展開講了,初學者可以自行查閱事件冒泡知識。

    2.作用域很重要

    說到作用域啊就很容易想到作用域鏈(scope chain),我們知道要搜索一個變量,所在的執行環境都要沿著這條作用域向上搜索這個變量,作用域鏈上有很多的變量,那么我們就得遍歷,遍歷就需要時間啊,而且你越往上查找所需時間越多,如果我們能減少這個時間,我們代碼執行效率不是可以提高了嗎?

    好聰明啊,ok,我看看有哪些方式可以減少這個時間:

    2.1 避免全局查找

    這是性能優化的一重點,上面也說了,越往上查找時間越多,也就是說查找全局變量和函數比局部要多!看代碼:

    function updateUI(){
        var imgs = document.getElementByTagName("img");
        for(var i = 0 ,lng = imgs.length;i < lng;i ++){
            imgss[i].title = document.title + "image" + i;
        }
        var msg = docuement.getElementById("msg");
        msg.innerHTML = "update complete.";
    }
    

    這代碼很正常呀!我之前也經常這么做滴。但是我們細心可以發現,這段代碼有三處引用了全局變量document,如果我們的頁面很多圖片,那么在for循環中的document就會被執行上百次,而每次都要需要在作用域鏈中查找,時間都去哪了,我還沒......停!。

    我們可以通過在函數中創建一個局部變量保存對document的引用,這樣,我們在函數里任何地方引用document都不用跑到全局變量去找了。這樣就改進了代碼的性能,看代碼:

    function updateUI(){
        var doc = document; // 將document保存在局部變量doc中
        var imgs = doc.getElementByTagName("img");
        for(var i = 0 ,lng = imgs.length;i < lng;i ++){
            imgss[i].title = doc.title + "image" + i;
        }
        var msg = doc.getElementById("msg");
        msg.innerHTML = "update complete.";
    }
    

    所以啊,我們在開發中,如果在函數中會經常用到全局變量,把它保存在局部變量中!

    2.2 避免使用with語句

    用with語句延長了作用域,查找變量同樣費時間,這個我們一般不會用到,所以不展開了。解決方法還是和上面的例子一樣,將全局變量保存在局部變量中!

    3.優化循環

    循環在編程中可謂家常便飯,在js中也隨處可見,循環體會反復地執行同一段代碼,執行時間一直累加,所以能夠對循環體的代碼進行優化也可以大大減少執行時間!如何優化?四種方式。

    3.1 減值迭代

    我們寫迭代器(循環條件)的時候一般都這樣(var i = 0;i < 10;i ++),從0開始,增加到某個特定值。然而在很多情況下,如果在循環中使用減值迭代器效率更高。我測試了下,如果循環體不復雜的話,兩者差不多!

    //增值迭代 --效率較低
    for(var i = 0;i < items.length;i++){
       doSomething(items[i]); 
    }
    //減值迭代 --效率較高
    for(var i = items.length - 1;i >= 0;i--){
       doSomething(items[i]); 
    }
    
    3.2 簡化終止條件

    由于每次循環都會計算終止條件,所以必須保證它的執行盡可能地塊。這里主要是避免其他DOM元素及其屬性的的查找。

     //看終止條件,每次循環都需要查詢items及其length屬性
    for(var i = 0;i < items.length;i++){
       doSomething(items[i]); 
    }
    
    //將items.length的值保存在局部變量lng中。
    for(var i = 0,lng = items.length;i < lng;i++){
       doSomething(items[i]); 
    }
    
    3.3 簡化循環體

    原因和上面以上的,所以在循環體內避免大量的密集的操作。

    這其實和上面講的:1.1 最小化現場更新 。是一樣的優化方式??梢缘够厝タ纯?。

    4.基本的算法優化

    在計算機中,算法的復雜度用O表示。下面是javascript中幾種常見的算法類型:

    O(1) :常數,不管有多少值,執行的時間都是恒定的,比如簡單值和存儲在變量中的值。

    O(log n):對數,總的執行時間和數量有關,但不一定要獲取每一個值,如:二分法查找

    O(n) :線性,總執行時間和數量直接相關,如:遍歷

    O(n*n) :平方,總執行時間和數量有關,每個值至少獲取N次,如:插入排序

    ok,有了上面的知識,我們就可以對javascript進行一些算法上的優化了??创a:

    var value = 5;
    var sum = value + 10;
    alert(sum);
    

    這段代碼進行了4次常量值的查找:數字5,變量value,數字10,變量sum,這段代碼的算法復雜度就是O(1)。又如:

    var value = [10,5];
    var sum = value[0] + value[1];
    alert(sum);
    

    在javascript中訪問數組元素也是一個O(1)操作,和簡單的變量查找效率一樣。再看:

    var value = {one:10,two:10};
    var sum = value.one + value.two;
    alert(sum);
    

    要表達的是訪問對象上的屬性要比訪問數組和變量的效率低。因為這是一個O(n)操作。你需要在對象的原型鏈中查找該屬性,所花時間較多。

    好了,看完這個是不是感覺眼前一片光明啊。其實我們前面所講的要把經常用到的全局屬性保存在一個局部變量中就是根據這個原理了,訪問全局屬性是一個O(n)的操作,而訪問變量是一個O(1)的操作,大聲告訴我,挖掘機哪家強啊!

    5.最小化語句數

    前面講的優化差不多都是和精簡優化語句有關的,是的,我覺得代碼的質量和數量就是性能的評判標準。前面講了一些代碼質量相關的優化,這里就講講代碼數量的優化。

    5.1 精簡變量聲明
    //用了5條語句聲明5個變量
    var count = 5;
    var color = "red";
    var values = [1,2,3];
    var now = new Date();
    
    //用了1條語句聲明5個變量,注意每個變量用逗號隔開
    var count = 5,
        color = "red",
        values = [1,2,3],
        now = new Date();
    
    5.2 使用數組和對象字面量
    // 創建兩個對象 ----不好的方式
    //one 四條語句
    var values = new Array();
    values[0] = 123;
    values[1] = 456;
    values[2] = 789;
    //two 四條語句
    var person = new Object();
    person.name = "jozo";
    person.age = 21;
    person.sayName = function(){
        alert(this.name);
    };
    // 創建兩個對象 ----推薦的方式
    //one 1條語句
    var values = [123,456,789]
    //two 1條語句
    var person = {
        name : "jozo",
        age : 21,
        sayName : function(){
        alert(this.name);
    };
    
    6.其他

    寫累了,如有不正確的地方請指正哦,還有一些其他的優化,下次文章繼續!

    文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

    轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85578.html

    相關文章

    • 初學者福音!可能是最適合你的Java學習路線和方法推薦。

      摘要:學習完多線程之后可以通過下面這些問題檢測自己是否掌握,下面這些問題的答案以及常見多線程知識點的總結在這里??蛇x數據結構與算法如果你想進入大廠的話,我推薦你在學習完基礎或者多線程之后,就開始每天抽出一點時間來學習算法和數據結構。 我自己總結的Java學習的系統知識點以及面試問題,已經開源,目前已經 35k+ Star。會一直完善下去,歡迎建議和指導,同時也歡迎Star: https://...

      yanest 評論0 收藏0
    • 前端學習路線

      摘要:具體來說,包管理器就是可以通過命令行,幫助你把外部庫和插件放到你的項目里面并在之后進行版本升級,這樣就不用手工復制和更新庫?,F在有的包管理器主要是和。 一、基礎 1、學習HTML基礎 HTML給你的網頁賦予了結構。它就像是人的骨架那樣讓你保持站立。首先你需要去學習語法以及它必須提供的一切。你的學習應該聚焦在下面這些東西上: 學習HTML基礎,了解如何編寫語義HTML 理解如何把網頁分...

      FullStackDeveloper 評論0 收藏0
    • 前端學習路線

      摘要:具體來說,包管理器就是可以通過命令行,幫助你把外部庫和插件放到你的項目里面并在之后進行版本升級,這樣就不用手工復制和更新庫?,F在有的包管理器主要是和。 一、基礎 1、學習HTML基礎 HTML給你的網頁賦予了結構。它就像是人的骨架那樣讓你保持站立。首先你需要去學習語法以及它必須提供的一切。你的學習應該聚焦在下面這些東西上: 學習HTML基礎,了解如何編寫語義HTML 理解如何把網頁分...

      20171112 評論0 收藏0
    • 前端進階(14) - 如何提升前端性能和響應速度

      摘要:一般建議文件最大不超過。按需加載可以減小首屏加載文件的體積,達到提高響應速度的目的。如果你的項目不需要處理靜態資源如圖片,也不需要按需加載,并追求前端高性能的話,可以嘗試。 如何提升前端性能和響應速度 下面大多是從前端工程化的角度給出的優化建議,如果需要了解語法上的優化,可以參考: 如何提高頁面加載速度 編寫高效的JavaScript Web前端性能優化進階 - 完結篇 1. 原生...

      lylwyy2016 評論0 收藏0

    發表評論

    0條評論

    young.li

    |高級講師

    TA的文章

    閱讀更多
    最新活動
    閱讀需要支付1元查看
    <