高效能JavaScript讀書筆記

來源:互聯網
上載者:User

標籤:推薦   失控   另一個   非同步載入   trace   動作   檔案載入   全域   解決方案   

零、組織圖

根據引言,作者將全書劃分為四個部分:
一、頁面載入js的最佳方式(開發前準備)
二、改善js代碼的編程技巧(開發中)
三、構建與部署(發布)
四、發布後效能檢測與問題追蹤(線上問題最佳化)
這樣的組織圖也符合我們的開發習慣,首先進入第一部分。

一、JavaScript載入

起因:script指令碼的載入會阻塞瀏覽器渲染頁面和處理使用者互動,如果載入的script指令碼太多太大,就會長時間阻塞,造成頁面假死。
解決方案:

1.指令碼位置

放在底部。
放在底部可以保證頁面主體結構已經基本載入完成展示給使用者,才去載入script指令碼。這條準則也有特例,如果是一些公司的埋點指令碼,可能要求必須放在head裡,以確保能上報頁面載入時間長度。

2.組織指令碼

減少script數量,合并指令碼。
不論是使用concat打包工具合并,還是cdn提供的combo,都能達到該目的。

3.無阻塞指令碼

在頁面載入完成之後再去觸發載入js,這樣可以防止script載入阻塞頁面。

原生defer

script標籤內建defer屬性,可以達到這個目的。捎帶一提,async屬性可以觸發非同步載入,合理利用了寬頻。

動態指令碼

或者使用動態指令碼元素,通過js檔案動態建立script標籤,檔案載入完成之後會立刻執行。

這個技術的重點在於不論在何時啟動下載,檔案的下載和執行過程都不會阻塞頁面其他進程。

XMLHttpRequest指令碼注入

通過XHR載入指令碼,由於不是在script標籤中載入,所以可以控制script標籤中的代碼執行時間。在需要的時候再去把script標籤添加到頁面上。
這也是jsonp的原理。

作者推薦的無阻塞模式

先載入很少量的jsLoader代碼,之後通過loader來載入剩餘的代碼。

