乾物|最も完全なVueプロジェクトのパフォーマンス最適化実践ガイド

 

序文

双方向のデータバインディングと仮想DOMテクノロジーを通じて、Vueフレームワークは、フロントエンド開発におけるDOM操作の最も汚くて最も疲れる部分に対処するのに役立ちました。DOMの操作方法とその方法について考える必要はもうありません。 DOMを最も効率的に操作しますが、それでもVueプロジェクト内プロジェクトの最初の画面の最適化やWebpackコンパイル構成の最適化などの問題があるため、Vueプロジェクトのパフォーマンスの最適化に注意を払う必要があります。プロジェクトのパフォーマンスを向上させ、ユーザーエクスペリエンスを向上させます。この記事は、実際のプロジェクトの最適化の実践を通して著者によって要約されています。読者が自分のプロジェクトを最適化するのに役立つように、この記事を読んだ後、いくつかの啓発的な考えを持ってほしいと思います。この記事の内容は、次の3つの部分に分かれています。

  • Vueコードレベルの最適化。

  • webpack構成レベルの最適化。

  • 基本的なWebテクノロジーの最適化。

 

1.コードレベルでの最適化

 

1.1、v-ifとv-showは使用シナリオを区別します

v-ifが真の条件付きレンダリングである場合、条件付きブロック内のイベントリスナーとサブコンポーネントが適切に破棄され、切り替えプロセス中に再構築されるためです。また、怠惰です。最初のレンダリング時に条件がfalseの場合、何もしませんDo-条件ブロックは、条件が初めて真になるまでレンダリングされません。

 

v-showは、初期条件に関係なく、はるかに単純であり、要素は常にレンダリングされ、CSSの表示プロパティに基づいて単純に切り替えられます。

 

したがって、v-ifは、実行時に条件がほとんど変更されず、条件を頻繁に切り替える必要がないシナリオに適しています。v-showは、非常に頻繁な切り替え条件が必要なシナリオに適しています。

 

1.2。計算された使用シナリオと監視された使用シナリオの区別

計算済み:他の属性値に依存する計算済み属性であり、計算値がキャッシュされます。依存する属性値が変更された場合にのみ、次に計算値が取得されたときに計算値が再計算されます。

 

監視:これは、一部のデータの監視コールバックと同様に、「監視」の機能であり、監視データが変更されるたびに、後続の操作のためにコールバックが実行されます。

 

アプリケーションシナリオ:

  • 数値計算を実行して他のデータに依存する必要がある場合は、calculatedを使用する必要があります。これは、calculatedのキャッシュ機能を使用して、値を取得するたびに再計算を回避できるためです。

  • データが変更されたときに非同期または高価な操作を実行する必要がある場合は、watchを使用する必要があります。watchオプションを使用すると、非同期操作(APIへのアクセス)を実行できるため、操作を実行する頻度が制限されます。最終結果、中間状態を設定します。これらは、計算されたプロパティでは実行できないことです。

 

1.3、v-トラバーサルの場合、アイテムにキーを追加し、同時にv-ifを使用しないようにする必要があります

 

(1)V-トラバーサルの場合、アイテムにキーを追加する必要があります

リストデータをトラバースしてレンダリングするときは、Vue.jsの内部メカニズムがリストデータを正確に検出できるように、アイテムごとに一意のキー値を設定する必要があります。状態が更新されると、新しい状態値が古い状態値と比較され、差分の位置がより速くなります。

 

(2)v-トラバーサルの場合、v-ifを同時に使用しないでください

v-forはv-ifよりも優先度が高くなります。毎回配列全体をトラバースする必要がある場合、特に配列の一部をレンダリングする必要がある場合は、速度に影響します。次の場合は、計算されたプロパティに置き換える必要があります。必要。

 

推奨:

<ul> <li v-for="user in activeUsers" :key="user.id"> {
   
   { user.name }} </li></ul>computed: { activeUsers: function () { return this.users.filter(function (user) { return user.isActive }) }}
