Vue ファースト スクリーン パフォーマンス最適化コンポーネントの知識ポイントの概要

Vue ファースト スクリーン パフォーマンス最適化コンポーネントの知識ポイントの概要

Vue ファースト スクリーン パフォーマンス最適化コンポーネント

Vue ファースト スクリーン パフォーマンス最適化コンポーネントを実装するだけです。 最新のブラウザは多くの新しいインターフェイスを提供しています。 IE との互換性を考慮せずに、これらのインターフェイスを使用すると、コードの作成とパフォーマンスの最適化にかかる作業負荷を大幅に軽減できます。 もちろん、IE を考慮するために、コンポーネントをカプセル化するときに IE のバックアップを提供することもできます。 この記事のファースト スクリーン パフォーマンス最適化コンポーネントは、主に IntersectionObserver と requestIdleCallback の 2 つのインターフェイスを使用します。

説明する

まず、最初の画面のシナリオを考えてみましょう。表示を主な目的とした最初の画面を作成する場合、通常は画像などのリソースがさらに読み込まれます。ユーザーが開いたときにすべてのリソースを読み込むのではなく、コンポーネントを読み込む前にユーザーが関連する位置までスクロールするようにしたい場合は、IntersectionObserver インターフェイスを選択できます。もちろん、onscroll イベントを使用してリスナーを実行することもできますが、パフォーマンスが低下する可能性があります。ロードする必要があるコンポーネントもありますが、ページの初期化時に同期的にロードされないようにする必要があります。この方法では、Promise や setTimeout などの非同期メソッドを使用できます。ただし、このコンポーネントのロードの優先度を下げたい場合は、requestIdleCallback インターフェイスを検討できます。関連するコードは、https://github.com/WindrunnerMax/webpack-simple-environment の vue--first-screen-optimization ブランチにあります。

インターセクションオブザーバー

IntersectionObserver インターフェースは、Intersection Observer API に属し、ターゲット要素とその祖先要素または最上位ドキュメント ビューポートとの交差状態を非同期的に監視する方法を提供します。祖先要素とビューポートはルートと呼ばれます。つまり、IntersectionObserver API は要素が表示されているかどうかを自動的に監視できます。表示の本質は、ターゲット要素とビューポートが交差領域を生成することであるため、この API は交差オブザーバーと呼ばれます。互換性 https://caniuse.com/?search=IntersectionObserver。

const io = new IntersectionObserver(コールバック、オプション);

// 観察を開始します io.observe(document.getElementById("example"));
// 監視を停止します io.unobserve(element);
// オブザーバーを閉じます io.disconnect();
  • パラメータ callback は新しい IntersectionObserver オブジェクトを作成します。ターゲット要素の表示部分が 1 つ以上のしきい値を超えたことを検出すると、指定されたコールバック関数が実行されます。
  • パラメーター オプション、IntersectionObserver コンストラクターの 2 番目のパラメーターは構成オブジェクトであり、次のプロパティを設定できます。
  • しきい値属性は、コールバック関数がいつトリガーされるかを決定します。これは、各メンバーがしきい値である配列です。デフォルト値は[0]で、交差率が0に達したときにコールバック関数がトリガーされることを意味します。ユーザーはこの配列をカスタマイズできます。たとえば、[0、0.25、0.5、0.75、1]は、対象要素が0%、25%、50%、75%、100%表示されたときにコールバック関数がトリガーされることを意味します。
  • root 属性は、ターゲット要素が配置されているコンテナ ノード、つまりルート要素を指定します。ターゲット要素はウィンドウとともにスクロールするだけでなく、iframe ウィンドウ内でのスクロールのようにコンテナ内でもスクロールします。この場合、root 属性を設定する必要があります。コンテナ要素は、ターゲット要素の祖先ノードである必要があることに注意してください。
  • rootMargin属性はルート要素の余白を定義します。これはrootBounds四角形のサイズを拡大または縮小するために使用され、それによってintersectionRectの交差領域のサイズに影響を与えます。これは10px 20px 30px 40pxなどのCSS定義方法を使用し、上、右、下、左の方向の値を表します。
  • IntersectionObserver.root プロパティは読み取り専用で、監視対象オブジェクトの特定の祖先要素を参照します。値が渡されないか、値が null の場合、デフォルトで最上位のドキュメント ウィンドウが使用されます。
  • IntersectionObserver.rootMargin プロパティは読み取り専用です。これは、交差を計算するときにルート境界ボックスに追加される長方形のオフセットです。これにより、計算のニーズに合わせてルート決定範囲を効果的に縮小または拡大できます。このプロパティによって返される値は、コンストラクターの呼び出し時に指定された値と異なる場合があるため、内部要件に合わせて値を変更する必要がある場合があります。すべてのオフセットは、ピクセル (px) またはパーセンテージ (%) で表すことができます。デフォルト値は 0px 0px 0px 0px です。
  • IntersectionObserver.thresholds プロパティは読み取り専用で、しきい値を昇順で含むリストです。リスト内の各しきい値は、リスニング オブジェクトの交差領域と境界領域の比率です。リスニング オブジェクトのいずれかのしきい値を超えると、通知 Notification が生成されます。コンストラクターに値が渡されない場合、デフォルト値は 0 です。
  • IntersectionObserver.disconnect() メソッドは、IntersectionObserver オブジェクトの監視を停止します。
  • IntersectionObserver.observe() メソッドにより、IntersectionObserver はターゲット要素の監視を開始します。
  • メソッド IntersectionObserver.takeRecords() は、監視対象のすべてのターゲットの IntersectionObserverEntry オブジェクトの配列を返します。
  • IntersectionObserver.unobserve() メソッドは、IntersectionObserver による特定のターゲット要素の監視を停止します。

