欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

webpack的異步加載原理是什么

這篇文章主要講解了“webpack的異步加載原理是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“webpack的異步加載原理是什么”吧!

創(chuàng)新互聯(lián)公司2013年至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都做網(wǎng)站、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元臨安做網(wǎng)站,已為上家服務(wù),為臨安各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:13518219792

webpack 異步加載原理

webpack ensure 有人稱它為異步加載,也有人稱為代碼切割,他其實(shí)就是將 js 模塊給獨(dú)立導(dǎo)出一個(gè).js 文件,然后使用這個(gè)模塊的時(shí)候,再創(chuàng)建一個(gè) script 對(duì)象,加入到 document.head 對(duì)象中,瀏覽器會(huì)自動(dòng)幫我們發(fā)起請(qǐng)求,去請(qǐng)求這個(gè) js 文件,然后寫個(gè)回調(diào)函數(shù),讓請(qǐng)求到的 js 文件做一些業(yè)務(wù)操作。

舉個(gè)例子

需求:main.js 依賴兩個(gè) js 文件:A.js 是點(diǎn)擊 aBtn 按鈕后,才執(zhí)行的邏輯,B.js 是點(diǎn)擊 bBtn 按鈕后,才執(zhí)行的邏輯。

webpack.config.js,我們先來(lái)寫一下 webpack 打包的配置的代碼

const path = require('path') // 路徑處理模塊  const HtmlWebpackPlugin = require('html-webpack-plugin')  const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 引入CleanWebpackPlugin插件  module.exports = {    entry: {      index: path.join(__dirname, '/src/main.js'),    },    output: {      path: path.join(__dirname, '/dist'),      filename: 'index.js',    },    plugins: [      new HtmlWebpackPlugin({        template: path.join(__dirname, '/index.html'),      }),      new CleanWebpackPlugin(), // 所要清理的文件夾名稱    ],  }

index.html 代碼如下

<!DOCTYPE html>  <html lang="en">    <head>      <meta charset="UTF-8" />      <meta name="viewport" content="width=device-width, initial-scale=1.0" />      <title>webpack</title>    </head>    <body>      <div id="app">        <button id="aBtn">按鈕A</button>        <button id="bBtn">按鈕B</button>      </div>    </body>  </html>

入口文件 main.js 如下

import A from './A'  import B from './B'  document.getElementById('aBtn').onclick = function () {    alert(A)  }  document.getElementById('bBtn').onclick = function () {    alert(B)  }

A.js 和 B.js 的代碼分別如下

// A.js  const A = 'hello A'  module.exports = A  // B.js  const B = 'hello B'  module.exports = B

此時(shí),我們對(duì)項(xiàng)目進(jìn)行 npm run build, 打包出來(lái)的只有兩個(gè)文件

  •  index.html

  •  index.js

由此可見(jiàn),此時(shí) webpack 把 main.js 依賴的兩個(gè)文件都同時(shí)打包到同一個(gè) js 文件,并在 index.html 中引入。但是 A.js 和 B.js 都是點(diǎn)擊相應(yīng)按鈕才會(huì)執(zhí)行的邏輯,如果用戶并沒(méi)有點(diǎn)擊相應(yīng)按鈕,而且這兩個(gè)文件又是比較大的話,這樣是不是就導(dǎo)致首頁(yè)默認(rèn)加載的 js 文件太大,從而導(dǎo)致首頁(yè)渲染較慢呢?那么有能否實(shí)現(xiàn)當(dāng)用戶點(diǎn)擊按鈕的時(shí)候再加載相應(yīng)的依賴文件呢?

webpack.ensure 就解決了這個(gè)問(wèn)題。

require.ensure 異步加載

下面我們將 main.js 改成異步加載的方式

document.getElementById('aBtn').onclick = function () {    //異步加載A    require.ensure([], function () {      let A = require('./A.js')      alert(A)    })  }   document.getElementById('bBtn').onclick = function () {    //異步加載b    require.ensure([], function () {      let B = require('./B.js')      alert(B)    })  }

此時(shí),我們?cè)龠M(jìn)行一下打包,發(fā)現(xiàn)多了 1.index.js 和 2.index.js 兩個(gè)文件。而我們打開(kāi)頁(yè)面時(shí)只引入了 index.js 一個(gè)文件,當(dāng)點(diǎn)擊按鈕 A 的時(shí)候才引入 1.index.js 文件,點(diǎn)擊按鈕 B 的時(shí)候才引入 2.index.js 文件。這樣就滿足了我們按需加載的需求。

