首頁 > web前端 > js教程 > 在vue中如何最佳化頁面(按需載入)

在vue中如何最佳化頁面(按需載入)

亚连
發布: 2018-06-21 16:22:44
原創
2184 人瀏覽過

本篇文章主要介紹了vue專案優化頁面的按需載入(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')))

下面的內容講解的更為詳細

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(&#39;script&#39;);
 //设置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(&#39;./baidumap.js&#39;) //baidumap.js放在我们当前目录下
 })
})
登入後複製

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

var sync = require(&#39;syncdemo.js&#39;)  //下面ensure里面也用到
mapBtn.click(function() {
 require.ensure([], function() {
  var baidumap = require(&#39;./baidumap.js&#39;) //baidumap.js放在我们当前目录下
  var sync = require(&#39;syncdemo.js&#39;) //这个不会独立出去,因为它已经加载到模块缓存中了
 })
})
登入後複製

也就是说,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。

  1. Abtn-work.js 是封装了 abtn按钮点击后,才执行的业务逻辑

  2. Bbtn-work.js 是封装了 bbtn按钮点击后,才执行的业务逻辑

  3. 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>
  <p id="aBtn">Abtn</p>
  <p id="bBtn">Bbtn</p>
 </body>
</html>
登入後複製

定义了两个buttom

然后看看 entry.js

var util_sync = require(&#39;./util-sync.js&#39;)
alert(util_sync.data)
document.getElementById("aBtn").onclick = function() {
 require.ensure([], function() {
  var awork = require(&#39;./workA-async.js&#39;)
  alert(awork.data)
  //异步里面再导入同步模块--实际是使用同步中的模块
  var util1 = require(&#39;./util-sync.js&#39;)
 })
}
document.getElementById("bBtn").onclick = function() {
 require.ensure([], function() {
  var bwork = require(&#39;./workB-async.js&#39;)
  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可以是页面的已经请求的数据得以保存,减少请求的次数,提高用户的体验程度。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

使用VS Code编辑器如何开发AngularJS 2应用程序

在Angular中有关管道操作符(|)用法

在Vue中有关SPA首屏加载优化(详细教程)

VS Code编辑器中关于修改选中文字或代码颜色操作

以上是在vue中如何最佳化頁面(按需載入)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板