ホームページ  >  記事  >  ウェブフロントエンド  >  vue でページを最適化する方法 (ロードオンデマンド)

vue でページを最適化する方法 (ロードオンデマンド)

亚连
亚连オリジナル
2018-06-21 16:22:442160ブラウズ

この記事では、Vue プロジェクトの最適化のためのページのオンデマンド読み込み (vue+webpack) を主に紹介します。編集者はこれが非常に優れていると考えたので、参考として共有します。エディターをフォローして見てみましょう

vue を使用して単一ページのアプリケーションを作成する場合、多くのルートが導入されることがあります。パッケージ化してビルドすると、JavaScript パッケージが非常に大きくなり、読み込みに影響します。異なるルートに対応するコンポーネントを異なるコード ブロックに分割し、ルートにアクセスするときに対応するコンポーネントをロードできれば、より効率的になります。これにより、最初の画面の表示速度が大幅に向上しますが、他のページの速度が低下する可能性があります。 Vue の非同期コンポーネントと webpack のコード分割機能を組み合わせると、ルーティング コンポーネントの遅延読み込みを簡単に実装できます。

写真の遅延読み込みと同様に、顧客がそれらの写真をまったく見ていないのに、ページを開くときにすべての写真を読み込む場合、リクエスト時間が大幅に増加し、ユーザー エクスペリエンスが低下します。遅延読み込みは、淘宝網や JD.com などのショッピング サイトなど、多くの Web サイトで使用されており、スクロールをすばやく下に引くと、画像が読み込まれていることがわかります。

同じことが単一ページのアプリケーションにも当てはまります。ユーザーはクリックしても他のページにジャンプすることはできず、メイン ページに留まるだけなので、他のページのすべてのリソースをロードする必要はありません。ユーザーがクリックすると、再度ロードされます。これにより、リクエスト時間が大幅に短縮され、ユーザー エクスペリエンスが向上します。

webpack は、オンデマンド読み込みを実装するための require.ensure() を提供します。以前はルートは import によって導入されていましたが、現在は const 定義によって導入されます。

オンデマンドページ読み込みなしの導入方法: import home from '../../common/home.vue'

オンデマンドページ読み込みありの導入方法: const home = r => ], () => r (require('../../common/home.vue')))

次の内容がより詳しく説明されています

誰もが聞いたことがあると思います。これを非同期読み込みと呼ぶ人もいますし、コードカットを行うと言う人もいます。では、これは何に使われるのでしょうか。実際、率直に言うと、js モジュールを .js ファイルに個別にエクスポートします。このモジュールを使用すると、webpack がスクリプト dom 要素を構築し、ブラウザーが js ファイルに対する非同期リクエストを開始します。

シナリオ分析:

たとえば、アプリケーションのホームページにはボタンがあり、クリックすると特定のマップが開きます。地図を開くには、Baidu Map の js を使用する必要があるため、Baidu Map の js をホームページにパッケージ化する必要があります。Baidu Map の js ファイルは 1 メートルとすると非常に大きいため、パッケージ化が発生します。私たちのホームページの js は非常に大きいため、ユーザーがホームページを開くのに時間がかかります。

何か良い解決策はありますか?

解決策 1

同じ JS をパッケージ化すると非常に大きいため、Baidu マップ JS を完全に分類し、ブラウザーの同時リクエスト JS ファイル処理を使用することができます。この場合、JS ファイルをロードするよりも時間がかかりません。 js ファイル 他にもたくさんあります。まあ、これもいい企画ですね。 baidumap.js の新しいエントリを構成するだけで、2 つの js ファイルにパッケージ化して HTML に挿入できます (baidumap.js が複数のエントリ ファイルによって参照されている場合、エントリ ファイルとして設定する必要はありません。また、直接CommonsChunkPlugin を使用してパブリック モジュールにエクスポートします) 私の以前の記事 webpack モジュールのパッケージ化を参照してください

より良い解決策はありますか?

解決策 2

もちろん、まだ 1 つあります。よく考えてみると、Baidu Map はユーザーがクリックした後にのみポップアップします。つまり、この機能はオプションです。次に、ユーザーがクリックしたときに Baidu Map の 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);
})

上記の数行のコードは、誰にとっても難しいものではありません。 Baidu マップをクリックすると、Baidu マップをロードできます。Baidu マップがロードされた後、Baidu マップのオブジェクトを使用して操作を実行できます。さて、この時点で webpack.ensure の原理は半分以上説明されました。いくつかの js モジュールを js ファイルに分割し、それらを使用する必要があるときにスクリプト オブジェクトを作成し、それを document.head オブジェクトに追加します。ブラウザは、この js ファイルを要求するリクエストを自動的に開始します。この js ファイルを取得した後に実行する必要があるビジネス ロジック操作を定義するコールバック。

それでは、webpack の API を使用して、そのようなことを実現します。クリックすると、Baidu マップ JS が非同期でロードされます。クリックして上記の JS をロードすると、Webpack を使用すると、手動で記述することなく、このような処理を簡単に行うことができます

mapBtn.click(function() {
 require.ensure([], function() {
  var baidumap = require(&#39;./baidumap.js&#39;) //baidumap.js放在我们当前目录下
 })
})

!もちろん、分析してみましょう。 require.ensure 関数はコード分離の境界線であり、コールバック内の require が分離したいものであること、つまり、baidumap.js を分離して baidumap.js を形成する require('./baidumap.js') であることを示します。 webpack パッケージの別の js ファイル。もちろん、

などのいくつかの同期要件を確実に記述することもできます。

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。