1. 程式人生 > 實用技巧 >前端效能優化整理總結

前端效能優化整理總結

gzip壓縮

gzip壓縮效率很高,可以達到70%的壓縮率

//npm i -D compression-webpack-plugin  安裝外掛依賴
configureWebpack: config => {
  const CompressionPlugin = require('compression-webpack-plugin')
  config.plugins.push(new CompressionPlugin())
}

去掉console.log

生產環境中,不需要列印日誌。通過對webpack進行配置,打包時自動去掉console.log

//npm i -D terser-webpack-plugin
configureWebpack:config =>{
    const  TerserPlugin = require('terser-webpack-pulugin')
    config.optimzation.minimizer.push(
    	new TerserPlugin({
            extractComments:false,
            terserOptions:{compress:{drop_console:true}} //外掛配置項 移除console
        })
    )
}

去除SourceMap

程式碼壓縮後進行調bug定位將非常困難,於是引入sourcemap記錄壓縮前後的位置資訊記錄,當產生錯誤時直接定位到未壓縮前的位置,將大大的方便我們除錯。

sourcemap附帶了很多資訊,如果build需要生成sourcemap,將會大大降低build的速度,還會增加包的體積。

//vue 中
module.exports = {
  productionSourceMap: false,
}

//react中
//開啟webpack.config.prod.js
const shouldUseSourceMap = false

CDN

內容分發網路,它能夠實時地根據網路流量和各節點的連線、負載狀況以及到使用者的距離和響應時間等綜合資訊將使用者的請求重新導向離使用者最近的服務節點上。其目的是使使用者可就近取得所需內容,解決 Internet網路擁擠的狀況,提高使用者訪問網站的響應速度。所以可以通過將資源部署在CDN上來提高響應速度,提高使用者體驗

預渲染

簡單來說,就是將瀏覽器解析JavaScript動態渲染的工作,在打包階段完成了(只構建了靜態資料)。換個說法,在構建過程中,webpack通過使用prerender-spa-plugin外掛生成靜態結構的html

// 1、安裝prerender-spa-plugin
npm install prerender-spa-plugin --save-dev
 
// 2、安裝vue-meta-info
npm install vue-meta-info --save-dev
 
 
// 3、相關配置
<!-- webpack.prod.conf.js -->
// 預渲染配置:在webpack.prod.conf檔案中加入
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
 
// 在 plugins 中加入
new PrerenderSPAPlugin({
      // 生成檔案的路徑,也可以與webpakc打包的一致。
      // 下面這句話非常重要!!!
      // 這個目錄只能有一級,如果目錄層次大於一級,在生成的時候不會有任何錯誤提示,在預渲染的時候只會卡著不動。
      staticDir: path.join(__dirname, '../dist'),
 
      // 對應自己的路由檔案,比如a有引數,就需要寫成 /a/param1。
      routes: ['/', '/first', '/second', '/third', '/fourth', '/userCenter/userFirst','/userCenter/userSecond','/userCenter/userThird'],
 
      // 這個很重要,如果沒有配置這段,也不會進行預編譯
      renderer: new Renderer({
        inject: {
          foo: 'bar'
        },
        // headless: false,
        renderAfterDocumentEvent: 'render-event', // 在 main.js 中 document.dispatchEvent(new Event('render-event')),兩者的事件名稱要對應上。
        args: ['--no-sandbox', '--disable-setuid-sandbox']
      })
    })
 
// 4、在main.js中
import MetaInfo from 'vue-meta-info'
 
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
  // 新增mounted,不然不會執行預編譯
  mounted () {
    document.dispatchEvent(new Event('render-event'))
  }
})

注意:路由模式必須為 history ,如果不設定 history 模式,也能執行和生成檔案,每個 index.html 檔案的內容都會是一樣的

Service Worker

ServiceWorker 是執行在瀏覽器後臺程序裡的一段 JS,它可以做許多事情,比如攔截客戶端的請求、向客戶端傳送訊息、向伺服器發起請求等等,其中最重要的作用之一就是離線資源快取。