require.ensure 這個(gè)函數(shù)是一個(gè)代碼分離的分割線,表示回調(diào)里面的 require 是我們想要進(jìn)行分割出去的,即 require('./A.js'),把 A.js 分割出去,形成一個(gè) webpack 打包的單獨(dú) js 文件。它的語(yǔ)法如下

require.ensure(dependencies: String[], callback: function(require), chunkName: String)

我們打開(kāi) 1.index.js 文件,發(fā)現(xiàn)它的代碼如下

(windowwindow.webpackJsonp = window.webpackJsonp || []).push([    [1],    [      ,      function (o, n) {        o.exports = 'hello A'      },    ],  ])

由上面的代碼可以看出:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2.  異步加載的代碼,會(huì)保存在一個(gè)全局的 webpackJsonp 中。

  3.  webpackJsonp.push 的的值,兩個(gè)參數(shù)分別為異步加載的文件中存放的需要安裝的模塊對(duì)應(yīng)的 id 和異步加載的文件中存放的需要安裝的模塊列表。

  4.  在滿足某種情況下,會(huì)執(zhí)行具體模塊中的代碼。

import() 按需加載

webpack4 官方文檔提供了模塊按需切割加載,配合 es6 的按需加載 import() 方法,可以做到減少首頁(yè)包體積,加快首頁(yè)的請(qǐng)求速度,只有其他模塊,只有當(dāng)需要的時(shí)候才會(huì)加載對(duì)應(yīng) js。

import()的語(yǔ)法十分簡(jiǎn)單。該函數(shù)只接受一個(gè)參數(shù),就是引用包的地址,并且使用了 promise 式的回調(diào),獲取加載的包。在代碼中所有被 import()的模塊,都將打成一個(gè)單獨(dú)的包,放在 chunk 存儲(chǔ)的目錄下。在瀏覽器運(yùn)行到這一行代碼時(shí),就會(huì)自動(dòng)請(qǐng)求這個(gè)資源,實(shí)現(xiàn)異步加載。

下面我們將上述代碼改成 import()方式。

document.getElementById('aBtn').onclick = function () {    //異步加載A    import('./A').then((data) => {      alert(data.A)    })  }  document.getElementById('bBtn').onclick = function () {    //異步加載b    import('./B').then((data) => {      alert(data.B)    })  }

此時(shí)打包出來(lái)的文件和 webpack.ensure 方法是一樣的。

路由懶加載

為什么需要懶加載?

像 vue 這種單頁(yè)面應(yīng)用,如果沒(méi)有路由懶加載,運(yùn)用 webpack 打包后的文件將會(huì)很大,造成進(jìn)入首頁(yè)時(shí),需要加載的內(nèi)容過(guò)多,出現(xiàn)較長(zhǎng)時(shí)間的白屏,運(yùn)用路由懶加載則可以將頁(yè)面進(jìn)行劃分,需要的時(shí)候才加載頁(yè)面,可以有效的分擔(dān)首頁(yè)所承擔(dān)的加載壓力,減少首頁(yè)加載用時(shí)。

vue 路由懶加載有以下三種方式

  •  vue 異步組件

  •  ES6 的 import()

  •  webpack 的 require.ensure()

vue 異步組件

這種方法主要是使用了 resolve 的異步機(jī)制,用 require 代替了 import 實(shí)現(xiàn)按需加載

export default new Router({    routes: [      {        path: '/home',',        component: (resolve) => require(['@/components/home'], resolve),      },      {        path: '/about',',        component: (resolve) => require(['@/components/about'], resolve),      },    ],  })

require.ensure

這種模式可以通過(guò)參數(shù)中的 webpackChunkName 將 js 分開(kāi)打包。

export default new Router({    routes: [      {        path: '/home',        component: (resolve) => require.ensure([], () => resolve(require('@/components/home')), 'home'),     },      {        path: '/about',        component: (resolve) => require.ensure([], () => resolve(require('@/components/about')), 'about'),      },    ],  })

ES6 的 import()

vue-router 在官網(wǎng)提供了一種方法,可以理解也是為通過(guò) Promise 的 resolve 機(jī)制。因?yàn)?Promise 函數(shù)返回的 Promise 為 resolve 組件本身,而我們又可以使用 import 來(lái)導(dǎo)入組件。

export default new Router({    routes: [      {        path: '/home',        component: () => import('@/components/home'),      },      {        path: '/about',        component: () => import('@/components/home'),      },    ], })

