Zusammenfassung der Wissenspunkte der Komponente zur Leistungsoptimierung des ersten Vue-Bildschirms

Zusammenfassung der Wissenspunkte der Komponente zur Leistungsoptimierung des ersten Vue-Bildschirms

Komponente zur Leistungsoptimierung für den ersten Vue-Bildschirm

Implementieren Sie einfach eine Vue-Komponente zur Leistungsoptimierung für den ersten Bildschirm. Moderne Browser bieten viele neue Schnittstellen. Ohne die IE-Kompatibilität zu berücksichtigen, können diese Schnittstellen den Arbeitsaufwand beim Schreiben von Code und bei der Leistungsoptimierung erheblich reduzieren. Um den IE zu berücksichtigen, können wir natürlich auch eine Sicherung dafür bereitstellen, wenn wir Komponenten kapseln. Die in diesem Artikel beschriebene Komponente zur Leistungsoptimierung für den ersten Bildschirm verwendet hauptsächlich die beiden Schnittstellen IntersectionObserver und requestIdleCallback.

beschreiben

Betrachten wir zunächst das Szenario des ersten Bildschirms. Wenn ein erster Bildschirm hauptsächlich zur Anzeige erstellt wird, werden normalerweise mehr Ressourcen wie Bilder geladen. Wenn wir nicht alle Ressourcen laden möchten, wenn der Benutzer ihn öffnet, sondern möchten, dass der Benutzer vor dem Laden der Komponente zur entsprechenden Position scrollt, können wir die Schnittstelle IntersectionObserver wählen. Natürlich können wir auch das Onscroll-Ereignis verwenden, um einen Listener zu erstellen, aber die Leistung kann schlechter sein. Es gibt auch einige Komponenten, von denen wir hoffen, dass sie geladen werden müssen, aber wir möchten nicht, dass sie synchron geladen werden, wenn die Seite initialisiert wird. Auf diese Weise können wir asynchrone Methoden wie Promise und setTimeout verwenden. Wenn wir jedoch die Priorität des Ladens dieser Komponente verringern möchten, können wir die Schnittstelle requestIdleCallback in Betracht ziehen. Der relevante Code befindet sich im Zweig vue--first-screen-optimization von https://github.com/WindrunnerMax/webpack-simple-environment.

Kreuzungsbeobachter

Die Schnittstelle IntersectionObserver, die zur API Intersection Observer gehört, bietet eine Methode zum asynchronen Beobachten des Schnittpunktstatus eines Zielelements mit seinem Vorgängerelement oder dem Dokumentansichtsfenster der obersten Ebene. Das Vorgängerelement und das Ansichtsfenster werden als Wurzeln bezeichnet. Das heißt, die API IntersectionObserver kann automatisch beobachten, ob das Element sichtbar ist. Da das Wesen der Sichtbarkeit darin besteht, dass das Zielelement und das Ansichtsfenster einen Schnittpunktbereich erzeugen, wird diese API als Schnittpunktbeobachter bezeichnet. Kompatibilität https://caniuse.com/?search=IntersectionObserver.

const io = neuer IntersectionObserver(Rückruf, Option);

