再談 webpack build 及 加載優化

以前項目多,事情忙,一直沒時間寫博客,如今空閒下來了,總結一下javascript

以前講過了關於 build 壓縮文件的方法,有興趣的能夠看下: 點擊查看css

如今講講一個頁面的首屏加載速度該如何提高html

提早說明 須要 webpack-bundle-analyzer 插件來進行 build 文件的分析

異步文件和必須文件

首先是異步文件,能夠按功能分,也能夠按照路由分塊,目的就是儘可能較少首次加載的必須代碼的大小
即登陸,註冊和必須存在的組件是必須加載組件,優先度最高,這些組件是不能爲異步的,其餘儘可能都要設置爲異步組件java

若是你的項目足夠小,一個 main 文件總共200k 那麼能夠不使用分塊(僅限 web 端,移動端另說)node

由於我使用的是 react+antd 還有一些附帶的大包 如 immutable,moment,babel-polyfill等,並且最重要的是這些包是必須的,大小快接近1M了react

固然我是不會將接近 1M 的必需文件放在一個加載包裏的,這樣的話首屏加載恐怕要2S以上了webpack

這個時候 webpack 的分塊功能就出來了web

通常來講 瀏覽器的併發數量是6個資源,webpack 生成文件呢,至少會有一個 css 文件會在 head 加載;瀏覽器

去除 css 剩餘5個位置 1000k/5 = 200k 因此 將 1000k 的必需文件包平均分紅5分,併發加載
速度便可縮短至 1/5 (固然這是理想狀態)緩存

簡單解釋一下: 1我的搬10公斤貨物,須要 1個小時,可是如今一個線程就是一我的,就變成了5我的搬10公斤貨物,速度就只要20分鐘了

如今簡介一下 webpack3 和 webpack4 該怎樣分塊:

webpack3:

new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks(module) {
        return (
          module.resource &&
          /\.js$/.test(module.resource) &&
          !new RegExp('/antd/lib|/react-dom|/moment').test(module.resource) &&
          module.resource.indexOf(
            path.join(__dirname, '../node_modules')
          ) === 0
        )
      }
    })

相似於這樣 RegExp 中的表示不會被加到這個包中,有一點須要注意,剩餘的會自動加在默認包裏,因此我前面纔會說 須要 webpack-bundle-analyzer;
由於想要達到最佳狀態,須要根據插件的頁面屢次試驗分塊

webpack4:

splitChunks: {
      cacheGroups: {
        vendor: {
          test(chunks){
            return !new RegExp('/antd/lib|/react-dom|/moment').test(chunks.context) &&  /[\\/]node_modules[\\/]/.test(chunks.context)
          },
          name: "vendor",
          chunks: "all",
          reuseExistingChunk: true
        }
      }
    }

webpack4 和 3 的道理差很少,只是格式不同罷了


prefetch , preload ,dns-prefetch

這兩個的做用,雖然網上如今也是一搜一大把,我仍是在這裏說下他的做用和我簡單的心得和體會

preload

表示瀏覽器一檢測到該條腳本就會對服務器進行請求,一般會寫在上部,由於越先檢測就越先加載

prefetch

表示瀏覽器一檢測到該條腳本就會在空閒的時候,下載腳本,並緩存到disk

dns-prefetch

表示瀏覽器一檢測到該條腳本就會解析CDN的地址的DNS放的位置越前越好

因此他們分別做用的塊是這樣的:

  • 必須模塊和 cdn 模塊須要的是preload
  • 異步模塊須要的是 prefetch 記住最好是全部異步模塊都加上
  • 使用dns-prefetch前提是你必須先知道域名是什麼,並且更換域名時也要同步更換,效果立竿見影,加快頁面加載時間

下面放上一個標準使用方法:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>title</title>
  <link rel="dns-prefetch" href="//www.grewer.cn/">
  <link rel="preload" as="script" href="/static/js/module1.js" >
  <link rel="preload" as="script" href="/static/js/module2.js">
  <link rel="preload" as="script" href="/static/js/module3.js">
  <link rel="preload" as="style" href="/static/css/main.css">
  <link rel="prefetch" href="/static/js/async1.chunk.js">
  <link rel="prefetch" href="/static/js/async2.chunk.js">
  <link rel="prefetch" href="/static/js/async3.chunk.js">
  <link rel="prefetch" href="/static/js/async4.chunk.js">
  <link rel="prefetch" href="/static/js/async5.chunk.js">
  <link rel="prefetch" href="/static/js/async6.chunk.js">
  <link href="/static/css/main.css" rel="stylesheet">
</head>
<body>

<script type="text/javascript" src="/static/js/module1.js" ></script>
<script type="text/javascript" src="/static/js/module2.js" ></script>
<script type="text/javascript" src="/static/js/module3.js" ></script>
</body>
</html>

http2 服務器推送

http2出來大概3年了吧,大多數人都覺得他的做用就是加密就 HTTPS 而已,其實他還有一個最重要的功能,服務器推送

服務器推送的基礎是 HTTP2,因此須要先升級 而後須要再服務器配置,一旦有客服端請求文件,如 index.html
就能夠將文件立馬推送,並且關鍵仍是他沒有併發限制,好比圖片,你能夠一會兒推送10個,20個,任意個文件! 只有客戶端須要的

效果以下:
服務器推送效果
(圖片來自網絡,若是掛了還請自行尋找)
可是配合 webpack 還有一個問題,就是 webpack 生成的文件會帶有 hash 參數,好比這樣的文件名: /static/js/system.9b7a5941.chunk.js
要推送文件須要知道文件的名稱(也許能夠自動化,可是我不怎麼了解)

這個問題的解決就交給你們了

不過即便沒有服務器推送,有 preload也是十分好用了

結語

減少請求時間的方法有不少,還請你們酌情使用

相關文章
相關標籤/搜索