function loadScript(url, callback) {    var script = document.createElement(‘script‘);    script.type = ‘text/javascript‘;        if (script.readyState) { // IE        script.onreadystatechange = function () {            if (script.readyState == ‘loaded‘ || script.readyState == ‘complete‘) {                script.onreadystatechange = null;                callback();            }        }    } else { // 其他瀏覽器        script.onload = function () {            callback();        }    }        script.src = url;    document.getElementsByTagName(‘head‘)[0].appendChild(script);}loadScript(‘rest.js‘, function () {    Rest.init()});
YUI3、LazyLoad、LABjs

作者介紹了上述3個類庫中lazyload的使用方式,其實原理就是上述所說,在體驗上各有不同。關鍵就是loader中監聽script的onload事件,決定script的執行時機。

二、高效能編程技巧

這個部分從2到8章分別介紹不同的提高效能的技巧。

1.資料存取
  • 資料的存取有四種方式,字面量、變數、資料項目、對象。字面量和變數快於數組項和對象。
  • 局部變數位於範圍鏈的開始,尋找速度最快,所處的位置越深,尋找越慢,全域變數尋找最慢。
  • with可以影響範圍鏈,try-catch語句中的catch也會影響。謹慎使用。
  • 如果當前對象沒有某個屬性或者方法,就會去遍曆原型鏈上的屬性和方法,也會造成效能損耗。
  • 嵌套對象層數越多,也會減慢速度。例如,location.href要快於window.location.href。

  • 解決方案:
    大部分的效能損耗都是與對象尋找相關,所以建議緩衝對象,減少尋找次數。

    2.DOM編程
  • 由於DOM渲染引擎和JS引擎一般是分離實現的,要讓兩個相互獨立的模組建立通訊,就會產生消耗。所以,我們需要減少DOM操作,已經擷取的DOM節點,緩衝下來,防止多次重複操作。
  • 其次,要注意重繪和重排,對DOM的哪些操作會引起重繪和重排,減少這方面的操作。
    最後,需要注意DOM事件處理使用者互動。

  • 使用innerHTML和原生的document.createElement()類似的方法,速度相差不大。在最新版的webkit核心瀏覽器(chrome和safari)以外,innerHTML會更快,而且相較而言,代碼量也少很多。

  • HTML集合是包含了DOM節點引用的類數組對象,例如document.getElementByName()這樣的方法,需要注意的是HTML集合一直與文檔保持著串連,每次需要新資訊的時候,都會重新查詢。

  • 在尋找DOM元素時,儘可能使用原生方法,如最新支援比較完善的querySelectorAll()。

  • 在頁面配置和幾何屬性改變時就需要“重排”,例如:
  1. 添加或者刪除可見的DOM元素
  2. 元素位置改變
  3. 元素尺寸改變(包括:外邊距、內邊距、邊框厚度、寬度、高度等屬性改變)。
  4. 內容改變,例如:文本改變或者圖片被另一個尺寸的圖片替代
  5. 頁面渲染器初始化
  6. 瀏覽器視窗尺寸改變
  • 為了減少重排和重繪,批量修改樣式時,“離線”操作DOM樹,使用緩衝,並減少訪問布局資訊的次數。在動畫中使用絕對位置,使用拖放代理。

  • 使用事件委託來減少事件處理器的數量。

3.演算法和流程式控制制
  • 減少迭代的工作量,比如使用局部變數緩衝數組的長度,減少查詢次數。
  • 減少迭代次數,使用Duff‘s Device。
  • 儘可能不用forin,forin要比for、while、do-while要慢。
  • switch比if-else要快,但要綜合考慮代碼可讀性。
  • 判斷條件較多時,尋找表要比if-else和switch更快。
  • 遞迴容易造成棧溢出,控制遞迴的迴圈次數。
4.字串和Regex
  • 串連巨大的字串時,數組項合并在IE7或更早之前版本是最優方法。
  • 如果在現代瀏覽器中,推薦使用簡單的+和+=操作符代替,避免不必要的中間字串。
  • 回溯是正則的基本組成,也會帶來效能問題。
  • 回溯失控發生在Regex本應快速匹配的地方,因為某些特殊的字串匹配動作導致運行緩慢甚至瀏覽器崩潰。為了避免這種情況,應該使相鄰的字元互斥,避免嵌套量詞對同一字串的相同部分多次匹配,通過利用預查的原子組去除不必要的回溯。
5.快速響應的使用者介面
  • 任何JavaScript任務不應該超過100ms,否則使用者體驗會變差。
  • JavaScript運行期間,瀏覽器響應使用者互動的行為存在差異。
  • 定時器可用來安排代碼順延強制,但不一定絕對精確。
  • web worker允許程式員在UI線程外執行JavaScript代碼,從而避免鎖定UI。
6.AJAX
  • 減少請求數
  • 縮短頁面載入時間,頁面主要內容載入完成之後,用Ajax擷取次要內容
  • 代碼錯誤儘可能對使用者屏蔽
7.最佳實務
  • 避免使用eval和Function構造器帶來雙重求值帶來的效能損耗。
  • 使用直接量建立對象和數組,直接量更快
  • 避免重複工作,需要檢測瀏覽器時,可使用消極式載入或者條件預先載入。
  • 進行數學計算時,考慮使用位元運算。
  • 盡量使用原生方法
三、構建與部署
  • 合并JavaScript檔案以減少HTTP請求數
  • 使用YUI Compressor壓縮JavaScript檔案(事實上,如今nodejs下的打包工具更加好用)
  • 在服務端壓縮JavaScript檔案(Gzip編碼)
  • 通過正確設定HTTP回應標頭來緩衝JavaScript檔案,通過向檔案名稱加時間戳記來避免緩衝問題
  • 使用CDN
四、發布後效能檢測與問題追蹤
  • 使用網路分析工具找出載入指令碼和頁面中其他資源的瓶頸。
  • 把指令碼消極式載入可以加快頁面渲染速度,帶來更好的使用者體驗
  • 使用效能分析工具找出指令碼運行速度慢的地方,檢查每個函數消耗的時間,以及函數被調用的次數,通過調用棧自身的一些線索來找出需要集中精力最佳化的地方
    一些工具:
  • YUI Profile
  • Firebug
  • Page Speed
  • Fiddler
  • YSlow
  • dynaTrace Ajax Edition

事實上,這些工具的功能在新版的chrome開發工具都有了,所以我建議好好學習chrome開發人員工具。
感謝閱讀。

高效能JavaScript讀書筆記

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.