デモコードは Vue3 + ts + Vite で書かれていますが、Vue2 に適用できる最適化手法も記載します。Vue3 または Vue2 のみに適用できる最適化の場合は、タイトルにその旨を記載します。 コードの最適化v-for でキーを使用するv-for を使用してレンダリングされた要素リストを更新する場合、デフォルトのインプレース再利用戦略が使用されます。リスト データが変更されると、キー値に基づいて値が変更されたかどうかが判断されます。変更された場合は、この項目が再レンダリングされ、変更されていない場合は以前の要素が再利用されます。 キーの使用に関する注意事項:
v-if/v-else-if/v-else でキーを使用するおそらく多くの人がこの点を無視するでしょう。 理由: デフォルトでは、Vue は DOM を可能な限り効率的に更新します。つまり、同じタイプの要素を切り替えるときに、古い要素を削除して同じ場所に新しい要素を追加するのではなく、既存の要素にパッチを適用します。同一ではない要素が同一であると識別されると、予期しない副作用が発生する可能性があります。 v-if が 1 つだけあり、v-else または v-if-else がない場合、キーを追加する必要はありません。 v-for のキーと比較すると、v-if/v-else-if/v-else のキーは比較的単純です。固定の文字列または配列を直接記述できます。 <遷移> <ボタン v-if="編集中" v-on:click="isEditing = false" > 保存 </ボタン> <ボタン v-else v-on:click="isEditing = true" > 編集 </ボタン> </トランジション> .v-enter-active、.v-leave-active { 遷移: すべて 1; } .v-enter、.v-leave-to { 不透明度: 0; 変換: translateY(30px); } .v-アクティブ状態を解除{ 位置: 絶対; } たとえば、上記のコードでは、ボタンにトランジション効果が追加されているにもかかわらず、キースイッチが追加されていないとトランジションをトリガーできないことがわかります。 この最適化手法は Vue2 に限定されています。Vue3 では v-for と v-if の優先順位が調整されています。 誰もが知っている 同じ要素に v-if と v-for を使用しないでください。 Vue 2.x スタイルガイドを参照してください その理由は、v-for は v-if よりも優先度が高いため、同じタグで使用すると、まずそれぞれのレンダリングがループされ、その後条件判定が行われるからです。 注: Vue3 では v-if は v-for よりも優先度が高いため、v-for と v-if を一緒に使用すると、その効果は Vue2 で v-if を発生させた場合と同様になります。 例えば、次のコードはVue2では推奨されておらず、Vueも対応する警告を発します。 <ul> <li v-for="users 内の user" v-if="user.active"> {{ユーザー名}} </li> </ul> v-ifを上位レベルに移動するか、計算プロパティを使用してデータを処理する必要があります。 <ul v-if="アクティブ"> <li v-for="users 内の user"> {{ユーザー名}} </li> </ul> ループに不要な親コンテナーを持たせたくない場合は、親要素として template を使用できます。Template は、ブラウザーによって DOM ノードとしてレンダリングされません。トラバーサル オブジェクト内の各項目の内容を判別してレンダリングされたデータを選択する場合は、computed を使用してトラバーサル オブジェクトをフィルターできます。 // js usersActive = computed(()=>users.filter(user => user.active)) とします。 // テンプレート <ul> <li v-for="usersActive 内のユーザー"> {{ユーザー名}} </li> </ul> v-ifとv-showの適切な選択v-if と v-show の違いは誰もがよく知っています。v-if は DOM の削除と追加を直接操作して要素の表示と非表示を制御します。v-show は DOM の表示 CSS を制御することで要素の表示と非表示を制御します。DOM の追加/削除操作のパフォーマンスは DOM の CSS プロパティを操作するパフォーマンスよりもはるかに低いため、要素を頻繁に表示/非表示にする必要がある場合は、v-show を使用してパフォーマンスを向上させます。 単純な計算プロパティの使用複雑な計算プロパティは、できるだけ多くの単純なプロパティに分割する必要があります。 各計算プロパティが依存関係の少ない非常に単純な式で構成されている場合、正しく動作することを確認するためのテストを記述するのが簡単になります。 読みやすくするために、簡略化された計算プロパティでは、再利用できない場合でも、各値にわかりやすい名前を付ける必要があります。これにより、他の開発者 (および将来のあなた) が関心のあるコードに集中し、何が起こっているかを把握しやすくなります。 「変化を受け入れる」方が良い Vue2スタイルガイドを参照してください Computed は誰もがよく知っているものです。Computed は、その表現で依存する反応データが変化すると再計算されます。計算プロパティにさらに複雑な式を記述すると、依存するリアクティブ データの数も任意に増加します。依存関係のいずれかが変更されると、式全体を再計算する必要があります。 価格 = 計算される(()=>{ 基本価格 = 製造コスト / (1 - 利益マージン) とします。 戻る ( 基本価格 - 基本価格 * (割引率 || 0) ) }) 製造コスト、利益マージン、または割引パーセントのいずれかが変更されると、全体の価格が再計算されます。 basePrice = computed(() => manufacturingCost / (1 - profitMargin)) とします。 割引率を計算します(() => 基本価格 * (割引率 || 0)) finalPrice = computed(() => basePrice - discount) とします。 discountPercent が変更された場合、discount と finalPrice のみが再計算されます。computed のキャッシュ機能により、basePrice は再計算されません。 機能コンポーネント (Vue2)これは Vue2 での最適化のみであり、3.x ではステートフル コンポーネントと関数型コンポーネント間のパフォーマンスの違いが大幅に削減され、ほとんどのユース ケースでは無視できるほどになっていることに注意してください。したがって、SFC で functional を使用する開発者の移行パスは、その属性を削除し、props のすべての参照を $props に、attrs のすべての参照を $attrs に名前変更することです。 最適化前 <テンプレート> <div class="cell"> <div v-if="値" クラス="on"></div> <セクション v-else クラス="オフ"></セクション> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ プロパティ: ['値'], } </スクリプト> 最適化後 <テンプレート機能> <div class="cell"> <div v-if="props.value" class="on"></div> <セクション v-else クラス="オフ"></セクション> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ プロパティ: ['値'], } </スクリプト>
コンポーネントを分割する何?あなたが書いた Vue ファイルに 1,000 行を超えるコードがありますか? 🤔 出典: https://slides.com/akryum/vueconfus-2019#/4/0/3 最適化前 <テンプレート> <div :style="{ 不透明度: 数値 / 300 }"> <div>{{ 重い() }} </div> </テンプレート> <スクリプト> エクスポートデフォルト{ プロパティ: ['数値'], メソッド: { 重い () { /* 重いタスク */ } } } </スクリプト> 最適化後 <テンプレート> <div :style="{ 不透明度: 数値 / 300 }"> <チャイルドコンプ/> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ プロパティ: ['数値'], コンポーネント: チャイルドコンプ: { メソッド: { 重い () { /* 重いタスク */ } }, レンダリング (h) { h('div', this.heavy()) を返します } } } } </スクリプト> Vue はコンポーネント レベルで更新されるため、各フレームでデータの変更によって親コンポーネントが再レンダリングされますが、ChildComp は内部に応答的なデータ変更がないため再レンダリングされません。最適化されたコンポーネントは、レンダリングごとに時間のかかるタスクを実行しません。 ローカル変数の使用最適化前 <テンプレート> <div :style="{ opacity: start / 300 }">{{ 結果 }}</div> </テンプレート> <スクリプト> '@/utils' から {heavy} をインポートします エクスポートデフォルト{ プロパティ: ['開始'], 計算: { 基数(){戻り値42}、 結果 () { 結果 = this.start とする (i = 0; i < 1000; i++ とします) { 結果 += 重い(this.base) } 結果を返す } } } </スクリプト> 最適化後 <テンプレート> <div :style="{ 不透明度: 開始 / 300 }"> {{ 結果 }} </テンプレート> <スクリプト> '@/utils' から {heavy} をインポートします エクスポートデフォルト{ プロパティ: ['開始'], 計算: { 基数(){戻り値42}、 結果 () { 定数ベース = this.base 結果 = this.start とする (i = 0; i < 1000; i++ とします) { 結果 += 重い(ベース) } 結果を返す } } } </スクリプト> ここでの主な違いは、最適化前後のコンポーネントの計算されたプロパティ結果の実装の違いです。最適化前のコンポーネントは計算プロセス中に this.base に何度もアクセスしますが、最適化後のコンポーネントは計算前にローカル変数 base を使用し、this.base をキャッシュしてから、直接 base にアクセスします。 では、なぜこの違いがパフォーマンスの違いを引き起こすのでしょうか? その理由は、this.base にアクセスするたびに、this.base はレスポンシブ オブジェクトであるため、そのゲッターがトリガーされ、依存関係コレクションに関連するロジック コードが実行されるためです。同様のロジックが頻繁に実行されると、例のように、数百のコンポーネントが数百サイクルで更新され、各コンポーネントの計算が再計算されるようにトリガーされ、依存関係の収集に関連するロジックが複数回実行されるため、パフォーマンスは当然低下します。 需要の観点から言えば、this.base は依存関係の収集を 1 回実行し、そのゲッター評価結果をローカル変数 base に返すだけで十分です。後で base に再度アクセスすると、ゲッターがトリガーされず、依存関係の収集ロジックが実行されないため、パフォーマンスが自然に向上します。 Vue.js のパフォーマンス最適化のヒント 9 つを公開 KeepAliveの使用レンダリングコストの高いコンポーネントを頻繁に切り替える必要がある場合は、キープアライブを使用してコンポーネントをキャッシュできます。キープアライブを使用すると、キープアライブでラップされたコンポーネントの vnode と DOM は、最初のレンダリング後にキャッシュされます。次回コンポーネントが再度レンダリングされるときに、対応する vnode と DOM がキャッシュから直接取得され、レンダリングされます。コンポーネントの初期化、レンダリング、パッチ適用などの一連のプロセスを再度実行する必要がないため、スクリプトの実行時間が短縮され、パフォーマンスが向上します。 注意: キープアライブを乱用すると、長時間にわたって大量のメモリを占有するため、アプリの動作が遅くなるだけです。 イベントの破壊コンポーネントが破棄されるときは、メモリ リークを防ぐために、コンポーネントに追加されたグローバル イベントとタイマーをクリアする必要があります。 関数 scrollFun(){ /* ... */ document.addEventListener("スクロール", scrollFun) マウント解除前に(()=>{ document.removeEventListener("スクロール", scrollFun) }) Vue2 では、$once を通じてこの効果を実現できます。もちろん、optionsAPI beforeDestroy でイベントを破棄することもできますが、後者では同じ機能を持つコードが分散されるため、前者の方法をお勧めします。 関数 scrollFun(){ /* ... */ document.addEventListener("スクロール", scrollFun) this.$once('hook:beforeDestroy', ()=>{ document.removeEventListener("スクロール", scrollFun) }) 関数 scrollFun(){ /* ... */ エクスポートデフォルト{ 作成された() { document.addEventListener("スクロール", scrollFun) }, beforeDestroy(){ document.removeEventListener("スクロール", scrollFun) } } 画像の読み込み画像の遅延読み込み: ページ上に多くの画像があり、すべての画像が1つの画面に表示されない状況に適しています。vue-lazyloadプラグインは、非常に便利な画像遅延読み込み命令v-lazyを提供します。 ただし、すべての画像が遅延読み込みに適しているわけではありません。たとえば、バナーやフォトアルバムの場合は、現在表示されている画像の前後の画像を優先的にダウンロードするために、画像のプリロード技術を使用することをお勧めします。 合理的なデータ処理アルゴリズムを使用するこれは、データ構造とアルゴリズムに関する知識を比較的テストするものです。たとえば、配列を多階層構造に変換する方法などです。 /** * 配列からツリー構造へ、時間計算量 O(n) * @param list 配列 * @param idKey 要素 ID キー * @param parIdKey 要素の親 ID キー * @param parId 最初のレベルのルート ノードの親 ID 値 * @return {[]} */ 関数 listToTree (リスト、idKey、parIdKey、parId) { map = {} とします。 結果 = [] とします。 len = list.length;とします。 // マップを構築する (i = 0; i < len; i++) の場合 { //配列内のデータをキーと値のペアの構造に変換します (ここでの配列と obj は相互参照します。これがアルゴリズム実装の重要なポイントです) map[リスト[i][idKey]] = リスト[i]; } //ツリー配列を構築 for(let i=0; i < len; i++) { itemParId = list[i][parIdKey]とします。 // トップレベルノード if(itemParId === parId) { 結果をプッシュします(リスト[i]); 続く; } // 孤立ノード、破棄(親ノードが存在しない) if(!map[itemParId]){ 続く; } // 現在のノードを親ノードの子に挿入します (参照データ型であるため、obj 内のノードが変更されると、結果内の対応するノードもそれに応じて変更されます) if(map[itemParId].children) { map[itemParId].children.push(リスト[i]); } それ以外 { map[itemParId].children = [list[i]]; } } 結果を返します。 } 他の上記の方法以外にも最適化テクニックはたくさんありますが、私のプロジェクトではあまり使用していません🤣
ファーストスクリーン/ボリュームの最適化私のプロジェクトでは、最初の画面の最適化のために主に次の最適化の方向性を持っています。
ボリュームの最適化
コード分割コード分割の役割は、パッケージ化された製品を esModule に依存する小さな製品に 1 つずつ分割することです。したがって、import() 関数を使用してファイルまたは依存関係をインポートすると、ファイルまたは依存関係は小さな製品として個別にパッケージ化されます。 ルートの遅延読み込みと非同期コンポーネントの両方でこの原則が使用されます。
UI ライブラリの場合、通常はオンデマンドのコンポーネント読み込みは使用せず、CDN 経由で導入して最適化することを好みます。 ネットワーク
これで、22 の Vue 最適化テクニック (プロジェクトに実用的) に関するこの記事は終了です。より関連性の高い Vue 最適化テクニックについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
>>: Win10 + Ubuntu20.04 LTS デュアルシステムブートインターフェースの美化
いくつかの概念行ボックス: インライン ボックスを囲むボックス。1 つ以上の行ボックスが積み重ねられ...
ダウンロード:ステップ 1: ウェブサイトを開きます (ダウンロードするには公式ウェブサイトにアクセ...
マシンに初めて MySQL をインストールします。オペレーティングシステムはwin7ですmysqlの...
テクノロジーの活用itext.jar: バイト ファイル入力ストリームを画像、PDF などに変換しま...
MySQL 5.7 以降のバージョンでは、冗長インデックス、重複インデックス、およびインデックスを使...
問題: MySQLテーブル内の自動増分IDのオーバーフローによりビジネスブロックが発生した背景: t...
mysqlslap共通パラメータの説明–auto-generate-sql システムはテスト用のSQ...
目次シナリオ解決してみる解決するシナリオ今日、コンポーネントの双方向データバインディングにv-mod...
私は全体のプロセスを 4 つのステップに分けます。 JDKをダウンロードしてインストールするTomc...
目次次のチェックv-model 構文シュガー.sync 修飾子$セット計算プロパティセット要約する次...
目次1. Dockerを使用する利点2. Dockerをインストールする1) LinuxにDocke...
1 MVCCとは何かMVCC の正式名称は、マルチバージョン同時実行制御です。データベースへの同時ア...
CentOS にはデフォルトで MariaDB がインストールされていますが、これは MySQL の...
目次序文1. wgetを使用して単一のファイルをダウンロードする2. wget -Oを使用してダウン...
CSS インポート方法 - インラインスタイルタグ属性を通じて、CSSのキーと値のペアがタグに直接書...