Google Chrome-Erweiterungen: Erweiterung der API zur Unterstützung der sofortigen Navigation

Tapuska
Dave Tapuska

Zusammenfassung: Die Extensions API wurde aktualisiert, um den Back-Forward-Cache zu unterstützen und Navigationen vorab zu laden. Weitere Informationen dazu findest du unten.

Bei Chrome wurde intensiv daran gearbeitet, die Navigation zu beschleunigen. Technologien zur Sofortnavigation wie Back-Forward-Cache (versendet auf dem Computer in Chrome 96) und Speculation Rules (versendet in Chrome 103) verbessern sowohl die Rückkehr als auch die Zukunft. In diesem Post gehen wir auf die Updates ein, die wir an den APIs für Browsererweiterungen vorgenommen haben, um diesen neuen Workflows gerecht zu werden.

Die verschiedenen Seitentypen

Vor Einführung des Back-Forward-Cache und Pre-Renderings hatte ein einzelner Tab nur eine aktive Seite. Das war schon immer sichtbar. Wenn ein Nutzer zur vorherigen Seite zurückkehrt, wird die aktive Seite gelöscht (Seite B) und die vorherige Seite im Verlauf wird vollständig rekonstruiert (Seite A). Erweiterungen mussten sich keine Gedanken darüber machen, in welchem Teil der Lebenszyklusseiten sie sich befanden, da es nur einen für einen Tab gab, den Status „Aktiv“/„Sichtbar“.

Entfernen der aktiven Seite
Die aktive Seite wurde entfernt.

Mit dem Back-Forward-Cache und Pre-Rendering gibt es keine 1:1-Beziehung zwischen Tabs und Seiten mehr. Auf jedem Tab werden jetzt mehrere Seiten und Seitenübergänge zwischen den Zuständen gespeichert, anstatt gelöscht und rekonstruiert zu werden.

Beispielsweise könnte eine Seite ihr Leben als vorab gerenderte (nicht sichtbare) Seite beginnen und in eine aktive (sichtbare) Seite übergehen, wenn der Nutzer auf einen Link klickt, und dann im Back-Forward-Cache gespeichert (nicht sichtbar), wenn der Nutzer zu einer anderen Seite navigiert, ohne dass die Seite zerstört wird. Später in diesem Artikel sehen wir uns die neuen Properties an, damit Erweiterungen den Status von Seiten besser nachvollziehen können.

Seitentypen
Seitentypen.

Ein Tab kann eine Reihe vorab gerenderter Seiten (nicht nur eine), eine einzelne aktive (sichtbare) Seite und eine Reihe von im Cache gespeicherten Seiten vor und zurück enthalten.

Was ändert sich für Entwickler von Erweiterungen?

FrameId == 0

In Chromium bezeichnen wir den obersten Frame als äußersten Frame.

Bei Erweiterungen, die davon ausgehen, dass die frameId des äußersten Frames 0 ist (eine frühere Best Practice), können Probleme auftreten. Da ein Tab jetzt mehrere äußerste Frames (vorgerenderte und im Cache gespeicherte Seiten) haben kann, ist die Annahme, dass es für einen Tab nur einen einzigen äußersten Frame gibt, falsch. frameId == 0 stellt weiterhin den äußersten Frame der aktiven Seite dar, die äußersten Frames anderer Seiten auf demselben Tab sind jedoch ungleich null. Zur Behebung dieses Problems wurde das neue Feld frameType hinzugefügt. Weitere Informationen finden Sie im Abschnitt Wie ermittle ich, ob ein Frame der äußerste Frame ist? in diesem Beitrag.

Lebenszyklus von Frames im Vergleich zu Dokumenten

Ein weiteres Konzept, das bei Erweiterungen problematisch ist, ist der Lebenszyklus des Frames. In einem Frame wird ein Dokument gehostet, das mit einer Commit-URL verknüpft ist. Das Dokument kann sich ändern (z. B. durch Navigieren), aber die frameId nicht. Daher ist es schwierig, ein Ereignis in einem bestimmten Dokument nur mit frameIds zuzuordnen. Wir führen das Konzept einer documentId ein, die eine eindeutige Kennzeichnung für jedes Dokument darstellt. Wird ein Frame aufgerufen und ein neues Dokument geöffnet, ändert sich die ID. Dieses Feld ist nützlich, um zu bestimmen, wann Seiten ihren Lebenszyklusstatus (zwischen Pre-Rendering/Aktiv/Cache) ändern, da er gleich bleibt.

Web-Navigationsereignisse

Ereignisse im chrome.webNavigation-Namespace können auf derselben Seite mehrmals ausgelöst werden, je nachdem, in welchem Lebenszyklus sie sich befinden. Weitere Informationen finden Sie in den Abschnitten Wie ermittle ich den Lebenszyklus einer Seite? und Wie stelle ich fest, wann eine Seite gewechselt wird?.

Woher weiß ich, in welchem Lebenszyklus sich die Seite befindet?