// Beginnen Sie mit der Beobachtung io.observe(document.getElementById("example"));
// Beobachtung beenden io.unobserve(element);
// Schließen Sie den Beobachter io.disconnect();
  • Der Parameter callback erstellt ein neues IntersectionObserver-Objekt. Wenn festgestellt wird, dass der sichtbare Teil des Zielelements einen oder mehrere Schwellenwerte überschreitet, wird die angegebene Callback-Funktion ausgeführt.
  • Parameteroption, der zweite Parameter des IntersectionObserver-Konstruktors ist ein Konfigurationsobjekt, das die folgenden Eigenschaften festlegen kann:
  • Das Schwellenwertattribut bestimmt, wann die Rückruffunktion ausgelöst wird. Es ist ein Array, in dem jedes Mitglied ein Schwellenwert ist. Der Standardwert ist [0], was bedeutet, dass die Rückruffunktion ausgelöst wird, wenn das Schnittverhältnis 0 erreicht. Benutzer können dieses Array anpassen. Beispielsweise bedeutet [0, 0,25, 0,5, 0,75, 1], dass die Rückruffunktion ausgelöst wird, wenn das Zielelement 0 %, 25 %, 50 %, 75 % und 100 % sichtbar ist.
  • Das Root-Attribut gibt den Containerknoten an, in dem sich das Zielelement befindet, also das Root-Element. Das Zielelement scrollt nicht nur mit dem Fenster, sondern auch innerhalb des Containers, z. B. beim Scrollen in einem Iframe-Fenster. In diesem Fall muss das Root-Attribut festgelegt werden. Beachten Sie, dass das Containerelement der Vorgängerknoten des Zielelements sein muss.
  • Das rootMargin-Attribut definiert den Rand des Stammelements, der zum Erweitern oder Verkleinern der Größe des rootBounds-Rechtecks ​​verwendet wird und dadurch die Größe des Schnittbereichs von intersectionRect beeinflusst. Es verwendet die CSS-Definitionsmethode, z. B. 10px 20px 30px 40px, die die Werte in der oberen, rechten, unteren und linken Richtung darstellt.
  • Die Eigenschaft IntersectionObserver.root ist schreibgeschützt und bezieht sich auf das spezifische Vorgängerelement des überwachten Objekts. Wenn kein Wert übergeben wird oder der Wert null ist, wird standardmäßig das Dokumentfenster der obersten Ebene verwendet.
  • Die Eigenschaft IntersectionObserver.rootMargin ist schreibgeschützt. Es handelt sich um den rechteckigen Versatz, der beim Berechnen der Schnittmenge zum Wurzelbegrenzungsrahmen hinzugefügt wird. Er kann den Wurzelbestimmungsbereich effektiv reduzieren oder erweitern, um den Berechnungsanforderungen gerecht zu werden. Der von dieser Eigenschaft zurückgegebene Wert kann sich von dem beim Aufruf des Konstruktors angegebenen Wert unterscheiden, sodass Sie den Wert möglicherweise ändern müssen, um den internen Anforderungen zu entsprechen. Alle Versätze können in Pixeln (px) oder Prozentsätzen (%) ausgedrückt werden. Der Standardwert ist 0px 0px 0px 0px.
  • Die Eigenschaft IntersectionObserver.thresholds ist schreibgeschützt und enthält eine Liste mit Schwellenwerten in aufsteigender Reihenfolge. Jeder Schwellenwert in der Liste ist das Verhältnis des Schnittbereichs zum Randbereich des abhörenden Objekts. Wenn ein beliebiger Schwellenwert des abhörenden Objekts überschritten wird, wird eine Benachrichtigung generiert. Wenn im Konstruktor kein Wert übergeben wird, ist der Standardwert 0.
  • Die Methode IntersectionObserver.disconnect() stoppt die Überwachung des IntersectionObserver-Objekts.
  • Die Methode IntersectionObserver.observe() bewirkt, dass IntersectionObserver mit der Überwachung eines Zielelements beginnt.
  • Die Methode IntersectionObserver.takeRecords() gibt ein Array von IntersectionObserverEntry-Objekten für alle beobachteten Ziele zurück.
  • Die Methode IntersectionObserver.unobserve() verhindert, dass IntersectionObserver ein bestimmtes Zielelement beobachtet.

Darüber hinaus wird bei der Ausführung der Callback-Funktion ein Objektparameter „IntersectionObserverEntry“ übergeben, der folgende Informationen bereitstellt.

  • Zeit: Der Zeitpunkt der Sichtbarkeitsänderung, ein hochpräziser Zeitstempel in Millisekunden.
  • Ziel: Das beobachtete Zielelement ist ein DOM-Knotenobjekt.
  • rootBounds: Informationen über den rechteckigen Bereich des Root-Elements, der der Rückgabewert der Methode getBoundingClientRect ist. Wenn kein Root-Element vorhanden ist und das Scrollen direkt relativ zum Ansichtsfenster erfolgt, wird null zurückgegeben.
  • boundingClientRect: Informationen über die rechteckige Fläche des Zielelements.
  • intersectionRect: Informationen zum Schnittpunktbereich zwischen dem Zielelement und dem Viewport bzw. Root-Element.
  • intersectionRatio: Das sichtbare Verhältnis des Zielelements, also das Verhältnis von intersectionRect zu boundingClientRect. Es ist 1, wenn es vollständig sichtbar ist, und kleiner oder gleich 0, wenn es vollständig unsichtbar ist.
{
  Zeit: 3893,92,
  rootBounds: ClientRect {
    unten: 920,
    Höhe: 1024,
    links: 0,
    rechts: 1024,
    oben: 0,
    Breite: 920
  },
  boundingClientRect: ClientRect {
     // ...
  },
  Kreuzungsrechteck:ClientRechteck {
    // ...
  },
  Schnittmenge: 0,54,
  Ziel: Element
}