br

 

推奨されません:

<ul> <li v-for="user in users" v-if="user.isActive" :key="user.id"> {
   
   { user.name }} </li></ul>
br

 

1.4、ロングリストのパフォーマンスの最適化

VueはObject.definePropertyを介してデータをハイジャックし、ビューがデータの変更に応答することを認識します。ただし、コンポーネントが純粋なデータ表示であり、変更がない場合もあります。データをハイジャックするためにVueは必要ありません。データ表示、これは明らかにコンポーネントの初期化時間を短縮することができます。Vueがデータを乗っ取ることを禁止するにはどうすればよいですか?Object.freezeメソッドを使用してオブジェクトをフリーズできます。オブジェクトがフリーズすると、変更できなくなります。

export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); }};
br

 

1.5。イベントの破壊

Vueコンポーネントが破棄されると、他のインスタンスとの接続が自動的にクリーンアップされ、すべての命令とイベントリスナーのバインドが解除されますが、コンポーネント自体のイベントのみに限定されます。jsでaddEventListeneやその他のメソッドを使用する場合、自動的に破棄されることはありません。コンポーネントが破棄されたときに、次のようなメモリリークを回避するために、これらのイベントのリスナーを手動で削除する必要があります。

created() { addEventListener('click', this.click, false)},beforeDestroy() { removeEventListener('click', this.click, false)}
br

 

1.6、画像リソースの遅延読み込み

画像が多すぎるページの場合、ページの読み込み速度を上げるには、多くの場合、最初にページの表示領域にない画像を読み込み、次に表示領域にスクロールしてから読み込む必要があります。これにより、ページの読み込みパフォーマンスが大幅に向上し、ユーザーエクスペリエンスも向上します。プロジェクトではVueのvue-lazyloadプラグインを使用します。

 

(1)プラグインをインストールします

npm install vue-lazyload --save-dev
br

 

(2)エントリファイルman.jsで紹介して使用する

import VueLazyload from 'vue-lazyload'
br
 

次に、vueで直接使用します

Vue.use(VueLazyload)
br

 

またはカスタムオプションを追加します

Vue.use(VueLazyload, {preLoad: 1.3,error: 'dist/error.png',loading: 'dist/loading.gif',attempt: 1})br

(3)画像表示モードを遅延読み込み表示に変更するには、vueファイルでimgタグのsrc属性を直接v-lazyに変更します。

<img v-lazy="/static/img/1.png">
br

 

上記はvue-lazyloadプラグインの簡単な使用法です。プラグインのその他のパラメーターオプションを確認したい場合は、vue-lazyloadのgithubアドレスを確認できます。

 

1.7、遅延読み込みのルーティング

Vueはシングルページアプリケーションであり、多くのルートが導入される可能性があります。このように、webpcakでパッケージ化されたファイルは非常に大きくなります。ホームページに入ると、読み込まれるリソースが多すぎて、ページが空白で表示されます。ユーザーエクスペリエンスを助長しません。異なるルートに対応するコンポーネントを異なるコードブロックに分割し、ルートにアクセスしたときに対応するコンポーネントをロードできれば、より効率的になります。これにより、最初の画面表示の速度は大幅に向上しますが、他のページの速度は低下する可能性があります。

 

ルーティングの遅延読み込み:

const Foo = () => import('./Foo.vue')const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ]})
br

 

 

1.8。サードパーティのプラグインのオンデマンド導入

 

プロジェクトにサードパーティのプラグインを導入する必要があることがよくあります。プラグイン全体を直接導入すると、プロジェクトのサイズが大きくなりすぎます。babel-plugin-componentを使用して、必要なコンポーネントのみを導入できます。プロジェクトのサイズを縮小します。の目標。以下は、element-uiコンポーネントライブラリをプロジェクトに導入する例です。

 

(1)まず、babel-plugin-componentをインストールします。

npm install babel-plugin-component -D
br

 

(2)次に、.babelrcを次のように変更します。