さらに、コールバック関数が実行されると、次の情報を提供する IntersectionObserverEntry オブジェクト パラメータが渡されます。

  • time: 可視性が変化する時間。ミリ秒単位の高精度のタイムスタンプです。
  • target: 監視対象のターゲット要素は DOM ノード オブジェクトです。
  • rootBounds: getBoundingClientRect メソッドの戻り値である、ルート要素の矩形領域に関する情報。ルート要素が存在せず、ビューポートに対して直接スクロールする場合は null が返されます。
  • boundingClientRect: 対象要素の矩形領域に関する情報。
  • intersectionRect: ターゲット要素とビューポートまたはルート要素間の交差領域に関する情報。
  • intersectionRatio: ターゲット要素の可視比率、つまり、intersectionRect と boundingClientRect の比率。完全に可視の場合は 1、完全に不可視の場合は 0 以下になります。
{
  時間: 3893.92、
  ルート境界: クライアントRect {
    下: 920、
    高さ: 1024,
    左: 0,
    右: 1024、
    上: 0,
    幅: 920
  },
  境界クライアント矩形: クライアント矩形 {
     // ...
  },
  交差点矩形:クライアント矩形{
    // ...
  },
  交差比率: 0.54、
  ターゲット: 要素
}

リクエストアイドルコールバック

requestIdleCallback メソッドは、ブラウザのアイドル期間中に呼び出される関数を受け入れることができます。これにより、開発者は、アニメーションや入力応答などの遅延されたキー イベントに影響を与えることなく、メイン イベント ループでバックグラウンドおよび低優先度の作業を実行できます。関数は通常、先入れ先出しの順序で実行されます。コールバック関数で実行タイムアウトが指定されている場合は、タイムアウト前に関数を実行するために実行順序を乱すことが可能です。互換性 https://caniuse.com/?search=requestIdleCallback。

const ハンドル = window.requestIdleCallback(コールバック[, オプション]);
  • requestIdleCallback メソッドは ID を返します。この ID を window.cancelIdleCallback() メソッドに渡すと、コールバックを終了できます。
  • パラメータ callback は、イベント ループがアイドル状態のときに呼び出される関数への参照です。この関数は、IdleDeadline というパラメータを受け取ります。このパラメータによって、現在のアイドル時間と、タイムアウト前にコールバックが実行されたかどうかを取得できます。
  • パラメータ オプションはオプションであり、次のプロパティを持つオプションの構成パラメータが含まれます。
  • timeout: timeout が指定され、正の値を持ち、timeout ミリ秒が経過してもコールバックが呼び出されなかった場合、パフォーマンスに悪影響を与える可能性がある場合でも、コールバック タスクはイベント ループのキューに入れられます。

成し遂げる

実際、コンポーネントの作成では、主にこれら 2 つの主要な API の使用方法を理解する必要があります。まず、IntersectionObserver に注目しましょう。動的コンポーネント <component /> を使用する必要があるため、これに値を渡すときに、非同期コンポーネント読み込み () => import("component") 形式を使用する必要があります。リスニングする場合、読み込みが完了したらリスナーを破棄するか、視覚領域を離れたら破棄するかなどが考えられます。これは主に戦略的な問題です。ページが破棄されると、メモリ リークを防ぐために Intersection Observer を切断する必要があります。 requestIdleCallback の使用は比較的簡単です。Promise.resolve().then の非同期処理に似たコールバック関数を実行するだけです。

