1. 程式人生 > >vue專案優化之頁面的按需載入(vue+webpack)

vue專案優化之頁面的按需載入(vue+webpack)

vue+webpack實現頁面的按需載入

        通過vue寫的單頁應用時,可能會有很多的路由引入。當打包構建的時候,javascript包會變得非常大,影響載入。如果我們能把不同路由對應的元件分割成不同的程式碼塊,然後當路由被訪問的時候才載入對應的元件,這樣就更加高效了。這樣會大大提高首屏顯示的速度,但是可能其他的頁面的速度就會降下來。結合Vue的非同步元件和webpackde code splitting feature,輕鬆實現路由元件的懶載入。

就像圖片的懶載入一樣,如果客戶根本就沒有看到那些圖片,而我們卻在開啟頁面的時候全部給載入完了,這樣會大大的增加請求的時間,降低使用者的體驗程度。懶載入在很多的網站都有用到,比如淘寶、京東等等這樣的購物網站,上面的圖片連結等等都很多,如果你把滾軸迅速的往下拉的時候,你可能會看到圖片載入的情況。

        單頁應用也是一樣,使用者可能沒有通過點選跳轉到其他的的頁面,而是隻在主頁面進行了停留,那麼我們就沒有必要把其他頁面的資源全部載入過來。如果使用者點進去再載入。這樣就可以大大提高請求時間,提高使用者的體驗程度。

webpack中提供了require.ensure()來實現按需載入。以前引入路由是通過import 這樣的方式引入,改為const定義的方式進行引入。

        不進行頁面按需載入引入方式:import  home   from '../../common/home.vue'

        進行頁面按需載入的引入方式:const  home = r => require.ensure( [], () => r (require('../../common/home.vue'

)))

