Chrome-extensies: uitbreiding van de API ter ondersteuning van directe navigatie

Dave Tapuska
Dave Tapuska

TL;DR: De Extensions API is bijgewerkt om back/forward cache te ondersteunen, waarbij navigatie vooraf wordt geladen. Zie hieronder voor meer informatie.

Chrome heeft hard gewerkt om de navigatie snel te maken. Instant Navigation-technologieën zoals Back/Forward Cache ( verzonden op desktop in Chrome 96) en Speculatieregels ( verzonden in Chrome 103) verbeteren zowel de terug- als de vooruit-ervaring. In dit bericht onderzoeken we de updates die we hebben aangebracht in de API's van browserextensies om aan deze nieuwe workflows tegemoet te komen.

Inzicht in de soorten pagina's

Vóór de introductie van Back/Forward Cache en prerendering had een afzonderlijk tabblad slechts één actieve pagina. Dit was altijd degene die zichtbaar was. Als een gebruiker terugkeert naar de vorige pagina, wordt de actieve pagina vernietigd (Pagina B) en wordt de vorige pagina in de geschiedenis volledig gereconstrueerd (Pagina A). Extensies hoefden zich geen zorgen te maken over welk deel van de levenscycluspagina's zich bevonden, omdat er maar één was voor een tabblad, de actieve/zichtbare status.

Verwijdering van de actieve pagina
Verwijdering van de actieve pagina.

Met Back/Forward Cache en pre-rendering is er niet langer een één-op-één-relatie tussen tabbladen en pagina's. Nu slaat elk tabblad feitelijk meerdere pagina's en pagina's op die tussen staten overgaan, in plaats van te worden vernietigd en gereconstrueerd.

Een pagina kan bijvoorbeeld zijn leven beginnen als een vooraf weergegeven (niet zichtbare) pagina, overgaan in een actieve (zichtbare) pagina wanneer de gebruiker op een link klikt, en vervolgens worden opgeslagen in de Back/Forward Cache (niet zichtbaar) wanneer de gebruiker navigeert naar een andere pagina, allemaal zonder dat de pagina ooit wordt vernietigd. Verderop in dit artikel zullen we kijken naar de nieuwe eigenschappen die worden weergegeven om extensies te helpen begrijpen in welke statuspagina's deze zich bevinden.

Soorten pagina's
Soorten pagina's.

Houd er rekening mee dat een tabblad een reeks vooraf weergegeven pagina's kan hebben (niet slechts één), een enkele actieve (zichtbare) pagina en een reeks pagina's in de cache Terug/Vooruit.

Wat verandert er voor extensie-ontwikkelaars?

FrameId == 0

In Chroom noemen we het bovenste/hoofdframe het buitenste frame.

