Browserondersteuning
Moderne browsers zullen tegenwoordig soms pagina's onderbreken of volledig verwijderen als de systeembronnen beperkt zijn. In de toekomst willen browsers dit proactief doen, zodat ze minder stroom en geheugen verbruiken. De Page Lifecycle API biedt lifecycle hooks zodat uw pagina's deze browserinterventies veilig kunnen verwerken zonder de gebruikerservaring te beïnvloeden. Bekijk de API om te zien of u deze functies in uw applicatie zou moeten implementeren.
Achtergrond
De levenscyclus van applicaties is een belangrijke manier waarop moderne besturingssystemen bronnen beheren. Op Android-, iOS- en recente Windows-versies kunnen apps op elk moment door het besturingssysteem worden gestart en gestopt. Hierdoor kunnen deze platforms middelen stroomlijnen en opnieuw toewijzen waar de gebruiker het beste van profiteert.
Op internet bestaat er historisch gezien geen dergelijke levenscyclus, en apps kunnen voor onbepaalde tijd in leven worden gehouden. Als er grote aantallen webpagina's actief zijn, kunnen kritieke systeembronnen zoals geheugen, CPU, batterij en netwerk overbelast raken, wat leidt tot een slechte eindgebruikerservaring.
Hoewel het webplatform al lang gebeurtenissen kent die verband houden met levenscyclusstatussen (zoals load
, unload
en visibilitychange
), kunnen ontwikkelaars met deze gebeurtenissen alleen reageren op door de gebruiker geïnitieerde veranderingen in de levenscyclusstatus. Om het web betrouwbaar te laten werken op apparaten met een laag vermogen (en in het algemeen meer hulpbronnenbewust te zijn op alle platforms) hebben browsers een manier nodig om proactief systeembronnen terug te winnen en opnieuw toe te wijzen.
In feite nemen browsers tegenwoordig al actieve maatregelen om bronnen te besparen voor pagina's op achtergrondtabbladen, en veel browsers (vooral Chrome) zouden dit nog veel meer willen doen: om hun totale hulpbronnenvoetafdruk te verkleinen.
Het probleem is dat ontwikkelaars zich niet kunnen voorbereiden op dit soort door het systeem geïnitieerde interventies, of zelfs maar weten dat ze plaatsvinden. Dit betekent dat browsers conservatief moeten zijn, anders lopen ze het risico webpagina's kapot te maken.
De Page Lifecycle API probeert dit probleem op te lossen door:
- Het introduceren en standaardiseren van het concept van levenscyclusstatussen op internet.
- Het definiëren van nieuwe, door het systeem geïnitieerde statussen waarmee browsers de bronnen kunnen beperken die kunnen worden verbruikt door verborgen of inactieve tabbladen.
- Het creëren van nieuwe API's en gebeurtenissen waarmee webontwikkelaars kunnen reageren op overgangen van en naar deze nieuwe, door het systeem geïnitieerde toestanden.
Deze oplossing biedt de voorspelbaarheid die webontwikkelaars nodig hebben om applicaties te bouwen die bestand zijn tegen systeeminterventies, en stelt browsers in staat de systeembronnen agressiever te optimaliseren, wat uiteindelijk ten goede komt aan alle internetgebruikers.
In de rest van dit bericht worden de nieuwe functies voor de paginalevenscyclus geïntroduceerd en wordt onderzocht hoe deze zich verhouden tot alle bestaande webplatformstatussen en -gebeurtenissen. Het zal ook aanbevelingen en best practices geven voor het soort werk dat ontwikkelaars in elke staat zouden moeten (en niet zouden moeten) doen.
Overzicht van statussen en gebeurtenissen van de paginalevenscyclus
Alle statussen van de paginalevenscyclus zijn afzonderlijk en sluiten elkaar uit, wat betekent dat een pagina zich slechts in één status tegelijk kan bevinden. En de meeste wijzigingen in de levenscyclusstatus van een pagina zijn over het algemeen waarneembaar via DOM-gebeurtenissen (zie de aanbevelingen van ontwikkelaars voor elke status voor de uitzonderingen).
Misschien wel de gemakkelijkste manier om de statussen van de paginalevenscyclus uit te leggen – evenals de gebeurtenissen die overgangen daartussen signaleren – is met een diagram:
Staten
In de volgende tabel wordt elke status gedetailleerd uitgelegd. Het vermeldt ook de mogelijke toestanden die ervoor en erna kunnen optreden, evenals de gebeurtenissen die ontwikkelaars kunnen gebruiken om veranderingen waar te nemen.
Staat | Beschrijving |
---|---|
Actief | Een pagina is actief als deze zichtbaar is en invoerfocus heeft. Mogelijke eerdere toestanden: |
Passief | Een pagina bevindt zich in de passieve status als deze zichtbaar is en geen invoerfocus heeft. Mogelijke eerdere toestanden: Mogelijke volgende toestanden: |
Verborgen | Een pagina bevindt zich in de verborgen status als deze niet zichtbaar is (en niet is bevroren, weggegooid of beëindigd). Mogelijke eerdere toestanden: Mogelijke volgende toestanden: |
Bevroren | In de bevroren toestand schort de browser de uitvoering van bevriezingstaken in de taakwachtrijen van de pagina op totdat de pagina wordt gedeblokkeerd. Dit betekent dat zaken als JavaScript-timers en ophaal-callbacks niet worden uitgevoerd. Reeds uitgevoerde taken kunnen worden voltooid (het allerbelangrijkste: de terugroepactie Browsers bevriezen pagina's als een manier om het CPU-/batterij-/datagebruik te behouden; ze doen het ook als een manier om snellere terug-/vooruitnavigatie mogelijk te maken, waardoor de noodzaak voor het opnieuw laden van een volledige pagina wordt vermeden. Mogelijke eerdere toestanden: Mogelijke volgende toestanden: |
Beëindigd | Een pagina bevindt zich in de beëindigde status zodra deze door de browser wordt verwijderd en uit het geheugen wordt gewist. In deze status kunnen geen nieuwe taken worden gestart en lopende taken kunnen worden beëindigd als ze te lang duren. Mogelijke eerdere toestanden: Mogelijke volgende toestanden: |
Weggegooid | Een pagina bevindt zich in de weggegooide status wanneer deze door de browser wordt verwijderd om bronnen te besparen. In deze staat kunnen geen taken, gebeurtenis-callbacks of JavaScript van welke aard dan ook worden uitgevoerd, omdat het weggooien doorgaans plaatsvindt onder beperkte middelen, waardoor het starten van nieuwe processen onmogelijk is. In de verwijderde status is het tabblad zelf (inclusief de tabbladtitel en favicon) meestal zichtbaar voor de gebruiker, ook al is de pagina verdwenen. Mogelijke eerdere toestanden: Mogelijke volgende toestanden: |
Evenementen
Browsers verzenden veel gebeurtenissen, maar slechts een klein deel ervan signaleert een mogelijke verandering in de levenscyclusstatus van de pagina. De volgende tabel geeft een overzicht van alle gebeurtenissen die betrekking hebben op de levenscyclus en geeft aan van welke status ze kunnen overgaan.
Naam | Details |
---|---|
focus | Een DOM-element heeft focus gekregen. Opmerking: een Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
blur | Een DOM-element heeft de focus verloren. Opmerking: een Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
visibilitychange | De |
freeze * | De pagina is zojuist bevroren. Elke bevriesbare taak in de taakwachtrijen van de pagina wordt niet gestart. Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
resume * | De browser heeft een bevroren pagina hervat. Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
pageshow | Er wordt naar een sessiegeschiedenisitem gepasseerd. Dit kan een geheel nieuwe pagina zijn die is geladen of een pagina die uit de back/forward cache is gehaald. Als de pagina uit de back/forward cache is gehaald, is de Mogelijke eerdere toestanden: |
pagehide | Er wordt vanuit een sessiegeschiedenisitem gepasseerd. Als de gebruiker naar een andere pagina navigeert en de browser de huidige pagina aan de back/forward-cache kan toevoegen om deze later opnieuw te gebruiken, is de Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
beforeunload | Het venster, het document en de bijbehorende bronnen staan op het punt te worden verwijderd. Het document is nog steeds zichtbaar en de gebeurtenis kan op dit moment nog steeds worden geannuleerd. Belangrijk: de gebeurtenis Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
unload | De pagina wordt verwijderd. Waarschuwing: het gebruik van de Mogelijke eerdere toestanden: Mogelijke huidige toestanden: |
* Geeft een nieuwe gebeurtenis aan die is gedefinieerd door de Page Lifecycle API
Nieuwe functies toegevoegd in Chrome 68
Het vorige diagram toont twee toestanden die door het systeem worden geïnitieerd in plaats van door de gebruiker: bevroren en weggegooid . Zoals eerder vermeld, bevriezen browsers tegenwoordig al af en toe en verwijderen ze verborgen tabbladen (naar eigen goeddunken), maar ontwikkelaars kunnen niet weten wanneer dit gebeurt.
In Chrome 68 kunnen ontwikkelaars nu waarnemen wanneer een verborgen tabblad wordt bevroren en gedeblokkeerd door te luisteren naar de freeze
en resume
gebeurtenissen op document
.
document.addEventListener('freeze', (event) => {
// The page is now frozen.
});
document.addEventListener('resume', (event) => {
// The page has been unfrozen.
});
Vanaf Chrome 68 bevat het document
nu een wasDiscarded
eigenschap in desktop-Chrome ( Android-ondersteuning wordt in dit nummer bijgehouden ). Om te bepalen of een pagina is verwijderd terwijl deze zich op een verborgen tabblad bevond, kunt u de waarde van deze eigenschap controleren tijdens het laden van de pagina (opmerking: verwijderde pagina's moeten opnieuw worden geladen om ze opnieuw te kunnen gebruiken).
if (document.wasDiscarded) {
// Page was previously discarded by the browser while in a hidden tab.
}
Voor advies over wat belangrijk is om te doen bij het freeze
en resume
gebeurtenissen, en hoe u moet omgaan met en voorbereiden op het weggooien van pagina's, raadpleegt u de aanbevelingen voor ontwikkelaars voor elke status .
De volgende secties bieden een overzicht van hoe deze nieuwe functies passen in de bestaande statussen en gebeurtenissen van het webplatform.
Hoe u de status van de paginalevenscyclus in code kunt observeren
In de actieve , passieve en verborgen status is het mogelijk JavaScript-code uit te voeren die de huidige paginalevenscyclusstatus bepaalt op basis van bestaande webplatform-API's.
const getState = () => {
if (document.visibilityState === 'hidden') {
return 'hidden';
}
if (document.hasFocus()) {
return 'active';
}
return 'passive';
};
De bevroren en beëindigde toestanden kunnen daarentegen alleen worden gedetecteerd in hun respectievelijke gebeurtenislistener ( freeze
en pagehide
) wanneer de toestand verandert.
Hoe toestandsveranderingen te observeren
Voortbouwend op de eerder gedefinieerde functie getState()
kunt u alle wijzigingen in de status van de paginalevenscyclus waarnemen met de volgende code.
// Stores the initial state using the `getState()` function (defined above).
let state = getState();
// Accepts a next state and, if there's been a state change, logs the
// change to the console. It also updates the `state` value defined above.
const logStateChange = (nextState) => {
const prevState = state;
if (nextState !== prevState) {
console.log(`State change: ${prevState} >>> ${nextState}`);
state = nextState;
}
};
// Options used for all event listeners.
const opts = {capture: true};
// These lifecycle events can all use the same listener to observe state
// changes (they call the `getState()` function to determine the next state).
['pageshow', 'focus', 'blur', 'visibilitychange', 'resume'].forEach((type) => {
window.addEventListener(type, () => logStateChange(getState()), opts);
});
// The next two listeners, on the other hand, can determine the next
// state from the event itself.
window.addEventListener('freeze', () => {
// In the freeze event, the next state is always frozen.
logStateChange('frozen');
}, opts);
window.addEventListener('pagehide', (event) => {
// If the event's persisted property is `true` the page is about
// to enter the back/forward cache, which is also in the frozen state.
// If the event's persisted property is not `true` the page is
// about to be unloaded.
logStateChange(event.persisted ? 'frozen' : 'terminated');
}, opts);
Deze code doet drie dingen:
- Stelt de initiële status in met behulp van de
getState()
functie. - Definieert een functie die een volgende status accepteert en, als er een wijziging is, de statuswijzigingen in de console registreert.
- Voegt vastleggen van gebeurtenislisteners toe voor alle noodzakelijke levenscyclusgebeurtenissen, die op hun beurt
logStateChange()
aanroepen en de volgende status doorgeven.
Een ding om op te merken over de code is dat alle gebeurtenislisteners aan window
worden toegevoegd en dat ze allemaal {capture: true}
doorgeven. Hier zijn een paar redenen voor:
- Niet alle paginalevenscyclusgebeurtenissen hebben hetzelfde doel.
pagehide
enpageshow
worden opwindow
geactiveerd;visibilitychange
,freeze
enresume
worden opdocument
afgevuurd, enfocus
enblur
worden op hun respectieve DOM-elementen afgevuurd. - De meeste van deze gebeurtenissen borrelen niet, wat betekent dat het onmogelijk is om niet-vastleggende gebeurtenislisteners toe te voegen aan een gemeenschappelijk voorouderelement en ze allemaal te observeren.
- De capture-fase wordt uitgevoerd vóór de target- of bubble-fase, dus door daar luisteraars aan toe te voegen, zorg je ervoor dat ze worden uitgevoerd voordat andere code ze kan annuleren.
Aanbevelingen voor ontwikkelaars voor elke staat
Als ontwikkelaars is het belangrijk om zowel de status van de paginalevenscyclus te begrijpen als te weten hoe u deze in code kunt observeren, omdat het soort werk dat u wel (en niet zou moeten) doen, grotendeels afhangt van de staat waarin uw pagina zich bevindt.
Het heeft bijvoorbeeld duidelijk geen zin om een tijdelijke melding aan de gebruiker weer te geven als de pagina zich in de verborgen status bevindt. Hoewel dit voorbeeld vrij duidelijk is, zijn er nog andere aanbevelingen die niet zo voor de hand liggend zijn en die de moeite waard zijn om op te sommen.
Staat | Aanbevelingen van ontwikkelaars |
---|---|
Active | De actieve status is het meest kritieke moment voor de gebruiker en dus het belangrijkste moment waarop uw pagina reageert op gebruikersinvoer . Alle niet-UI-werkzaamheden die de hoofdthread kunnen blokkeren, moeten worden gedeprioriteerd naar inactieve perioden of worden overgedragen aan een webwerker . |
Passive | In de passieve toestand heeft de gebruiker geen interactie met de pagina, maar kan hij deze nog steeds zien. Dit betekent dat UI-updates en animaties nog steeds soepel moeten verlopen, maar dat de timing van deze updates minder kritisch is. Wanneer de pagina verandert van active naar passief , is het een goed moment om de niet-opgeslagen applicatiestatus te behouden. |
Wanneer de pagina verandert van passief naar verborgen , is het mogelijk dat de gebruiker er pas weer mee communiceert nadat deze opnieuw is geladen. De overgang naar verborgen is ook vaak de laatste statusverandering die betrouwbaar waarneembaar is door ontwikkelaars (dit geldt vooral op mobiele apparaten, omdat gebruikers tabbladen of de browser-app zelf kunnen sluiten, en de Dit betekent dat u de verborgen status moet beschouwen als het waarschijnlijke einde van de sessie van de gebruiker. Met andere woorden: bewaar de niet-opgeslagen applicatiestatus en stuur eventuele niet-verzonden analysegegevens. U moet ook stoppen met het maken van UI-updates (aangezien deze niet door de gebruiker worden gezien) en u moet alle taken stoppen die een gebruiker niet op de achtergrond wil uitvoeren. | |
Frozen | In de bevroren toestand worden bevriezingstaken in de taakwachtrijen opgeschort totdat de pagina wordt gedeblokkeerd - wat misschien nooit zal gebeuren (bijvoorbeeld als de pagina wordt weggegooid). Dit betekent dat wanneer de pagina verandert van verborgen naar bevroren, het van essentieel belang is dat u timers stopt of verbindingen verbreekt die, indien bevroren, van invloed kunnen zijn op andere geopende tabbladen in dezelfde oorsprong, of op het vermogen van de browser om de pagina op de achtergrond te plaatsen. voorwaartse cache . Het is vooral belangrijk dat u:
Je moet ook elke dynamische weergavestatus (bijvoorbeeld schuifpositie in een oneindige lijstweergave) behouden in Als de pagina van bevroren terug naar verborgen gaat, kunt u alle gesloten verbindingen opnieuw openen of de polling opnieuw starten die u hebt gestopt toen de pagina aanvankelijk bevroren was. |
Terminated | Normaal gesproken hoeft u geen actie te ondernemen wanneer een pagina overgaat naar de beëindigde status. Omdat pagina's die worden verwijderd als resultaat van een gebruikersactie, altijd de verborgen status doorlopen voordat ze in de beëindigde status terechtkomen, is de verborgen status de plek waar logica voor het beëindigen van de sessie (bijvoorbeeld het aanhouden van de applicatiestatus en rapportage aan analyses) moet worden uitgevoerd. Ook (zoals vermeld in de aanbevelingen voor de verborgen status ) is het erg belangrijk voor ontwikkelaars om te beseffen dat de overgang naar de beëindigde status in veel gevallen niet op betrouwbare wijze kan worden gedetecteerd (vooral op mobiel), dus ontwikkelaars die afhankelijk zijn van beëindigingsgebeurtenissen (bijv. |
Discarded | De weggegooide status is niet waarneembaar voor ontwikkelaars op het moment dat een pagina wordt weggegooid. Dit komt omdat pagina's doorgaans worden weggegooid onder beperkte middelen, en het deblokkeren van een pagina alleen maar om het script uit te voeren als reactie op een wegwerpgebeurtenis in de meeste gevallen eenvoudigweg niet mogelijk is. Als gevolg hiervan moet u zich voorbereiden op de mogelijkheid van weggooien bij de wijziging van verborgen naar bevroren , en vervolgens kunt u reageren op het herstel van een weggegooide pagina tijdens het laden van de pagina door |
Nogmaals, aangezien de betrouwbaarheid en volgorde van levenscyclusgebeurtenissen niet consistent in alle browsers zijn geïmplementeerd, is de eenvoudigste manier om het advies in de tabel op te volgen het gebruik van PageLifecycle.js .
Verouderde levenscyclus-API's moeten worden vermeden
De volgende gebeurtenissen moeten waar mogelijk worden vermeden.
Het ontlaadevenement
Veel ontwikkelaars beschouwen de unload
-gebeurtenis als een gegarandeerde callback en gebruiken deze als een signaal aan het einde van de sessie om de status op te slaan en analysegegevens te verzenden, maar dit doen is uiterst onbetrouwbaar , vooral op mobiel! De unload
-gebeurtenis wordt in veel typische unload-situaties niet geactiveerd, inclusief het sluiten van een tabblad via de tabbladwisselaar op mobiel of het sluiten van de browserapp via de appwisselaar.
Om deze reden is het altijd beter om te vertrouwen op de visibilitychange
om te bepalen wanneer een sessie eindigt, en de verborgen status te beschouwen als de laatste betrouwbare tijd om app- en gebruikersgegevens op te slaan .
Bovendien kan alleen al de aanwezigheid van een geregistreerde unload
-gebeurtenishandler (via onunload
of addEventListener()
) voorkomen dat browsers pagina's in de back/forward-cache kunnen plaatsen voor sneller terug- en vooruitladen.
In alle moderne browsers wordt aanbevolen om altijd de pagehide
-gebeurtenis te gebruiken om mogelijke verwijderingen van pagina's te detecteren (ook wel de beëindigde status genoemd) in plaats van de unload
-gebeurtenis. Als u Internet Explorer versie 10 en lager moet ondersteunen, moet u de pagehide
gebeurtenis detecteren en alleen unload
gebruiken als de browser pagehide
niet ondersteunt:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
window.addEventListener(terminationEvent, (event) => {
// Note: if the browser is able to cache the page, `event.persisted`
// is `true`, and the state is frozen rather than terminated.
});
De beforeunload-gebeurtenis
De gebeurtenis beforeunload
heeft een soortgelijk probleem als de gebeurtenis unload
, in die zin dat historisch gezien de aanwezigheid van een gebeurtenis beforeunload
ervoor kon zorgen dat pagina's niet in aanmerking komen voor back/forward cache . Moderne browsers hebben deze beperking niet. Hoewel sommige browsers uit voorzorg de gebeurtenis beforeunload
niet activeren wanneer ze proberen een pagina in de back/forward cache te plaatsen, wat betekent dat de gebeurtenis niet betrouwbaar is als signaal voor het einde van de sessie. Bovendien vereisen sommige browsers (waaronder Chrome ) een gebruikersinteractie op de pagina voordat de beforeunload
gebeurtenis kan worden geactiveerd, wat de betrouwbaarheid ervan verder beïnvloedt.
Een verschil tussen beforeunload
en unload
is dat er legitiem gebruik is van beforeunload
. Als u de gebruiker bijvoorbeeld wilt waarschuwen dat er niet-opgeslagen wijzigingen zijn, gaan deze verloren als hij doorgaat met het verwijderen van de pagina.
Omdat er geldige redenen zijn om beforeunload
te gebruiken, is het raadzaam beforeunload
listeners alleen toe te voegen wanneer een gebruiker niet-opgeslagen wijzigingen heeft en deze vervolgens onmiddellijk te verwijderen nadat ze zijn opgeslagen.
Met andere woorden, doe dit niet (aangezien het onvoorwaardelijk een beforeunload
listener toevoegt):
addEventListener('beforeunload', (event) => {
// A function that returns `true` if the page has unsaved changes.
if (pageHasUnsavedChanges()) {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
}
});
Doe dit in plaats daarvan (aangezien het alleen de beforeunload
-listener toevoegt wanneer dit nodig is, en verwijdert wanneer dit niet het geval is):
const beforeUnloadListener = (event) => {
event.preventDefault();
// Legacy support for older browsers.
return (event.returnValue = true);
};
// A function that invokes a callback when the page has unsaved changes.
onPageHasUnsavedChanges(() => {
addEventListener('beforeunload', beforeUnloadListener);
});
// A function that invokes a callback when the page's unsaved changes are resolved.
onAllChangesSaved(() => {
removeEventListener('beforeunload', beforeUnloadListener);
});
Veelgestelde vragen
Waarom is er geen status 'laden'?
De Page Lifecycle API definieert statussen als discreet en wederzijds uitsluitend. Omdat een pagina kan worden geladen in de actieve, passieve of verborgen status, en omdat deze van status kan veranderen (of zelfs kan worden beëindigd) voordat het laden is voltooid, is een afzonderlijke laadstatus binnen dit paradigma niet zinvol.
Mijn pagina doet belangrijk werk als deze verborgen is. Hoe kan ik voorkomen dat deze wordt bevroren of verwijderd?
Er zijn veel legitieme redenen waarom webpagina's niet mogen worden bevroren terwijl ze in de verborgen staat worden uitgevoerd. Het meest voor de hand liggende voorbeeld is een app die muziek afspeelt.
Er zijn ook situaties waarin het voor Chrome riskant zou zijn om een pagina te verwijderen, bijvoorbeeld als deze een formulier bevat met niet-ingediende gebruikersinvoer, of als er een beforeunload
-handler is die waarschuwt wanneer de pagina wordt verwijderd.
Op dit moment zal Chrome conservatief zijn bij het weggooien van pagina's en dit alleen doen als het er zeker van is dat dit geen gevolgen heeft voor gebruikers. Pagina's waarvan is waargenomen dat ze een van de volgende handelingen uitvoeren terwijl ze zich in de verborgen status bevinden, worden bijvoorbeeld niet verwijderd, tenzij onder extreme beperkingen van de middelen:
- Audio afspelen
- WebRTC gebruiken
- De tabeltitel of favicon bijwerken
- Waarschuwingen weergeven
- Pushmeldingen verzenden
Voor de huidige lijstfuncties die worden gebruikt om te bepalen of een tabblad veilig kan worden bevroren of verwijderd, zie: Heuristieken voor bevriezen en verwijderen in Chrome.
De back/forward-cache is een term die wordt gebruikt om een navigatie-optimalisatie te beschrijven die sommige browsers implementeren en die het gebruik van de back- en forward-knoppen sneller maakt.
Wanneer een gebruiker een pagina verlaat, bevriezen deze browsers een versie van die pagina, zodat deze snel kan worden hervat als de gebruiker terug navigeert met de knoppen Vorige of Volgende. Houd er rekening mee dat het toevoegen van een unload
-gebeurtenishandler verhindert dat deze optimalisatie mogelijk is .
In alle opzichten is dit bevriezen functioneel hetzelfde als wat de bevriezingsbrowsers doen om de CPU/batterij te sparen; om die reden wordt het beschouwd als onderdeel van de bevroren levenscyclusstatus.
Als ik geen asynchrone API's in de bevroren of beëindigde status kan uitvoeren, hoe kan ik dan gegevens opslaan in IndexedDB?
In bevroren en beëindigde toestanden worden bevriesbare taken in de taakwachtrijen van een pagina opgeschort, wat betekent dat asynchrone en op callback gebaseerde API's zoals IndexedDB niet betrouwbaar kunnen worden gebruikt.
In de toekomst zullen we een methode commit()
toevoegen aan IDBTransaction
objecten, waardoor ontwikkelaars een manier krijgen om in feite alleen-schrijven-transacties uit te voeren waarvoor geen callbacks nodig zijn. Met andere woorden: als de ontwikkelaar alleen maar gegevens naar IndexedDB schrijft en geen complexe transactie uitvoert die bestaat uit lees- en schrijfbewerkingen, kan de methode commit()
worden voltooid voordat taakwachtrijen worden opgeschort (ervan uitgaande dat de IndexedDB-database al open is).
Voor code die vandaag de dag moet werken, hebben ontwikkelaars echter twee opties:
- Gebruik sessieopslag: Sessieopslag is synchroon en blijft behouden wanneer pagina's worden weggegooid.
- Gebruik IndexedDB van uw servicemedewerker: een servicemedewerker kan gegevens opslaan in IndexedDB nadat de pagina is beëindigd of verwijderd. In de gebeurtenislistener
freeze
ofpagehide
kunt u gegevens naar uw servicemedewerker sturen viapostMessage()
, waarna de servicemedewerker de gegevens kan opslaan.
Uw app testen in de bevroren en afgedankte status
Om te testen hoe uw app zich gedraagt in de bevroren en weggegooide status, kunt u naar chrome://discards
gaan om uw geopende tabbladen daadwerkelijk te bevriezen of te verwijderen.
Hierdoor kunt u ervoor zorgen dat uw pagina de freeze
en resume
correct afhandelt, evenals de vlag document.wasDiscarded
wanneer pagina's opnieuw worden geladen na het weggooien.
Samenvatting
Ontwikkelaars die de systeembronnen van de apparaten van hun gebruikers willen respecteren, moeten hun apps bouwen met de status van de paginalevenscyclus in gedachten. Het is van cruciaal belang dat webpagina's niet buitensporig veel systeembronnen verbruiken in situaties die de gebruiker niet zou verwachten
Hoe meer ontwikkelaars de nieuwe Page Lifecycle API's gaan implementeren, hoe veiliger het voor browsers zal zijn om pagina's die niet worden gebruikt, te bevriezen en te verwijderen. Dit betekent dat browsers minder geheugen, CPU, batterij en netwerkbronnen verbruiken, wat een overwinning is voor gebruikers.