AnfrageIdleCallback

Die Methode requestIdleCallback kann eine Funktion akzeptieren, die während der Leerlaufzeit des Browsers aufgerufen wird. Dadurch können Entwickler Hintergrundarbeiten und Arbeiten mit niedriger Priorität an der Hauptereignisschleife durchführen, ohne verzögerte Schlüsselereignisse wie Animationen und Eingabeantworten zu beeinträchtigen. Funktionen werden im Allgemeinen in der Reihenfolge „First-In-First-Out“ ausgeführt. Wenn die Rückruffunktion ein Ausführungstimeout angibt, ist es möglich, die Ausführungsreihenfolge zu unterbrechen, um die Funktion vor dem Timeout auszuführen. Kompatibilität https://caniuse.com/?search=requestIdleCallback.

const handle = window.requestIdleCallback(Rückruf[, Optionen]);
  • Die Methode requestIdleCallback gibt eine ID zurück, die an die Methode window.cancelIdleCallback() übergeben werden kann, um den Rückruf zu beenden.
  • Der Parameter callback ist ein Verweis auf eine Funktion, die aufgerufen wird, wenn die Ereignisschleife im Leerlauf ist. Die Funktion erhält einen Parameter namens IdleDeadline, der die aktuelle Leerlaufzeit ermitteln kann und angibt, ob der Callback vor dem Timeout ausgeführt wurde.
  • Der Parameter „Optionen“ ist optional und umfasst optionale Konfigurationsparameter mit den folgenden Eigenschaften:
  • Timeout: Wenn ein Timeout angegeben ist und einen positiven Wert hat und der Rückruf nach Ablauf der Timeout-Millisekunden nicht aufgerufen wurde, wird die Rückrufaufgabe in die Warteschlange der Ereignisschleife eingereiht, selbst wenn dies negative Auswirkungen auf die Leistung haben kann.

erreichen

Tatsächlich geht es beim Schreiben von Komponenten hauptsächlich darum, herauszufinden, wie diese beiden Haupt-APIs verwendet werden. Konzentrieren wir uns zunächst auf IntersectionObserver. Da wir die dynamische Komponente <component /> verwenden müssen, müssen wir beim Übergeben von Werten an sie das Formular asynchrones Laden der Komponente () => import("component") verwenden. Beim Abhören können Sie erwägen, den Listener nach Abschluss des Ladevorgangs oder nach Verlassen des Sichtbereichs usw. zu zerstören. Dies ist hauptsächlich eine strategische Angelegenheit. Wenn die Seite zerstört wird, muss der Intersection Observer getrennt werden, um Speicherlecks zu verhindern. Die Verwendung von requestIdleCallback ist relativ einfach. Sie müssen nur die Rückruffunktion ausführen, die der asynchronen Verarbeitung von Promise.resolve().then ähnelt.

Hier ist eine einfache Implementierungslogik. Normalerweise besteht die Verwendung des Observers darin, zuerst ein Div als Platzhalter zu verwenden und dann den Container des Platzhalters im Observer zu überwachen. Wenn sich der Container im Ansichtsfenster befindet, laden Sie die relevanten Komponenten. Der relevante Code befindet sich im Zweig vue--first-screen-optimization von https://github.com/WindrunnerMax/webpack-simple-environment. Bitte versuchen Sie, Yarn für die Installation zu verwenden. Sie können die Datei yarn.lock verwenden, um die Version zu sperren und Abhängigkeitsprobleme zu vermeiden. Nach dem Ausführen mit npm run dev können Sie die Reihenfolge sehen, in der diese vier Lazy-Loading-Komponenten in der Konsole erstellt werden. Unter ihnen muss der Lazy-Loading-Beobachter von A warten, bis die Ladeseite gerendert ist und vor dem Laden als im sichtbaren Bereich liegend beurteilt wird, sodass sie direkt auf dem ersten Bildschirm angezeigt werden kann. Das Lazy-Loading von D erfordert das Verschieben der Bildlaufleiste, bis der externe Container von D in der Ansicht erscheint, bevor er angezeigt wird. Mit anderen Worten wird die D-Komponente nicht geladen, wenn sie nicht nach unten gescrollt wird. Darüber hinaus können Attrs und Listener über Komponentenparameter und Komponentenereignisse an die Lazy-Loading-Komponente übergeben werden, was $attrs und $listeners ähnelt. An diesem Punkt wurde die Lazy-Loading-Komponente einfach implementiert.