Auteurs van extensies die ervan uitgaan dat de frameId van het buitenste frame 0 is (een eerdere best practice), kunnen problemen ondervinden. Omdat een tabblad nu meerdere buitenste frames kan hebben (vooraf weergegeven en in de cache opgeslagen pagina's), is de aanname dat er één buitenste frame voor een tabblad is onjuist. frameId == 0 blijft nog steeds het buitenste frame van de actieve pagina vertegenwoordigen, maar de buitenste frames van andere pagina's op hetzelfde tabblad zijn niet nul. Er is een nieuw veldframeType toegevoegd om dit probleem op te lossen. Zie het gedeelte “Hoe bepaal ik of een frame het buitenste frame is?” gedeelte van dit bericht.

Levenscyclus van frames versus documenten

Een ander concept dat problematisch is bij uitbreidingen is de levenscyclus van het frame. Een frame host een document (dat is gekoppeld aan een vastgelegde URL). Het document kan veranderen (bijvoorbeeld door te navigeren), maar de frameId niet, en dus is het moeilijk om te associëren dat er iets in een specifiek document is gebeurd met alleen frameIds . We introduceren een concept van een documentId , een unieke identificatie voor elk document. Als er door een frame wordt genavigeerd en een nieuw document wordt geopend, verandert de identificatie. Dit veld is handig om te bepalen wanneer pagina's hun levenscyclusstatus wijzigen (tussen prerender/actief/cache), omdat deze hetzelfde blijft.

Webnavigatiegebeurtenissen

Gebeurtenissen in de naamruimte chrome.webNavigation kunnen meerdere keren op dezelfde pagina worden geactiveerd, afhankelijk van de levenscyclus waarin deze zich bevindt. Zie 'Hoe weet ik in welke levenscyclus de pagina zich bevindt?' en “Hoe bepaal ik wanneer een pagina overgaat?” secties.

Hoe weet ik in welke levenscyclus de pagina zich bevindt?

Het DocumentLifecycle type is toegevoegd aan een aantal extensie-API's waar de frameId eerder beschikbaar was. Als het DocumentLifecycle type aanwezig is bij een gebeurtenis (zoals onCommitted ), is de waarde ervan de staat waarin de gebeurtenis is gegenereerd. U kunt altijd informatie opvragen via de methoden getFrame() en getAllFrames() van WebNavigation , maar het gebruik van de waarde uit de gebeurtenis heeft altijd de voorkeur. Als u een van beide methoden gebruikt, moet u er rekening mee houden dat de status van het frame kan veranderen tussen het moment waarop de gebeurtenis is gegenereerd en het moment waarop de beloften die door beide methoden worden geretourneerd, zijn opgelost.

De DocumentLifecycle heeft de volgende waarden:

  • "prerender " : Momenteel niet gepresenteerd aan de gebruiker, maar wordt voorbereid om mogelijk aan de gebruiker te worden weergegeven.
  • "active" : momenteel weergegeven voor de gebruiker.
  • "cached" : opgeslagen in de Back/Forward-cache.
  • "pending_deletion" : Het document wordt vernietigd.

Hoe bepaal ik of een frame het buitenste frame is?

Eerdere extensies hebben mogelijk gecontroleerd of frameId == 0 om te bepalen of de gebeurtenis die optreedt voor het buitenste frame geldt of niet. Met meerdere pagina's op een tabblad hebben we nu meerdere buitenste frames, dus de definitie van frameId is problematisch. U zult nooit gebeurtenissen ontvangen over een frame dat in de cache Terug/Vooruit is opgeslagen. Voor vooraf gerenderde frames is de frameId echter niet nul voor het buitenste frame. Het is dus onjuist om frameId == 0 te gebruiken als signaal om te bepalen of dit het buitenste frame is.

Om hierbij te helpen hebben we een nieuw type geïntroduceerd met de naam FrameType , zodat u nu eenvoudig kunt bepalen of het frame inderdaad het buitenste frame is. FrameType heeft de volgende waarden:

  • "outermost_frame" : Meestal het bovenste frame genoemd. Houd er rekening mee dat er veelvouden van zijn. Als u bijvoorbeeld vooraf gerenderde en in de cache opgeslagen pagina's heeft, heeft elke pagina een buitenste frame dat het bovenste frame zou kunnen worden genoemd.
  • "fenced_frame" : Gereserveerd voor toekomstig gebruik.
  • "sub_frame" : Meestal een iframe.

We kunnen DocumentLifecycle combineren met FrameType en bepalen of een frame het actieve buitenste frame is. Bijvoorbeeld: tab.documentLifecycle === “active” && frameType === “outermost_frame”

Hoe los ik gebruiksproblemen met frames op?

Zoals we hierboven al zeiden, herbergt een frame een document en het frame kan naar een nieuw document navigeren, maar de frameId zal niet veranderen. Dit levert problemen op wanneer u een gebeurtenis ontvangt met alleen een frameId . Als u de URL van het frame opzoekt, kan deze anders zijn dan toen de gebeurtenis plaatsvond. Dit wordt een gebruikstijdprobleem genoemd.

Om dit aan te pakken hebben we documentId (en parentDocumentId ) geïntroduceerd. De methode webNavigation.getFrame() maakt frameId nu optioneel als er een documentId wordt opgegeven. De documentId verandert telkens wanneer er door een frame wordt genavigeerd.

Hoe bepaal ik wanneer een pagina overgaat?

Er zijn expliciete signalen om te bepalen wanneer een pagina tussen staten overgaat.

Laten we eens kijken naar de WebNavigation gebeurtenissen .

Voor een allereerste navigatie op een pagina ziet u vier gebeurtenissen in de onderstaande volgorde. Houd er rekening mee dat deze vier gebeurtenissen kunnen optreden als de DocumentLifecycle status "prerender" of "active" is.

onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted

Dit wordt geïllustreerd in het onderstaande diagram, waarin wordt weergegeven dat de documentId verandert in "xyz" wanneer de vooraf weergegeven pagina de actieve pagina wordt.

De documentId verandert wanneer de vooraf weergegeven pagina de actieve pagina wordt
De documentId verandert wanneer de vooraf weergegeven pagina de actieve pagina wordt.

Wanneer een pagina overgaat van Back/Forward Cache of pre-render naar de actieve status, zullen er nog drie gebeurtenissen plaatsvinden (maar waarbij DocumentLifecyle "active" is).

onBeforeNavigate
onCommitted
onCompleted

De documentId blijft hetzelfde als in de oorspronkelijke gebeurtenissen. Dit wordt hierboven geïllustreerd wanneer documentId == xyz wordt geactiveerd. Houd er rekening mee dat dezelfde navigatiegebeurtenissen worden geactiveerd, behalve de gebeurtenis onDOMContentLoaded , omdat de pagina al is geladen.

Als u opmerkingen of vragen heeft, kunt u deze stellen in de chroomextensiesgroep .