1. 程式人生 > >JavaScript基礎概念之----效能優化

JavaScript基礎概念之----效能優化

一、載入與執行

  1. body閉合標籤之前,將所有的script標籤放到頁面的底部,能確保在指令碼執行前頁面已經完成渲染
  2. 合併指令碼,頁面中script標籤越少,載入越快,響應也更迅速
  3. 使用多種無阻塞下載Javascript方法:
    • 使用script標籤的defer屬性
    • 使用動態建立script元素來下載並執行程式碼
    • 使用XHR物件下載 Javascript程式碼並注入頁面中

二、資料存取

  • 訪問字面量和區域性變數的速度最快,相反,訪問陣列和物件相對較慢
  • 由於區域性變數存在於作用域的起始位置,因此訪問區域性變數比訪問跨作用域變數更快。變數在作用域鏈中的位置越深,訪問所需時間越長,由於全域性變數總處在作用域鏈的最末端,因此訪問速度最慢
  • 避免使用 with 語句,因為它會改變執行環境作用域鏈。同樣,try-catch語句中的catch子句也有同樣的影響
  • 巢狀的物件成員會明顯影響效能,儘量少用
  • 屬性或方法在原型鏈中的位置越深,訪問它的速度也越慢
  • 通過把常用的物件,陣列,跨域變數儲存在區域性變數中,來改善javascript的效能,因為區域性變數訪問速度最快

三、DOM編輯

  • 最小化 DOM 訪問次數,儘可能在javascript端處理
  • 如果需要多次訪問某個DOM節點,請使用區域性變數儲存它的引用
  • 小心處理HTML集合,因為它實時連繫著底層文件。把集合的長度快取到一個變數中,並在迭代中使用它。如果需要經常操作集合,建議把它拷貝到一個數組中
  • 如果可能的話,使用速度更快的API,比如 querySelectorAll() 和 firstElementChild
  • 要留意重繪和重排,批量修改樣式時,‘離線’操作DOM樹,使用快取,並減少訪問佈局資訊的次數
  • 使用事件委託來減少事件處理器的次數

四、演算法和流程控制

  • for、while和do-while迴圈效能特性相當,並沒有一種迴圈型別明顯快於或慢於其他型別
  • 避免使用 for-in 迴圈,除非你需要遍歷一個屬性數量未知的物件
  • 改善迴圈效能的最佳方式是減少每次迭代的運算量和減少迴圈迭代次數
  • 通常來說,swich 總是比 if-else 塊,但並不總是最佳解決方案
  • 在判斷條件較多時,使用查詢表比 if-else 和 switch 更快
  • 瀏覽器的呼叫棧大小限制了遞迴演算法在 javascript 中的應用,棧溢位錯誤會導致其他程式碼中斷執行
  • 如果你遇到棧溢位錯誤,可將方法改為迭代演算法,或使用 Memoization 來避免重複計算

五、字串和正則表示式

  • 當連線資料巨大或尺寸巨大的字串時,陣列項合併是唯一在IE7及更早版本中效能合理的方法
  • 如果不需要考慮IE7及更早版本的效能,陣列項合併是最慢的字串連線方法之一。推薦使用簡單的+和+=操作符替代,避免不必要的中間字串
  • 回溯既是正則表示式匹配功能的基本組成部分,也是正則表示式的低效之源
  • 回溯失控發生在正則表示式本應快速匹配的地方,但因為某些特殊的字串匹配動作導致執行緩慢甚至瀏覽器崩潰。避免這個問題的辦法是:使相鄰的字元互斥,避免巢狀量詞對同一字串的相同部分多次匹配,通過重複利用預查的原子組去除不必要的回溯
  • 提高正式表示式效率的各種技術手段會有助於正則表示式更快地匹配,並在非匹配位置上花更少的時間
  • 正則表示式並不總是完成工作的最佳工具,尤其當你只搜尋字面字串的時候
  • 儘管有許多方法可以去除字串的首尾空白,但使用兩個簡單的正則表示式(一個去除頭部空白,一個去除尾部空白)來處理大量字串內容能提供一個簡潔而跨瀏覽器的方法。從字串末尾開始迴圈向前搜尋第一個非空白字元,或者將此技術同正則表示式結合起來,會提供一個更好的替代方案,它很少受到字串長度影響