Der Typ DocumentLifecycle wurde einer Reihe von Erweiterungs-APIs hinzugefügt, für die frameId zuvor verfügbar war. Wenn der Typ DocumentLifecycle in einem Ereignis vorhanden ist (z. B. onCommitted), ist sein Wert der Status, in dem das Ereignis generiert wurde. Sie können jederzeit Informationen mit den Methoden WebNavigation getFrame() und getAllFrames() abfragen, aber es wird immer bevorzugt, den Wert aus dem Ereignis zu verwenden. Wenn Sie eine der beiden Methoden verwenden, beachten Sie, dass sich der Status des Frames zwischen dem Zeitpunkt der Generierung des Ereignisses und dem Zeitpunkt, an dem das Promise-Objekt mit beiden Methoden zurückgegeben wird, ändern kann.

Der DocumentLifecycle hat die folgenden Werte:

  • "prerender: Der Nutzer wird dem Nutzer zurzeit nicht angezeigt, wird aber in Vorbereitung sein.
  • "active": wird dem Nutzer angezeigt.
  • "cached": im Back-Forward-Cache gespeichert.
  • "pending_deletion": Das Dokument wird gelöscht.

Wie stelle ich fest, ob ein Frame der äußerste Frame ist?

Bisher wurde möglicherweise durch Erweiterungen geprüft, ob mit frameId == 0 ermittelt wurde, ob das Ereignis für den äußersten Frame gilt oder nicht. Bei mehreren Seiten in einem Tab haben wir jetzt mehrere äußerste Frames, sodass die Definition von frameId problematisch ist. Sie werden niemals Ereignisse zu einem im Back-Forward-Cache gespeicherten Frame erhalten. Bei vorab gerenderten Frames ist frameId jedoch für den äußersten Frame ungleich null. Die Verwendung von frameId == 0 als Signal, um festzustellen, ob es der äußerste Frame ist, ist falsch.

Um dies zu unterstützen, haben wir einen neuen Typ namens FrameType eingeführt. Damit lässt sich jetzt ganz einfach ermitteln, ob es sich tatsächlich um den äußersten Frame handelt. FrameType hat die folgenden Werte:

  • "outermost_frame": Wird in der Regel als oberster Frame bezeichnet. Beachten Sie, dass es davon ein Vielfaches gibt. Wenn Sie beispielsweise vorab gerenderte und im Cache gespeicherte Seiten haben, hat jede jeweils einen äußersten Frame, der als ihr höchster Frame bezeichnet werden könnte.
  • "fenced_frame": für die zukünftige Verwendung reserviert.
  • "sub_frame": Normalerweise ein iFrame.

Wir können DocumentLifecycle mit FrameType kombinieren und ermitteln, ob ein Frame der aktive äußere Frame ist. Beispiel: js tab.documentLifecycle == “active” && frameType == “outermost_frame”.

Wie behebe ich Probleme mit der Nutzungszeit von Frames?

Wie oben erwähnt, hostet ein Frame ein Dokument und der Frame kann zu einem neuen Dokument wechseln, aber frameId ändert sich nicht. Dies führt zu Problemen, wenn Sie ein Ereignis nur mit frameId empfangen. Wenn Sie die URL des Frames abrufen, kann sie sich vom Zeitpunkt des Auftretens des Ereignisses unterscheiden. Dies wird als Nutzungsproblem bezeichnet.

Um dieses Problem zu beheben, haben wir documentId (und parentDocumentId) eingeführt. Die Methode webNavigation.getFrame() macht jetzt frameId optional, wenn documentId angegeben wird. Das documentId ändert sich, wenn ein Frame aufgerufen wird.

Wie stelle ich fest, wann eine Seite umgestellt wird?

Es gibt explizite Signale, um zu bestimmen, wann eine Seite zwischen den Status wechselt.

Sehen wir uns die WebNavigation-Ereignisse an.

Bei der ersten Navigation auf einer Seite werden vier Ereignisse in der unten aufgeführten Reihenfolge angezeigt. Diese vier Ereignisse können mit dem Status DocumentLifecycle entweder "prerender" oder "active" auftreten.

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

Dies wird in der folgenden Abbildung veranschaulicht: documentId ändert sich zu "xyz", wenn die vorab gerenderte Seite zur aktiven Seite wird.

Die Dokument-ID ändert sich, wenn die vorab gerenderte Seite zur aktiven Seite wird.
Die documentId ändert sich, wenn die vorab gerenderte Seite zur aktiven Seite wird.

Wenn eine Seite aus dem Back-Forward-Cache oder Pre-Rendering in den aktiven Status wechselt, gibt es drei weitere Ereignisse, wobei DocumentLifecyle den Status "active" hat.

onBeforeNavigate
onCommitted
onCompleted

documentId bleibt unverändert. Dies wird oben dargestellt, wenn documentId == xyz aktiviert wird. Dieselben Navigationsereignisse werden ausgelöst, mit Ausnahme des Ereignisses onDOMContentLoaded, weil die Seite bereits geladen wurde.

Kommentare oder Fragen können Sie in der chromium-extensions-Gruppe stellen.