簡単な実装ロジックを以下に示します。通常、オブザーバーの使用方法は、まず div をプレースホルダーとして使用し、次にオブザーバーでプレースホルダーのコンテナーを監視します。コンテナーがビューポートにある場合、関連するコンポーネントを読み込みます。関連するコードは、https://github.com/WindrunnerMax/webpack-simple-environment の vue--first-screen-optimization ブランチにあります。インストールには yarn を使用してみてください。依存関係の問題を回避するために、yarn.lock ファイルを使用してバージョンをロックできます。 npm run dev で実行すると、Console でこれら 4 つの遅延ロード コンポーネントが作成される順序を確認できます。このうち、A のオブザーバーの遅延ロードは、ロード中のページがレンダリングされ、可視領域にあると判断されてからロードする必要があるため、最初の画面で直接見ることができます。D の遅延ロードは、D の外部コンテナーがビューに表示されるまでスクロール バーをスライドしてから表示する必要があります。つまり、D コンポーネントは一番下までスクロールしないと読み込まれません。また、$attrs と $listeners と同様に、component-params と component-events を通じて、遅延ロード コンポーネントに attrs と listeners を渡すこともできます。この時点で、遅延ロード コンポーネントが簡単に実装されました。

<!-- App.vue -->
<テンプレート>
    <div>
        <セクション>1</セクション>
        <セクション>
            <div>2</div>
            <遅延読み込み
                :lazy-component="例"
                タイプ="オブザーバー"
                :component-params="{ content: '例A' }"
                :コンポーネントイベント="{
                    'テストイベント': テストイベント、
                }"
            </遅延読み込み>
        </セクション>
        <セクション>
            <div>3</div>
            <遅延読み込み
                :lazy-component="例"
                タイプ="アイドル"
                :component-params="{ content: '例 B' }"
                :コンポーネントイベント="{
                    'テストイベント': テストイベント、
                }"
            </遅延読み込み>
        </セクション>
        <セクション>
            <div>4</div>
            <遅延読み込み
                :lazy-component="例"
                タイプ="lazy"
                :component-params="{ content: '例 C' }"
                :コンポーネントイベント="{
                    'テストイベント': テストイベント、
                }"
            </遅延読み込み>
        </セクション>
        <セクション>
            <div>5</div>
            <遅延読み込み
                :lazy-component="例"
                タイプ="オブザーバー"
                :component-params="{ content: '例 D' }"
                :コンポーネントイベント="{
                    'テストイベント': テストイベント、
                }"
            </遅延読み込み>
        </セクション>
    </div>
</テンプレート>

<script lang="ts">
「vue-property-decorator」から Component、Vue をインポートします。
「./components/lazy-load/lazy-load.vue」からLazyLoadをインポートします。
@成分({
    コンポーネント: { LazyLoad },
})
デフォルトクラスAppをエクスポートし、Vueを拡張します。
    保護された Example = () => import("./components/example/example.vue");

    保護されたテストイベント(コンテンツ: 文字列) {
        console.log(コンテンツ);
    }
}
</スクリプト>

<スタイル lang="scss">
@import "./common/styles.scss";
体 {
    パディング: 0;
    マージン: 0;
}
セクション {
    マージン: 20px 0;
    色: #fff;
    高さ: 500px;
    背景: $color-blue;
}
</スタイル>
コピー
<!-- 遅延ロード.vue -->
<テンプレート>
    <div>
        <コンポーネント
            :is="レンダリングコンポーネント"
            v-bind="コンポーネントパラメータ"
            v-on="コンポーネントイベント"
        </コンポーネント>
    </div>
</テンプレート>

<script lang="ts">
「vue-property-decorator」から { Component、Prop、Vue } をインポートします。
@成分
デフォルトのクラスLazyLoadをエクスポートし、Vueを拡張します。
    @Prop({ タイプ: 関数、必須: true })
    lazyComponent!: () => Vue;
    @Prop({ 型: 文字列、必須: true })
    タイプ: "オブザーバー" | "アイドル" | "レイジー";
    @Prop({ 型: Object、デフォルト: () => ({}) })
    コンポーネントパラメータ: Record<文字列、不明>;
    @Prop({ 型: Object、デフォルト: () => ({}) })
    コンポーネントイベント!: Record<文字列、不明>;

    保護されたオブザーバー: IntersectionObserver | null = null;
    保護された renderComponent: (() => Vue) | null = null;

    保護されたマウント() {
        これを初期化します。
    }

    プライベートinit() {
        if (this.type === "オブザーバー") {
            // `window.IntersectionObserver` が存在する
            if (window.IntersectionObserver) {
                this.observer = 新しい IntersectionObserver(entries => {
                    エントリ.forEach(item => {
                        // `intersectionRatio` は対象要素の可視比率で、`0` より大きい場合は可視であることを意味します // ロード後に `observe` を解放せず、不可視の場合は破棄するなど、実装戦略の問題もあります。 if (item.intersectionRatio > 0) {
                            コンポーネントをロードします。
                            // 読み込みが完了したら、`observe` のチェックを外します
                            this.observer?.unobserve(item.target);
                        }
                    });
                });
                this.observer.observe(this.$el.parentElement || this.$el);
            } それ以外 {
                // 直接ロードします this.loadComponent();
            }
        } そうでない場合 (this.type === "idle") {
            // `requestIdleCallback` が存在する
            // eslint 次の行を無効にする @typescript-eslint/ts コメントを禁止
            // @ts を無視
            if (window.requestIdleCallback) {
                リクエストIdleCallback(this.loadComponent, { タイムアウト: 3 });
            } それ以外 {
                // 直接ロードします this.loadComponent();
            }
        } そうでない場合 (this.type === "lazy") {
            // `Promise` が存在する
            if (window.Promise) {
                Promise.resolve().then(this.loadComponent);
            } それ以外 {
                // `setTimeout` を使用するようにダウングレードします
                タイムアウトを設定します(this.loadComponent);
            }
        } それ以外 {
            新しいエラーをスローします(`type: "observer" | "idle" | "lazy"`);
        }
    }

    プライベートloadComponent() {
        this.renderComponent を this.lazyComponent に追加します。
        this.$emit("ロードされました");
    }

    保護された破棄() {
        this.observer && this.observer.disconnect();
    }
}
</スクリプト>