六、快速響應的使用者介面

  • 任何 Javascript 任務都不應當執行超過 100 毫秒。過長的執行時間會導致 UI 更新出現明顯的延遲,從而對使用者體驗產生負面影響
  • Javascript 執行期間,瀏覽器響應使用者互動的行為存在差異。無論如何,Javascript 長時間執行將導致使用者體驗變得混亂和脫節
  • 定時器可用來安排程式碼延遲執行,它使得你可以把長時間執行指令碼分解成一系列的小任務
  • Web Workers 是新版瀏覽器支援的特性,它允許你在 UI 執行緒外部執行 Javascript 程式碼,從而避免鎖定 UI

七、Ajax

  • 瞭解專案的具體需求,選擇正確的資料格式和與之匹配的傳輸技術
  • 作為資料格式,純文字和HTML只適用於特定場合,但它們可以節省客戶端的CPU週期。XML被廣泛應用且支援性良好,但是它十分笨重且解析緩慢。JSON是輕量級的,解析速度快,通用性與XML相當。字元分隔的自定義格式十分輕量,在解析大量資料集時非常快,但需要編寫額外的伺服器構造程式,並在客戶端解析。
  • 從頁面當前所處的域下請求資料時,XHR提供了最完善的控制和靈活性,儘管它會把接收到的所有資料當成一個字串,且這有可能降低解析速度。另一方面,動態指令碼注入允許跨域請求和本地執行Javascript和JSON,但是它的介面不那麼安全,而且還不能讀取頭資訊或響應程式碼。Multipart XHR 可以用來減少請求數,並處理一個響應中的各種檔案型別,但是它不能快取接收到的響應。當需要傳送資料時,圖片信標是一種簡單而有效的方法。XHR可以用POST方法傳送大量資料。
  • 減少請求數,可以通過合併javascript和css檔案,或使用MXHR
  • 縮短頁面的載入時間,頁面主要內容載入完成後,用Ajax獲取那些次要的檔案
  • 確保你的程式碼錯誤不會輸出給使用者,並在伺服器端處理錯誤
  • 知道何時使用成熟的Ajax類庫,以及何時編寫自己的底層 Ajax程式碼

八、程式設計實踐

  • 通過避免使用eval() 和 Function() 構造器來避免雙重求值帶來的效能消耗。同樣的,給setTimeout() 和 setInterval()傳遞函式 而不是 字串 作為引數
  • 儘量直接使用直接量建立物件和陣列。直接量的建立和初始化都比非直接量形式要快
  • 避免做重複的工作,當需要檢測瀏覽器時,可使用延遲載入或條件預載入
  • 在進行數學計算時,考慮使用直接運算元字的二進位制形式的位運算
  • Javascript 在原生方法 總會比自己寫的任何程式碼都要快。儘量使用原生方法

九、部署

  • 合併javascript檔案以減少HTTP請求數
  • 壓縮 Javascript檔案
  • 在伺服器端壓縮 Javascript檔案
  • 通過正確設定HTTP響應頭來快取 Javascript檔案,通過向檔名增加時間戳來避免快取問題
  • 使用CDN提供Javascript檔案;CDN不僅可以提升效能,它也為你管理檔案的壓縮和快取

十、工具

  • 使用網路分析工具找出載入指令碼和頁面中共他資源的瓶頸,這會幫助你決定哪些指令碼需要延遲載入,或者需要進一步分析
  • 儘管傳統的經驗告訴我們要儘量減少HTTP請求數,但把指令碼儘可能延遲載入可以加快頁面渲染速度,給使用者帶來更好的體驗
  • 使用效能分析工具找出指令碼執行過程中速度慢的地方,檢查每個函式所消耗的時間,以及函式被呼叫的次數,通過呼叫棧自身提供的一些線索來找出需要集中精力優化的地方
  • 儘管耗費的時間和呼叫次數通常是資料中最有價值的部分,但仔細觀察函式的呼叫過程,你也許會發現其他優化目標