常見web性能優化策略

衡量指標:window.performance.timing:css

timeingInfo=performance.timing;
複製代碼

MDNhtml

  1. 頁面級別優化webpack

    • 減小HTTP請求次數:web

      • 影響: http請求會帶來時間成本和資源成本。一個完整的http請求,須要通過DNS尋址、與服務器創建鏈接、發送數據、等待服務器響應數據、接收數據的複雜過程;數組

        • 時間成本:表現爲用戶須要看到的或者感覺到的這個資源必須結束的過程;
        • 資源成本:表現爲每一個http請求都須要攜帶數據,所以每一個請求都須要佔用帶寬。因爲瀏覽器進行併發請求的請求數是有上限的,因此,當瀏覽器請求數量多了之後,瀏覽器須要進行分批請求;從而增長用戶的等待時間,給用戶形成站點慢的現象;
      • 途徑:瀏覽器

        • 設計實現層面簡化頁面: 保持頁面的簡潔,減小資源的使用;緩存

        • 合理設置HTTP緩存: 適當的利用緩存能夠減小HTTP請求;原則是緩存越多越久越好。例如:服務器

          一、 不多變化的圖片資源能夠直接經過HTTP Header 中的expires 設置一個很長的過時頭;閉包

          二、變化不頻繁而又有可能變的資源使用Last-Modifed來作請求驗證。併發

      • 資源合併與壓縮

        • 經過webpack等打包工具;將外部JS腳本、css樣式、image等合併爲一個壓縮文件
      • css sprites

        • 合併CSS 圖片,減小請求資源數量;
      • 使用Inline Images ;

        • 使用data:URL schema 的方式將圖片嵌入到CSS中; background: url(data:image/png;base64,iVBORw0KGgoAA AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAA....);
      • Lazy Load Images(圖片懶加載): -減小首屏加載;

    • 將外部腳本置底:

      • 瀏覽器是能夠進行併發請求的,這一特色使其可以更快的加載資源;然而,當外部腳本在加載時,會阻塞其餘的資源,例如,在腳本未加載完成以前,在改腳本後面的圖片資源,樣式資源、其餘的腳本都會處於阻塞狀態,直到當前外部腳本加載完成之後,纔開始執行後面資源的加載。
      • 所以將外部腳本放在靠前的位置,會影響整個頁面的加載速度,從而影響用戶的體驗;
    • 異步執行inline 腳本:

      • inline 腳本對性能的影響和外部腳本相比也是有過之而不及;與外部腳本同樣,當inline 腳本執行的時候,同樣會阻塞併發請求;因爲JS在瀏覽器中的執行是單線程的,當頁面的inline腳本在頁面渲染以前執行時候,會阻塞頁面的渲染;使用setTimeout()或者Web Workers 機制等;
    • Lazy Load Javascript (腳本懶加載):

      • 只在須要的時候,進行加載;例子:YUI的實現中,最初只加載核心模塊、其餘模塊等到了須要的時候進行加載;
    • 將CSS放在HEAD中:

      • 有些瀏覽器在CSS下載完成之後,纔會開始渲染頁面,若是CSS放在其餘的地方,則可能會延遲渲染;
    • 避免重複資源請求: -因爲疏忽或頁面由多個模塊拼接而成,而後每一個模塊中請求了一樣的資源時,會致使資源的重複請求

  2. 代碼級別優化

    • DOM操做:

      • 操做是腳本中最耗性能的;如增長、修改、刪除 DOM元素或者對 DOM集合進行操做; 當你須要遍歷 HTML Collection的時候,儘可能將它轉爲數組後再訪問,以提升性能。 即便不轉換爲數組,也請儘量少的訪問它,例如在遍歷的時候能夠將 length屬性、 成員保存到局部變量後再使用局部變量。

      • 避免使用 eval和 Function

        • 每次 eval 或 Function 構造函數做用於字符串表示的源代碼時,腳本引擎都須要將源代碼轉換成可執行代碼。這是很消耗資源的操做 —— 一般比簡單的函數調用慢 100倍以上。   
        • eval 函數效率特別低,因爲事先沒法知曉傳給 eval 的字符串中的內容,eval在其上下文中解釋要處理的代碼,也就是說編譯器沒法優化上下文,所以只能有瀏覽器在運行時解釋代碼。這對性能影響很大。  
        • Function 構造函數比 eval略好,由於使用此代碼不會影響周圍代碼 ;但其速度仍很慢。   
        • 此外,使用 eval和 Function也不利於Javascript 壓縮工具執行壓縮。
      •  減小做用域鏈查找

        • 做用域鏈查找問題,這一點在循環中是尤爲須要注意的問題。若是在循環中須要訪問非本做用域下的變量時請在遍歷以前用局部變量緩存該變量,並在遍歷結束後再重寫那個變量,這一點對全局變量尤爲重要,由於全局變量處於做用域鏈的最頂端,訪問時的查找次數是最多的。
        •  低效率的寫法:

        var count=0; function countInc(){ for(var i=0;i<1000;i++;){ count++ } }

        相對高效的寫法:

        var count=1;
        
          function countInc(){
          var temCount=count;
          for(var i=0;i<1000;i++ ){
          tempCount++		
        
          	}
          	count=tempCount;
          }
        複製代碼
        • 此外,要減小做用域鏈查找還應該減小閉包的使用。
    • 數據訪問

    • Javascript中的數據訪問包括直接量 (字符串、正則達式 )、變量、對象屬性以及數組,其中對直接量和局部變量的訪問是最快的,對對象屬性以及數組的訪問須要更大的開銷。當出現如下狀況時,建議將數據放入局部變量:

      • 對任何對象屬性的訪問超過 1次
      • 對任何數組成員的訪問次數超過 1次
      • 還應當儘量的減小對對象以及數組深度查找。

初始化頁面優化:

初始化的過程當中,能夠對提高頁面性能:
- JS優化:<script> 標籤加上defer屬性或者async屬性,用於在不阻塞頁面文檔解析的前提下,控制腳本的下載和執行;
 - defer屬性:用戶開啓新的線程下載腳本文件,並使腳本在文檔解析完成以後執行;
 - async屬性:H5新增屬性,用於異步下載腳本文件,下載完畢後當即解釋執行代碼;
- css優化:<link>標籤的ref屬性中的屬性值設置爲preload,可以讓你在你的html頁面中指明哪些資源是在頁面加載完成之後,馬上須要的,css資源將按順序加載,最有的配置加載順序,提升渲染性能;
複製代碼

Issue1:什麼是重繪repaint?什麼是迴流reflow?

參考

轉載於:https://juejin.im/post/5cb59515e51d456e577f934a