毎日の質問

https://github.com/WindrunnerMax/EveryDay

参照する

https://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html

https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback

これで、Vue のファースト スクリーン パフォーマンス最適化コンポーネントのナレッジ ポイントのまとめに関する記事は終了です。Vue のファースト スクリーン パフォーマンス最適化コンポーネントの関連コンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vue プロジェクトの最初の画面のパフォーマンス最適化コンポーネントの実践ガイド
  • Vue.js パフォーマンス最適化 N 個のヒント (収集する価値あり)
  • Vue2.x プロジェクトのパフォーマンス最適化のためのコード最適化の実装
  • vueプロジェクトはGzip圧縮とパフォーマンス最適化操作を可能にします
  • Vue のパフォーマンスを最適化する方法
  • Vueコンポーネントのレンダリングを高速化し、パフォーマンスを最適化します

<<:  CSS3で背景画像にカラーマスクを追加する方法

>>:  Docker、プレーヤー機能を備えたCMSオンデマンドシステムを構築

推薦する

9999px に別れを告げる新しい CSS 画像置換テクニック (背景表示と画面外へのテキストの移動)

-9999 ピクセルの画像置換技術は、ここ 10 年近く人気があります。テキスト要素を画像に置き換え...

Javascriptの基本ループの詳しい説明

目次サイクルのために入室のためのその間しながら行うループから抜け出す要約するサイクルのためにループは...

React でカレンダー コンポーネントを構築するためのステップ バイ ステップ ガイド

目次事業背景テクノロジーの活用技術的な問題デザインのアイデア😱 困惑と苦痛に満ちた顔🙄考え始める🌲デ...

Win7 インストール MySQL 5.6 チュートリアル図

目次1. ダウンロード2. インストール3. my.ini ファイルを設定する(デフォルトのエンコー...

docker を使って sonarqube を構築する方法

目次1. Dockerをインストールする2. ソナーイメージをインストールする3. ソナーを使ってコ...

ネイティブ JS で音楽プレーヤーを実装するためのサンプル コード

この記事では主に、次のように共有されるネイティブ JS 音楽プレーヤーのサンプル コードを紹介します...

Tomcatを自動的に開始するサービスとして設定するにはどうすればいいでしょうか?最も簡単な方法

Tomcat が自動的にサービスを開始するように設定します。最近、問題が発生しました。サーバー上のプ...

Vue+express+Socketでチャット機能を実現

この記事では、チャット機能を実現するためのVue+express+Socketの具体的なコードを参考...

MySQL 入門 - 概念

1. それは何ですか? MySQL は最も人気のあるリレーショナル データベース管理システムです。W...

Linux でローカル コンピューターとリモート サーバーのポートが接続されているかどうかを確認する方法

以下のように表示されます。 1. ssh -v -p [ポート番号] [ユーザー名]@[IPアドレス...

このリファレンスとJavaScriptのカスタムプロパティの詳細な説明

目次1. このキーワード2. カスタム属性3. 包括的なケース1:タブの実装付録要約する1. このキ...

MySQL 5.7.13 ソースコードのコンパイル、インストール、および構成方法のグラフィックチュートリアル

インストール環境: CentOS7 64ビットMINI版公式ソースコードのコンパイルおよびインストー...

HTML でのテキストエリアの使用と一般的な問題およびケース分析

textarea タグはよく使われる HTML タグです。主に長いテキストを入力するときに改行するた...

vueプロジェクトは特定の領域に透かしを描くことを実現する

この記事では、Vueを使用して特定の領域に透かしを描く方法を紹介します。具体的な内容は次のとおりです...

javascript:void(0) の意味と使用例

voidキーワードの紹介まず、void キーワードは JavaScript で非常に重要なキーワード...