{ "presets": [["es2015", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ]}
br

 

(3)main.jsにいくつかのコンポーネントを導入します。

import Vue from 'vue';import { Button, Select } from 'element-ui'; Vue.use(Button) Vue.use(Select)
br

 

 

1.9。無制限のリストパフォーマンスを最適化する

アプリケーションに非常に長いまたは無限のスクロールリストがある場合は、ウィンドウテクノロジーを使用してパフォーマンスを最適化する必要があります。領域のごく一部をレンダリングするだけで、コンポーネントの再レンダリングとdomノードの作成にかかる時間を短縮できます。次のオープンソースプロジェクトvue-virtual-scroll-listおよびvue-virtual-scrollerを参照して、この無限リストシーンを最適化できます。

 

1.10、サーバー側レンダリングSSRまたは事前レンダリング

サーバー側のレンダリングとは、クライアント側でタグのhtmlフラグメント全体をレンダリングするVueの作業がサーバー側で完了し、サーバー側で形成されたhtmlフラグメントがクライアント側に直接返されることを意味します。このプロセスはサーバーと呼ばれます。 -サイドレンダリング。

 

(1)サーバー側レンダリングの利点:

  • より良いSEO:SPAページのコンテンツはAjaxを介して取得され、検索エンジンのクロールツールはAjaxの非同期完了を待たずにページのコンテンツをクロールするため、SPAでページをクロールできません。ページが取得されます。 Ajax Contentを介して; SSRはサーバーからレンダリングされたページを直接返すため(データはすでにページに含まれています)、検索エンジンのクロールツールはレンダリングされたページをクロールできます。

  • コンテンツの到着時間の短縮(最初の画面での読み込みの高速化):SPAは、ページのレンダリングを開始する前に、すべてのVueコンパイル済みjsファイルがダウンロードされるのを待ちます。ファイルのダウンロードには一定の時間がかかるため、最初の画面のレンダリングには一定の時間が必要です。時間; SSRはサーバーによって直接レンダリングされ、ページはjsファイルのダウンロードとレンダリングを待たずに直接表示に戻されるため、SSRのコンテンツ到着時間は速くなります。

 

(2)サーバー側レンダリングのデメリット:

  • 開発条件に関するその他の制限:たとえば、サーバー側レンダリングは、beforeCreateとcreatedの2つのフック関数のみをサポートします。これにより、一部の外部拡張ライブラリは、サーバー側レンダリングアプリケーションで実行する前に特別な処理を必要とし、任意の場所にデプロイできます。静的ファイルサーバー上の完全に静的なシングルページアプリケーションSPAは異なります。サーバー側のレンダリングアプリケーションは、Node.jsサーバーの実行環境にある必要があります。

  • サーバー負荷の増加:Node.jsで完全なアプリケーションをレンダリングすると、静的ファイルのみを提供するサーバーよりも明らかに多くのCPUリソースが消費されます。したがって、トラフィックの多い環境で使用する場合は、対応するサーバー負荷を準備してください。賢明なキャッシング戦略。

 

プロジェクトのSEOと最初の画面のレンダリングがプロジェクトを評価するための重要な指標である場合、プロジェクトは、最高の初期読み込みパフォーマンスとSEOを達成するために、サーバー側のレンダリングが必要です。特定のVue SSRの実装については、作成者の別の記事「VueSSR踏みつけツアー」。Vueプロジェクトがいくつかのマーケティングページ(/、/ about、/ contactなど)のSEOを改善するだけでよい場合は、ビルド時に特定のルートの静的HTMLファイルを事前にレンダリングして単純に生成する必要があります。 。利点は、事前レンダリングの設定が簡単で、フロントエンドを完全に静的なサイトとして使用できることです。具体的には、prerender-spa-pluginを使用して、事前レンダリングを簡単に追加できます。

 

2.Webpackレベルでの最適化

 

2.1、Webpackは画像を圧縮します

vueプロジェクトでは、webpack.base.conf.jsのurl-loaderで制限サイズを設定して画像を処理できることを除いて、制限よりも小さい画像はbase64形式に変換され、残りは操作されません。したがって、一部の大きな画像リソースの場合、リソースをリクエストするときの読み込みが非常に遅くなります。image-webpack-loaderを使用して画像を圧縮できます。

 

(1)まず、image-webpack-loaderをインストールします。

npm install image-webpack-loader --save-dev
br

 

(2)次に、webpack.base.conf.jsで構成します。

{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use:[ { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { loader: 'image-webpack-loader', options: { bypassOnDebug: true, } } ]}
br

 

2.2、ES6の冗長コードをES5に減らします

Babelプラグインは、ES6コードをES5コードに変換するときに、次のES6コードなどのいくつかの補助関数を挿入します。

class HelloWebpack extends Component{...}
br

 

このコードを正常に実行できるES5コードに変換する場合、次の2つの補助機能が必要です。

babel-runtime/helpers/createClass // 用于实现 class 语法babel-runtime/helpers/inherits // 用于实现 extends 语法
br

 

デフォルトでは、Babelはこれらの依存ヘルパー関数コードを各出力ファイルに埋め込みます。複数のソースコードファイルがこれらのヘルパー関数に依存している場合、これらのヘルパー関数のコードが何度も表示されるため、コードが冗長になります。これらのヘルパー関数のコードが再表示されないようにするには、それらに依存するときにrequire( 'babel-runtime / helpers / createClass')を介してインポートし、1回だけ表示できるようにします。babel-plugin-transform-runtimeプラグインは、この機能を実現するために使用され、関連する補助関数をimportステートメントに置き換えて、babelによってコンパイルされたコードのファイルサイズを削減します。

 

(1)まず、babel-plugin-transform-runtimeをインストールします。

npm install babel-plugin-transform-runtime --save-dev
br

 

(2)次に、.babelrc構成ファイルを次のように変更します。

"plugins": [ "transform-runtime"]
br

 

プラグインの詳細を確認したい場合は、babel-plugin-transform-runtimeの詳細な紹介を確認してください。

 

 

2.3、公開コードを抽出する

各ページのサードパーティライブラリとパブリックモジュールがプロジェクトで抽出されない場合、プロジェクトには次の問題が発生します。

  • 同じリソースが繰り返し読み込まれ、ユーザートラフィックとサーバーコストが無駄になります。

  • 各ページにロードする必要のあるリソースが大きすぎるため、Webページの最初の画面のロードが遅くなり、ユーザーエクスペリエンスに影響します。

 

したがって、上記の問題を最適化するには、複数のページの共通コードを別々のファイルに分割する必要があります。Webpackには、複数のチャンクの共通部分を抽出するための専用プラグインであるCommonsChunkPluginが組み込まれています。プロジェクトでのCommonsChunkPluginの構成は次のとおりです。

// 所有在 package.json 里面依赖的包,都会被打包进 vendor.js 这个文件中。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: 'manifest', chunks: ['vendor']})
br

 

プラグインの詳細を確認したい場合は、CommonsChunkPluginの詳細な紹介をご覧ください。

 

 

2.4、テンプレートの事前コンパイル

JavaScriptでDOMテンプレートまたは文字列テンプレートを使用する場合、テンプレートは実行時にレンダリング関数にコンパイルされます。通常、このプロセスは十分に高速ですが、パフォーマンスに敏感なアプリケーションではこの使用を避けることをお勧めします。

 

プリコンパイルされたテンプレートを作成する最も簡単な方法は、単一ファイルコンポーネントを使用することです。関連するビルド設定は自動的にプリコンパイルを処理するため、ビルドされたコードには、元のテンプレート文字列ではなく、コンパイルされたレンダリング関数が既に含まれています。

 

webpackを使用していて、JavaScriptファイルとテンプレートファイルを分離したい場合は、vue-template-loaderを使用できます。これにより、ビルドプロセス中にテンプレートファイルをJavaScriptレンダリング関数に変換することもできます。

 

 

2.5、コンポーネントのCSSを抽出します

単一ファイルコンポーネントを使用する場合、コンポーネント内のCSSは、スタイルタグの形式でJavaScriptを介して動的に挿入されます。これには、実行時のオーバーヘッドがわずかにあります。サーバー側のレンダリングを使用する場合、これにより「スタイルなしコンテンツ(fouc)のちらつき」が発生します。すべてのコンポーネントのCSSを同じファイルに抽出すると、この問題を回避でき、CSSをより適切に圧縮してキャッシュすることもできます。

 

詳細については、このビルドツールのそれぞれのドキュメントを確認してください。

  • webpack + vue-loader(vue-cliのwebpackテンプレートは事前設定されています)

  • Browserify + vueify

  • ロールアップ+ロールアップ-プラグイン-vue

 

 

2.6、SourceMapを最適化する

プロジェクトがパッケージ化された後、開発中の複数のファイルコードを1つのファイルにパッケージ化し、圧縮して余分なスペースを削除し、babelでコンパイルした後、コンパイルされたコードは最終的にオンライン環境で使用されます。処理されたコードとソースコードの違いバグがある場合、圧縮されたコードの場所しか見つけることができず、開発環境でコードを見つけることができないため、開発が容易ではありません。問題が発生したため、sourceMapが表示されました。悪いデバッグコードの問題を解決することです。

 

SourceMapのオプションの値は次のとおりです(+記号が多いほど速度が速くなり、記号が多いほど速度が遅くなり、oは中速を意味します)

画像

推奨される開発環境:cheap-module-eval-source-map

実稼働環境の推奨事項:cheap-module-source-map

 

その理由は次のとおりです。

  • cheap:ソースコードの列情報は効果がないため、パッケージ化されたファイルには列関連の情報を含めたくありません。パッケージ化の前後で依存関係を確立できるのは行情報だけです。したがって、開発環境であろうと本番環境であろうと、パッケージ化の前後の列情報を無視するために、基本的なタイプの安価なものを追加したいと思います。

  • モジュール:開発環境であろうと正式な環境であろうと、バグのソースコードの特定の場所を見つけることを望んでいます。たとえば、Vueファイルがエラーを報告した場合、特定のVueファイルを見つけることを望んでいます。モジュール構成も必要です。

  • soure-map:source-mapは、パッケージ化されたモジュールごとに個別のsourcemapファイルを生成するため、source-map属性を追加する必要があります。

  • eval-source-map:マップファイルを生成しないため、evalパッケージコードの速度は非常に高速ですが、eval-source-mapをevalと組み合わせて使用​​できます。マップファイルはパッケージ化されたjsファイルに保存されます。 DataURLの形式で。eval-source-mapはファイルサイズが大きくなるため、正式な環境では使用しないでください。ただし、開発環境では、パッケージが高速であるため、試してみることができます。

 

 

2.7建設結果のアウトプット分析

Webpackによって出力されるコードは非常に読みやすく、ファイルが非常に大きいため、頭痛の種になります。出力結果をより簡単かつ直感的に分析するために、多くの視覚分析ツールがコミュニティに登場しました。これらのツールは、結果をより直感的にグラフィカルに表示するため、問題をすばやく理解できます。次に、Vueプロジェクトで使用した分析ツールwebpack-bundle-analyzerについて説明します。

 

プロジェクトでwebpack.prod.conf.jsを構成します。

if (config.build.bundleAnalyzerReport) { var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; webpackConfig.plugins.push(new BundleAnalyzerPlugin());}
br

 

$ npm run build --reportを実行した後、分析レポートは次のように生成されます。

画像

 

2.8、Vueプロジェクトのコンパイルの最適化

VueプロジェクトがWebpackでコンパイルされており、コーヒーを飲む必要がある場合は、プロジェクトのWebpack構成を最適化して、Webpack構築の効率を向上させる必要があります。VueプロジェクトのWebpack構築を最適化する方法の詳細については、著者による別の記事「Vue ProjectWebpack最適化プラクティス」を参照してください。

 

3.基本的なWebテクノロジーの最適化

 

3.1、gzip圧縮を開く

gzipはGNUzipの略語であり、UNIXシステムでのファイル圧縮に最初に使用されました。HTTPプロトコルのgzipエンコーディングは、Webアプリケーションのパフォーマンスを向上させるために使用されるテクノロジーです。Webサーバーとクライアント(ブラウザー)は、gzipを一緒にサポートする必要があります。現在の主流のブラウザ、Chrome、Firefox、IEなどはすべてこのプロトコルをサポートしています。Apache、Nginx、IISなどの一般的なサーバーもサポートしています。gzip圧縮効率は非常に高く、通常は70%の圧縮率に達します。つまり、Webページの圧縮率が30Kの場合、圧縮後は約9Kになります。 。

 

サーバーサイドエクスプレスを例として取り上げましょう。gzipを起動するのは非常に簡単です。関連する手順は次のとおりです。

インストール:

npm install compression --save
br

 

コードロジックを追加します。

var compression = require('compression');var app = express();app.use(compression())
br

 

サービスを再起動し、ネットワークパネルの応答ヘッダーを確認します。赤い円の中に次のフィールドが表示されている場合は、gzipが正常に開かれたことを意味します。

画像

 

 

3.2、ブラウザキャッシュ

ユーザーのページの読み込み速度を向上させるには、静的リソースをキャッシュする必要があります。サーバーへのリクエストを再開する必要があるかどうかに応じて、HTTPキャッシュルールは2つのカテゴリに分類されます(必須キャッシュ、キャッシングと比較して)。それを明確に理解していない場合は、HTTPキャッシングに関する著者の記事「HTTPキャッシングのメカニズムと原則の詳細な理解」を参照できます。これはここでは繰り返されません。

 

3.3CDNの使用

サーバーからCSS、js、画像、その他のファイルをダウンロードする場合、ブラウザはサーバーに接続する必要があり、ほとんどのサーバーの帯域幅は制限されています。制限を超えると、Webページは半日応答できなくなります。CDNは、さまざまなドメイン名を介してファイルをロードできるため、ファイルをダウンロードするための同時接続の数が大幅に増加し、CDNの可用性が向上し、ネットワーク遅延とパケット損失率が低下します。

 

3.4。ChromePerformanceを使用してパフォーマンスのボトルネックを見つける

Chromeのパフォーマンスパネルは、一定期間内のjs実行の詳細と時間を記録できます。Chromeデベロッパーツールを使用してページのパフォーマンスを分析する手順は次のとおりです。

  • Chromeデベロッパーツールを開き、パフォーマンスパネルに切り替えます

  • [記録]をクリックして記録を開始します

  • ページを更新するか、ノードを展開します

  • 記録を停止するには、[停止]をクリックします

画像

 

画像

終わり

サーバーからCSS、js、画像、その他のファイルをダウンロードする場合、ブラウザはサーバーに接続する必要があり、ほとんどのサーバーの帯域幅は制限されています。制限を超えると、Webページは半日応答できなくなります。CDNは、さまざまなドメイン名を介してファイルをロードできるため、ファイルをダウンロードするための同時接続の数が大幅に増加し、CDNの可用性が向上し、ネットワーク遅延とパケット損失率が低下します。

 

3.4。ChromePerformanceを使用してパフォーマンスのボトルネックを見つける

Chromeのパフォーマンスパネルは、一定期間内のjs実行の詳細と時間を記録できます。Chromeデベロッパーツールを使用してページのパフォーマンスを分析する手順は次のとおりです。

  • Chromeデベロッパーツールを開き、パフォーマンスパネルに切り替えます

  • [記録]をクリックして記録を開始します

  • ページを更新するか、ノードを展開します

  • 記録を停止するには、[停止]をクリックします

画像

 

画像

終わり

おすすめ

転載: blog.csdn.net/sqLeiQ/article/details/113110846