下面的內容講解的更為詳細(引自:https://cnodejs.org/topic/586823335eac96bb04d3e305)

webpack ensure相信大家都聽過。有人稱它為非同步載入,也有人說做程式碼切割,那這個傢伙到底是用來幹嘛的?其實說白了,它就是把js模組給獨立匯出一個.js檔案的,然後使用這個模組的時候,webpack會構造script dom元素,由瀏覽器發起非同步請求這個js檔案。

場景分析:

比如應用的首頁裡面有個按鈕,點選後可以開啟某個地圖。開啟地圖的話就要利用百度地圖的js,於是我們不得不在首頁中把百度地圖的js一起打包進去首頁,一個百度地圖的js檔案是非常大的,假設為1m,於是就造成了我們首頁打包的js非常大,使用者開啟首頁的時間就比較長了。

有沒有什麼好的解決方法呢?

解決1

既然打包成同一個js非常大的話,那麼我們完全可以把百度地圖js分類出去,利用瀏覽器的併發請求js檔案處理,這樣的話,會比載入一個js檔案時間小得多。嗯,這也是個不錯的方案。為baidumap.js配置一個新的入口就行了,這樣就能打包成兩個js檔案,都插入html即可(如果baidumap.js被多個入口檔案引用的話,也可以不用將其設定為入口檔案,而且直接利用CommonsChunkPlugin,匯出到一個公共模組即可)可以參考我之前文章webpack模組打包

那還有沒有更好的解決方案呢?

解決2

當然還是有的!我們細想,百度地圖是使用者點選了才彈出來的,也就是說,這個功能是可選的。那麼解決方案就來了,能不能在使用者點選的時候,我在去下載百度地圖的js.當然可以。那如何實現使用者點選的時候再去下載百度地圖的js呢?於是,我們可以寫一個按鈕的監聽器

mapBtn.click(function() {
  //獲取 文件head物件
  var head = document.getElementsByTagName('head')[0];
  //構建 <script>
  var script = document.createElement('script');
  //設定src屬性
  script.async = true;
  script.src = "http://map.baidu.com/.js"
  //加入到head物件中
  head.appendChild(script);
})

上面的幾行程式碼對大家來說都不難。可以在點選的時候,才載入百度地圖,等百度地圖載入完成後,在利用百度地圖的物件去執行我們的操作。ok,講到這裡webpack.ensure的原理也就講了一大半了。它就是把一些js模組給獨立出一個個js檔案,然後需要用到的時候,在建立一個script物件,加入到document.head物件中即可,瀏覽器會自動幫我們發起請求,去請求這個js檔案,在寫個回撥,去定義得到這個js檔案後,需要做什麼業務邏輯操作。

ok,那麼我們就利用webpack的api去幫我們完成這樣一件事情。點選後才進行非同步載入百度地圖js,上面的click載入js時我們自己寫的,webpack可以輕鬆幫我們搞定這樣的事情,而不用我們手寫

mapBtn.click(function() {
  require.ensure([], function() {
    var baidumap = require('./baidumap.js') //baidumap.js放在我們當前目錄下
  })
})

搞定!當然還是分析一下。require.ensure這個函式是一個程式碼分離的分割線,表示 回撥裡面的require是我們想要進行分割出去的,即require(’./baidumap.js’),把baidumap.js分割出去,形成一個webpack打包的單獨js檔案。當然ensure裡面也是可以寫一些同步的require的,比如

var sync = require('syncdemo.js')   //下面ensure裡面也用到

mapBtn.click(function() {
  require.ensure([], function() {
    var baidumap = require('./baidumap.js') //baidumap.js放在我們當前目錄下
    var sync = require('syncdemo.js')  //這個不會獨立出去,因為它已經載入到模組快取中了
  })
})

也就是說,ensure會把沒有使用過的require資源進行獨立分成成一個js檔案. require.ensure的第一個引數是什麼意思呢?[], 其實就是 當前這個 require.ensure所依賴的其他 非同步載入的模組。你想啊?如果A 和 B都是非同步載入的,B中需要A,那麼B下載之前,是不是先要下載A啊?,所以ensure的第一個引數[]是它依賴的非同步模組,但是這裡需要注意的是,webpack會把引數裡面的依賴非同步模組和當前的需要分離出去的非同步模組給一起打包成同一個js檔案,這裡可能會出現一個重複打包的問題, 假設A 和 B都是非同步的, ensure A 中依賴B,ensure B中 依賴A,那麼會生成兩個檔案,都包含A和B模組。 如果想載入A require.ensure([‘A.js’],function) 即可

說完了上面的原理。下面就實踐一下


entry.js 依賴三個 js。

  • Abtn-work.js 是封裝了 abtn按鈕點選後,才執行的業務邏輯
  • Bbtn-work.js 是封裝了 bbtn按鈕點選後,才執行的業務邏輯
  • util.js 是封裝了 entry.js需要利用的工具箱

針對上面的需求,優化方案

假設 Abtn-work.js Bbtn-work.js util.js都是非常大的檔案因為 Abtn-work.js Bbtn-work.js 都不是entry.js必須有的,即可能發生的操作,那麼我們把他們利用非同步載入,當發生的時候再去載入就行了

util.js是entry.js立即馬上依賴的工具箱。但是它又非常的大,所以將其配置打包成一個公共模組,利用瀏覽器的併發載入,加快下載速度。ok,構思完成,開始實現

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>index</title>
  </head>
  <body>
    <div id="aBtn">Abtn</div>
    <div id="bBtn">Bbtn</div>
  </body>
</html>

定義了兩個buttom

然後看看 entry.js

var util_sync = require('./util-sync.js')

alert(util_sync.data)

document.getElementById("aBtn").onclick = function() {

  require.ensure([], function() {
    var awork = require('./workA-async.js')
    alert(awork.data)
    //非同步裡面再匯入同步模組--實際是使用同步中的模組
    var util1 = require('./util-sync.js')
  })
}

document.getElementById("bBtn").onclick = function() {

  require.ensure([], function() {
    var bwork = require('./workB-async.js')
    alert(bwork.data)
  })
}

可以看到,workA-async.js, workB-async.js 都是點選後才ensure進來的。什麼時候載入完成呢?就是 require.ensure() 第二個函式引數,即回撥函式,它表示當下載js完成後,發生的因為邏輯

webpack打包後,形成

其實, 1.1… 2.2…就是我們ensure匯出來的js檔案

我們看看程式碼是如何載入的執行的,點選打包插入js後的html


可以看到,並沒有載入 ensure匯出來的 1.1…js 2.2…js

點選 abtn,


發現瀏覽器下載並載入了 1.1…js

點選 bbtn


發現瀏覽器下載並載入了 2.2…js

 vue專案優化,還有通過減少向伺服器請求的次數來減少等待的時間。比如,一個頁面的資料包括圖片、文字等使用者都已經載入完了,然後使用者通過點選跳轉到了另外一個介面。然後從另外一個介面通過返回又回到了原先的介面。如果沒有設定的話,那麼原先介面的資訊就要重新向伺服器請求得到。而通過vue提供的keep-alive可以是頁面的已經請求的資料得以儲存,減少請求的次數,提高使用者的體驗程度。

相關推薦

vue專案優化頁面載入(vue+webpack)

vue+webpack實現頁面的按需載入        通過vue寫的單頁應用時,可能會有很多的路由引入。當打包構建的時候,javascript包會變得非常大,影響載入。如果我們能把不同路由對應的元件分割成不同的程式碼塊,然後當路由被訪問的時候才載入對應的元件,這樣就更加高效

vue專案優化載入元件-使用webpack require.ensure

用 vue-cli構建的專案,在 預設情況下 ,執行 npm run build  會將所有的js程式碼打包為一個整體, 打包位置是 dist/static/js/app.[contenthash].js    類似下面的路由程式碼  router/index.j

vue專案優化使用webpack載入資源(require.ensure)

router/index.js 路由相關資訊,該路由檔案引入了多個 .vue元件import Hello from '@/components/Hello' import Province from '@/components/Province' import Segment

vue開發路由載入

       通過vue寫的單頁應用時,可能會有很多的路由引入。就像圖片的懶載入一樣,如果客戶根本就沒有看到那些圖片,而我們卻在開啟頁面的時候全部給載入完了,這樣會大大的增加請求的時間,降低使用者的體驗程度。        使用 vue-cli構建的專案,在 預設情況下 ,

React學習旅----載入Antd UI元件及自定義主題

package.json "babel": { "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "a

Vue專案中Element-Ui引入

重點:不管是全部引入還是按需引入,都要安裝element-ui的。   npm i element-ui -D 完事後可以在package.json的dev標籤下看到element。 npm i element-ui -D (解釋一下:npm是node包管理器,i是insta

pdfjs優化,實現載入,節省流量和記憶體

1 問題   當使用pdfjs來實現預覽功能的時候,遇到了2個問題:   一是頻寬佔用過大,會下載整個pdf檔案,這對部署在公網的應用來說,成本壓力很大,因為雲服務頻寬是很貴的。   二是記憶體佔用過大,一個80M的pdf,在預覽時佔用記憶體高達600M,在一些記憶體較小的手機上容易發生崩潰。   pdfjs

vue專案實現載入的3種方式:vue非同步元件、es提案的import()、webpack的require.ensure()

1. vue非同步元件技術 vue-router配置路由,使用vue的非同步元件技術,可以實現按需載入。 但是,這種情況下一個元件生成一個js檔案。 舉例如下: { path: '/promisedemo', na

載入iviei元件時,引入vue專案報iview is not defined解決辦法(使用vue-vli + iview)

解決方法 npm 下載(我使用了淘寶映象): cnpm install iview --save cnpm install babel-plugin-import --save-dev .babelrc檔案 { "presets": [ ["env", {

vue專案引用 iView 元件——全域性安裝與載入

隨著Vue框架的熱度,出現了不少基於Vue的UI元件庫,這次專案用到了 iView 這個元件庫。使用方法官網很詳細。 官網:https://www.iviewui.com/ 這篇文章主要是記錄一下npm 全域性安裝以及按需引用的用法。 一、全域性引用 ①、先安裝iview&nbs

vue專案實現路由載入(路由懶載入)的3種方式

vue專案實現按需載入的3種方式 vue非同步元件 es提案的import() webpack的require,ensure() 1 . vue非同步元件技術 ==== 非同步載入 vue-router配置路由 , 使用vue

HTML優化載入

按需載入是前端效能優化中的一項重要措施,按需載入是如何定義的呢?顧名思義,指的是當用戶觸發了動作時才載入對應的功能。觸發的動作,是要看具體的業務場景而言,包括但不限於以下幾個情況:滑鼠點選、輸入文字、拉動滾動條,滑鼠移動、視窗大小更改等。載入的檔案,可以是JS、

關於優化H5專案-載入

開發十年,就只剩下這套架構體系了! >>>   

Vue.js中用webpack合併打包多個元件並實現載入

對於現在前端外掛的頻繁更新,所以多多少少要對元件化有點了解,下面這篇文章主要給大家介紹了在Vue.js中用webpack合併打包多個元件並實現按需載入的相關資料,需要的朋友可以參考下。   前言 隨著移動裝置的升級、網路速度的提高,使用者對於web應用的要求越來越高,web

Vue專案優化首屏載入速度

Vue專案部署上線後經常會發現首屏載入的速度特別慢:那麼有那寫能做的簡單優化呢 一、路由的懶載入 路由懶載入也就是 把不同路由對應的元件分割成不同的程式碼塊,然後當路由被訪問的時候才載入對應元件。 結合 Vue 的非同步元件和 Webpack 的程式碼分割功能,輕鬆實現路由元件的懶載入。&nbs

寫一個模組載入的babel外掛 解決專案全量引入第三方資源的問題

babel 簡單的理解他是一個語法轉換器  Babel 的三個主要處理步驟分別是: 解析(parse),轉換(transform),生成(generate) Babel 專案是作為一個 monorepo 來進行管理的,它由無數 npm 包組成 其中babel-core為其核心庫

vue如何實現程式碼打包分離(載入

在vue中使用import()來代替require.ensure()實現程式碼打包分離 一、require.ensure() 方法來實現程式碼打包分離 require.ensure() 是 webpack 特有的,已經被 import() 取代。 require.en

iOS 效能優化頁面載入速率

前言 之前蒐羅了網上很多關於iOS效能優化方面的資料 ,本人和我的小夥伴們也用了一些時間針對自己的App進行了App的啟動速率、頁面的載入速率和 頁面的幀率方面進行了優化,所以結合了理論和實踐,把我們在實踐中主要踩過的坑和需要注意的東西 ,總結了一下,希望可以

iview 引入vue專案報iview找不到解決方法

//import iView from ‘iview’; //import ‘iview/dist/styles/iview.css’; //Vue.use(iView); 接下來,在需要用的vue檔案下,直接引入需要的iview元件就可以了 import V

jQuery:實現圖片載入的方法,當要顯示內容的高度超過了頁面的高度,載入,根據滾動條的位置來判斷頁面顯示的內容

實現圖片按需載入的方法,當要顯示內容的高度超過了頁面的高度,按需載入,根據滾動條的位置來判斷頁面顯示的內容 這個類似於京東或淘寶頁面,根絕頁面的滾動,顯示下面的內容 如下圖所示,一開始並不是所有的圖片都顯示,當滾動條移動到頁面最下面的時候,再顯示下面的內容   解決思路:通過判斷滾動條是