<!-- App.vue -->
<Vorlage>
    <div>
        <Abschnitt>1</Abschnitt>
        <Abschnitt>
            <div>2</div>
            <Lazy-Load-Funktion
                :lazy-component="Beispiel"
                Typ="Beobachter"
                :component-params="{ Inhalt: 'Beispiel A' }"
                :Komponentenereignisse="{
                    'Testereignis': Testereignis,
                }"
            ></lazy-load>
        </Abschnitt>
        <Abschnitt>
            <div>3</div>
            <Lazy-Load-Funktion
                :lazy-component="Beispiel"
                Typ="Leerlauf"
                :component-params="{ content: 'Beispiel B' }"
                :Komponentenereignisse="{
                    'Testereignis': Testereignis,
                }"
            ></lazy-load>
        </Abschnitt>
        <Abschnitt>
            <div>4</div>
            <Lazy-Load-Funktion
                :lazy-component="Beispiel"
                Typ="faul"
                :component-params="{ Inhalt: 'Beispiel C' }"
                :Komponentenereignisse="{
                    'Testereignis': Testereignis,
                }"
            ></lazy-load>
        </Abschnitt>
        <Abschnitt>
            <div>5</div>
            <Lazy-Load-Funktion
                :lazy-component="Beispiel"
                Typ="Beobachter"
                :component-params="{ Inhalt: 'Beispiel D' }"
                :Komponentenereignisse="{
                    'Testereignis': Testereignis,
                }"
            ></lazy-load>
        </Abschnitt>
    </div>
</Vorlage>

<script lang="ts">
importiere { Komponente, Vue } von „vue-property-decorator“;
importiere LazyLoad aus "./components/lazy-load/lazy-load.vue";
@Komponente({
    Komponenten: { LazyLoad },
})
exportiere Standardklasse App erweitert Vue {
    geschütztes Beispiel = () => import("./components/example/example.vue");

    geschütztes Testereignis (Inhalt: Zeichenfolge) {
        konsole.log(Inhalt);
    }
}
</Skript>

<style lang="scss">
@import "./common/styles.scss";
Körper {
    Polsterung: 0;
    Rand: 0;
}
Abschnitt {
    Rand: 20px 0;
    Farbe: #fff;
    Höhe: 500px;
    Hintergrund: $color-blue;
}
</Stil>
Kopie
<!-- lazy-load.vue -->
<Vorlage>
    <div>
        <Komponente
            :ist="Renderkomponente"
            v-bind="KomponentenParams"
            v-on="Komponentenereignisse"
        ></Komponente>
    </div>
</Vorlage>

