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

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

自定義 fun 相同 函數的調用 動態腳本 簡單的 渲染 編寫 字符串長度

一、加載與執行

  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請求數,但把腳本盡可能延遲加載可以加快頁面渲染速度,給用戶帶來更好的體驗
  • 使用性能分析工具找出腳本運行過程中速度慢的地方,檢查每個函數所消耗的時間,以及函數被調用的次數,通過調用棧自身提供的一些線索來找出需要集中精力優化的地方
  • 盡管耗費的時間和調用次數通常是數據中最有價值的部分,但仔細觀察函數的調用過程,你也許會發現其他優化目標

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