ServiceWorker 擁有對快取流程豐富靈活的控制能力,當頁面請求到 ServiceWorker 時,ServiceWorker 同時請求快取和網路,把快取的內容直接給使用者,而後覆蓋快取

注意:需要HTTPS才能使用ServiceWorker

HTTP快取

HTTP快取一般分為兩類:強快取(本地快取)、協商快取(304快取)

普通重新整理會啟用協商快取

在位址列輸入網址、通過連結引入資源等情況下,瀏覽器才啟用強快取

強快取(200)。本地快取是最快速的一種快取方式,只要資源還在快取有效期內,瀏覽器就會直接在本地讀取,不會請求服務端。在chrome控制檯的Network選項中可以看到該請求返回200的狀態碼,並且Size顯示from disk cache或from memory cache。強快取可以通過設定兩種 HTTP Header 實現:Expires 和 Cache-Control。

協商快取(304)。協商快取,顧名思義是經過瀏覽器與伺服器之間協商過之後,在決定是否讀取本地快取,如果伺服器通知瀏覽器可以讀取本地快取,會返回304狀態碼,並且協商過程很簡單,只會傳送頭資訊,不會發送響應體。

協商快取可以通過設定兩種 HTTP Header 實現:Last-Modified 和 ETag

首先在精確度上,Etag要優於Last-Modified

第二在效能上,Etag要遜於Last-Modified,畢竟Last-Modified只需要記錄時間,而Etag需要伺服器通過演算法來計算出一個hash值

第三在優先順序上,伺服器校驗優先考慮Etag

快取優先順序:Service Worker -> Memory Cache(記憶體快取) -> Disk Cache(硬碟快取) -> Push Cache(推送快取)

Push Cache 只在會話(session)中存在,會話結束就被釋放,而且快取時間很短

HTTP2

HTTP2 四個新特性:

  • 多路複用,無需多個TCP連線,因為其允許在單一的HTTP2連線上發起多重請求,因此可以不用依賴建立多個TCP連線。
  • 二進位制分幀,將所有要傳輸的訊息採用二進位制編碼,並且會將資訊分割為更小的訊息塊。
  • 頭部壓縮,用HPACK技術壓縮頭部,減小報文大小
  • 服務端推送,服務端可以在客戶端發起請求前傳送資料,換句話說,服務端可以對客戶端的一個請求傳送多個相應,並且資源可以正常快取。
server {
    listen 443 ssl http2;
}

資源預載入

提前載入資源,當用戶需要時,可以直接從本地快取中渲染。

preload

頁面載入的過程中,在瀏覽器開始主體渲染之前載入

//對sty1e.cs5和 index.js進行pre1oad預載入
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="index.js" as="script">

prefetch

頁面載入完成後,利用空閒時間提前載入

//對資源進行 prefetch預載入
<link rel="prefetch" href="next.css">
<link rel="prefetch" href="next.js">

dns-prefetch

//對特定域名進行預解析
//將靜態資源只放在一個域名下面,可以有效減少dns的請求
<link rel=”dns-prefetch” href=”//fonts.googleapis.com”>

非同步無阻塞載入JS

非同步載入 js 檔案,並且不會阻塞頁面的渲染。

普通的script標籤在開始解析和解析的過程中,會停止解析dom

defer

<script src="d.js" defer></script> <script src="e.js" defer></script>

在其他同步指令碼執行後,DOMContentLoaded 事件前 依次執行 d.js, e.js。

async

<script src="b.js" async></script>
<script src="c.js" async></script>

當指令碼下載完後立即執行。(兩者執行順序不確定,執行階段不確定,可能在 DOMContentLoaded 事件前或者後 )

defer和async都不會停止解析dom

webp

webp 是一種新的圖片格式,它的體積只有只有 jpeg的2/3,將圖片資源大量換成 webp 格式可以加快請求的速度

但是webp存在瀏覽器相容問題,使用前需要判斷瀏覽器是否支援

loading載入

通過新增載入中狀態,可以讓使用者在視覺上不會覺得慢

可以通過骨架屏載入,在感官上內容出現的流暢不突兀