<script lang="ts">
importiere { Komponente, Prop, Vue } aus „vue-property-decorator“;
@Komponente
exportiere Standardklasse LazyLoad erweitert Vue {
    @Prop({ Typ: Funktion, erforderlich: true })
    lazyComponent!: () => Vue;
    @Prop({ Typ: String, erforderlich: true })
    Typ!: "Beobachter" | "untätig" | "faul";
    @Prop({ Typ: Objekt, Standard: () => ({}) })
    componentParams!: Datensatz<string, unbekannt>;
    @Prop({ Typ: Objekt, Standard: () => ({}) })
    componentEvents!: Datensatz<Zeichenfolge, unbekannt>;

    geschützter Beobachter: IntersectionObserver | null = null;
    geschützte Renderkomponente: (() => Vue) | null = null;

    geschützt gemountet() {
        dies.init();
    }

    private init() {
        wenn (dieser.Typ === "Beobachter") {
            // `window.IntersectionObserver` existiert
            wenn (Fenster.IntersectionObserver) {
                this.observer = neuer IntersectionObserver(Einträge => {
                    Einträge.fürJeden(Element => {
                        // `intersectionRatio` ist das sichtbare Verhältnis des Zielelements, größer als `0` bedeutet, dass es sichtbar ist // Auch hier gibt es Probleme mit der Implementierungsstrategie, wie z. B. `observe` nach dem Laden nicht freizugeben und es zu zerstören, wenn es unsichtbar ist usw. if (item.intersectionRatio > 0) {
                            dies.loadComponent();
                            // Nachdem der Ladevorgang abgeschlossen ist, deaktivieren Sie „observe“.
                            dieser.Beobachter?.unobserve(item.target);
                        }
                    });
                });
                dies.Beobachter.beobachten(dieses.$el.parentElement || dies.$el);
            } anders {
                // Direkt laden this.loadComponent();
            }
        } sonst wenn (dieser.Typ === "idle") {
            // `requestIdleCallback` existiert
            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
            // @ts-ignorieren
            wenn (window.requestIdleCallback) {
                requestIdleCallback(this.loadComponent, { timeout: 3 });
            } anders {
                // Direkt laden this.loadComponent();
            }
        } sonst wenn (dieser.Typ === "lazy") {
            // `Promise` existiert
            wenn (Fenster.Versprechen) {
                Versprechen.resolve().then(diese.loadComponent);
            } anders {
                // Downgrade zur Verwendung von „setTimeout“
                setTimeout(diese.loadComponent);
            }
        } anders {
            neuen Fehler werfen (`Typ: "Beobachter" | "Leerlauf" | "faul"`);
        }
    }

    private Ladekomponente() {
        diese.renderComponent = diese.lazyComponent;
        dies.$emit("geladen");
    }

    geschützt zerstört() {
        dieser.Beobachter und dieser.Beobachter.trennen();
    }
}
</Skript>

Frage des Tages

https://github.com/WindrunnerMax/EveryDay

siehe

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

Damit ist dieser Artikel über die Zusammenfassung der Wissenspunkte zur Leistungsoptimierungskomponente des ersten Bildschirms von Vue abgeschlossen. Weitere relevante Inhalte zur Leistungsoptimierungskomponente des ersten Bildschirms von Vue finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Ein praktischer Leitfaden zu den Komponenten zur Leistungsoptimierung beim ersten Bildschirm von Vue-Projekten
  • Vue.js Leistungsoptimierung N Tipps (es lohnt sich, sie zu sammeln)
  • Implementierung der Codeoptimierung zur Leistungsoptimierung von Vue2.x-Projekten
  • Das Vue-Projekt ermöglicht Gzip-Komprimierung und Leistungsoptimierungsvorgänge
  • Methoden zur Optimierung der Vue-Leistung
  • Beschleunigen Sie das Rendering von Vue-Komponenten und optimieren Sie deren Leistung

<<:  So fügen Sie einem Hintergrundbild in CSS3 eine Farbmaske hinzu

>>:  Docker erstellt CMS-On-Demand-System mit Player-Funktion

Artikel empfehlen

25 Tipps und Tricks zur Div+CSS-Programmierung

1. Das ul-Tag hat in Mozilla standardmäßig einen ...

Detaillierte Erläuterung des Mysql Self-Join-Abfragebeispiels

Dieser Artikel beschreibt die Mysql-Self-Join-Abf...

JavaScript zum Implementieren einer dynamischen Digitaluhr

In diesem Artikel finden Sie den spezifischen Cod...

Detaillierte Einführung zum MySQL-Cursor

Inhaltsverzeichnis 1. Was ist ein Cursor? 2. So v...

Zusammenfassung der Tipps zur Verwendung von coalesce() in MySQL

Vorwort Kürzlich habe ich zufällig MySQLs Coalesc...

Erfahrung im Webdesign

<br />Der Autor war früher ein Anfänger im W...

Häufige Ursachen und Lösungen für langsame MySQL-SQL-Anweisungen

1. Langsame Abfrage aufgrund fehlenden oder ungül...

Beispielcode eines CSS-responsiven Layoutsystems

Responsive Layoutsysteme sind in den heute gängig...

Über die Implementierung des JavaScript-Karussells

Heute ist ein weiterer sehr praktischer Fall. All...