webpack 分包策略

在 webpack 打包過(guò)程中,經(jīng)常出現(xiàn) vendor.js, app.js 單個(gè)文件較大的情況,這偏偏又是網(wǎng)頁(yè)最先加載的文件,這就會(huì)使得加載時(shí)間過(guò)長(zhǎng),從而使得白屏?xí)r間過(guò)長(zhǎng),影響用戶體驗(yàn)。所以我們需要有合理的分包策略。

CommonsChunkPlugin

在 Webapck4.x 版本之前,我們都是使用 CommonsChunkPlugin 去做分離

plugins: [    new webpack.optimize.CommonsChunkPlugin({      name: 'vendor',      minChunks: function (module, count) {        return (          module.resource &&          /.js$/.test(module.resource) &&          module.resource.indexOf(path.join(__dirname, './node_modules')) === 0        )      },    }),    new webpack.optimize.CommonsChunkPlugin({      name: 'common',      chunks: 'initial',      minChunks: 2,    }),  ]

我們把以下文件單獨(dú)抽離出來(lái)打包

  •  node_modules 文件夾下的,模塊

  •  被 3 個(gè) 入口 chunk 共享的模塊

optimization.splitChunks

webpack 4 最大的改動(dòng)就是廢除了 CommonsChunkPlugin 引入了 optimization.splitChunks。如果你的 mode 是 production,那么 webpack4 就會(huì)自動(dòng)開(kāi)啟 Code Splitting。

它內(nèi)置的代碼分割策略是這樣的:

  •  新的 chunk 是否被共享或者是來(lái)自 node_modules 的模塊

  •  新的 chunk 體積在壓縮之前是否大于 30kb

  •  按需加載 chunk 的并發(fā)請(qǐng)求數(shù)量小于等于 5 個(gè)

  •  頁(yè)面初始加載時(shí)的并發(fā)請(qǐng)求數(shù)量小于等于 3 個(gè)

雖然在 webpack4 會(huì)自動(dòng)開(kāi)啟 Code Splitting,但是隨著項(xiàng)目工程的最大,這往往不能滿足我們的需求,我們需要再進(jìn)行個(gè)性化的優(yōu)化。

應(yīng)用實(shí)例

我們先找到一個(gè)優(yōu)化空間較大的項(xiàng)目來(lái)進(jìn)行操作。這是一個(gè)后臺(tái)管理系統(tǒng)項(xiàng)目,大部分內(nèi)容由 3-4 個(gè)前端開(kāi)發(fā),平時(shí)開(kāi)發(fā)周期較短,且大部分人沒(méi)有優(yōu)化意識(shí),只是寫好業(yè)務(wù)代碼完成需求,日子一長(zhǎng),造成打包出來(lái)的文件較大,大大影響性能。

我們先用 webpack-bundle-analyzer 分析打包后的模塊依賴及文件大小,確定優(yōu)化的方向在哪。

webpack的異步加載原理是什么

然后我們?cè)倏聪麓虬鰜?lái)的 js 文件

webpack的異步加載原理是什么

看到這兩張圖的時(shí)候,我內(nèi)心是崩潰的,槽點(diǎn)如下

  •  打包后生成多個(gè)將近 1M 的 js 文件,其中不乏 vendor.js 首頁(yè)必須加載的大文件

  •  xlsx.js 這樣的插件沒(méi)必要使用,導(dǎo)出 excel 更好的方法應(yīng)該是后端返回文件流格式給前端處理

  •  echart 和 iview 文件太大,應(yīng)該使用 cdn 引入的方法

吐槽完之后我們就要開(kāi)始做正事了。正是因?yàn)橛羞@么多槽點(diǎn),我們才更好用來(lái)驗(yàn)證我們優(yōu)化方法的可行性。

抽離 echart 和 iview

由上面分析可知,echart 和 iview 文件太大,此時(shí)我們就用到 webpack4 的 optimization.splitChunks 進(jìn)行代碼分割了,把他們單獨(dú)抽離打包成文件。(為了更好地呈現(xiàn)優(yōu)化效果,我們先把 xlsx.js 去掉)

vue.config.js 修改如下:

chainWebpack: config => {      config.optimization.splitChunks({        chunks: 'all',        cacheGroups: {          vendors: {            name: 'chunk-vendors',            test: /[/]node_modules[/]/,            priority: 10,            chunks: 'initial'          },          iview: {            name: 'chunk-iview',            priority: 20,            test: /[/]node_modules[/]_?iview(.*)/          },          echarts: {            name: 'chunk-echarts',            priority: 20,            test: /[/]node_modules[/]_?echarts(.*)/          },          commons: {            name: 'chunk-commons',            minChunks: 2,            priority: 5,            chunks: 'initial',            reuseExistingChunk: true          }        }      })    },

此時(shí)我們?cè)儆?webpack-bundle-analyzer 分析一下

webpack的異步加載原理是什么

打包出來(lái)的 js 文件

webpack的異步加載原理是什么

從這里可以看出我們已經(jīng)成功把 echart 和 iview 單獨(dú)抽離出來(lái)了,同時(shí) vendor.js 也相應(yīng)地減小了體積。此外,我們還可以繼續(xù)抽離其他更多的第三方模塊。

CDN 方式

雖然第三方模塊是單獨(dú)抽離出來(lái)了,但是在首頁(yè)或者相應(yīng)路由加載時(shí)還是要加載這樣一個(gè)幾百 kb 的文件,還是不利于性能優(yōu)化的。這時(shí),我們可以用 CDN 的方式引入這樣插件或者 UI 組件庫(kù)。

  1.  在 index.html 引入相應(yīng) cdn 鏈接

<head>    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/iview/3.5.4/styles/iview.css" /> </head>  <body>    <div id="app"></div>    <script src="https://cdn.bootcss.com/vue/2.6.8/vue.min.js"></script>    <script src="https://cdn.bootcdn.net/ajax/libs/iview/3.5.4/iview.min.js"></script>    <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.8/xlsx.mini.min.js"></script>    <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.8/cpexcel.min.js"></script>  </body>

  1.  vue.config.js 配置 externals

configureWebpack: (config) => {    config.externals = {      vue: 'Vue',      xlsx: 'XLSX',      iview: 'iView',      iView: 'ViewUI',    }  }

  1.  刪除之前的引入方式并卸載相應(yīng) npm 依賴包

npm uninstall vue iview echarts xlsx --save

此時(shí)我們?cè)趤?lái)看一下打包后的情況

webpack的異步加載原理是什么

打包出來(lái)的 js 文件

webpack的異步加載原理是什么

well done ! 這時(shí)基本沒(méi)有打包出大文件了,首頁(yè)加載需要的 vendor.js 也只有幾十 kb,而且我們還可以進(jìn)一步優(yōu)化,就是把 vue 全家桶的一些模塊再通過(guò) cdn 的方法引入,比如 vue-router,vuex,axios 等。這時(shí)頁(yè)面特別是首頁(yè)加載的性能就得到大大地優(yōu)化了。

感謝各位的閱讀,以上就是“webpack的異步加載原理是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)webpack的異步加載原理是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站題目:webpack的異步加載原理是什么
文章位置:http://aaarwkj.com/article22/peepjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站維護(hù)、域名注冊(cè)定制網(wǎng)站、全網(wǎng)營(yíng)銷推廣Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司
亚洲天堂国产成人精品| 亚洲乱码中文字幕久久| 十八禁无遮挡污污污网站| 最新国产av网址大全| 国产亚洲精品第一综合| 欧美三级精品三级在线| 男女性情视频免费大全网站| 国产一区二区黑丝美女| 久久久国产精品视频网站| 九九视频免费观看91| 欧美一区二区三区十区| 萌白的所有视频在线观看| 日韩精品一区二区三区中文| 变态另类欧美国产在线| 精品久久一区麻豆香蕉| 四季一区二区三区av| 中文字幕一区二区三区久久| 亚洲国产日韩伦中文字幕| 国产一级内射视频免费观看| 四虎精品在线免费视频| 亚洲一区二区实拍偷拍视频| 日本成年网站在线观看| 中文字幕韩国三级电影| 亚洲日本精品国产第一区| 五月婷婷av综合激情| 亚洲二区三区四区在线| 国产原创传媒在线观看| 日韩无码一区二区视频| 精品嫩模福利一区二区蜜臀| 日本精品av一区二区| 日本熟女视频中文字幕| 国产欧美日韩另类视频| 91精品人妻二区三区| 日韩欧美一区二区黄色| 日韩av一区二区人妻| 97碰碰视频在线观看| 国产一区二区三区av网站| 亚洲熟女内射特写一区| 国产a天堂一区二区专区| 亚洲精品丝袜成人偷拍| 亚洲精品伦理中文字幕|