Sayfa Yaşam Döngüsü API'sı

Tarayıcı Desteği

  • 68
  • 79
  • x
  • x

Günümüzde modern tarayıcılar, sistem kaynakları kısıtlı olduğunda bazen sayfaları askıya almakta veya tamamen silmektedir. Gelecekte, tarayıcılar bunu proaktif olarak yapmak isterler, böylece daha az güç ve bellek harcarlar. Page Lifecycle API, sayfalarınızın kullanıcı deneyimini etkilemeden bu tarayıcı müdahalelerini güvenli bir şekilde ele alabilmesi için yaşam döngüsü kancaları sağlar. Uygulamanızda bu özellikleri uygulamanız gerekip gerekmediğini görmek için API'ye göz atın.

Arka plan

Uygulama yaşam döngüsü, modern işletim sistemlerinin kaynakları yönetmek için kullandığı temel yollardan biridir. Android, iOS ve son Windows sürümlerinde uygulamalar herhangi bir zamanda işletim sistemi tarafından başlatılabilir ve durdurulabilir. Böylece bu platformlar, kaynakları kullanıcıya en faydalı olacak şekilde sadeleştirip yeniden tahsis edebilir.

Web'de bugüne kadar böyle bir yaşam döngüsü olmamıştı ve uygulamalar süresiz olarak kullanımda tutulabilir. Çok sayıda web sayfası çalışırken bellek, CPU, pil ve ağ gibi kritik sistem kaynaklarına aşırı abone olunabilir. Bu durum, kötü bir son kullanıcı deneyimine yol açabilir.

Web platformunda uzun zamandır load, unload ve visibilitychange gibi yaşam döngüsü durumlarıyla ilgili etkinlikler bulunuyor olsa da bu etkinlikler yalnızca geliştiricilerin kullanıcı tarafından başlatılan yaşam döngüsü durumundaki değişikliklere yanıt verebilmesini sağlar. Web'in düşük güçlü cihazlarda güvenilir bir şekilde çalışması (ve genel olarak tüm platformlarda daha bilinçli bir şekilde çalışması) için tarayıcıların, sistem kaynaklarını proaktif olarak geri alacağı ve yeniden tahsis edecek bir yola ihtiyacı vardır.

Aslında, günümüzde tarayıcılar arka plan sekmelerindeki sayfalara ilişkin kaynakları korumak için etkin önlemler alıyor ve pek çok tarayıcı (özellikle Chrome) genel kaynak ayak izini azaltmak için bu konudan çok daha fazlasını yapmak istiyor.

Sorun şu ki, geliştiricilerin sistem tarafından başlatılan bu tür müdahalelere hazırlanmak için hiçbir yolunun olmaması ve hatta bunların gerçekleştiğini bile anlaması mümkün değil. Bu, tarayıcıların ölçülü olması veya web sayfalarını bozma riski taşıması gerektiği anlamına gelir.

Page Lifecycle API, bu sorunu aşağıdaki şekilde çözmeye çalışır:

  • Web'deki yaşam döngüsü durumları kavramını tanıtma ve standart hale getirme.
  • Tarayıcıların, gizli veya etkin olmayan sekmeler tarafından kullanılabilecek kaynakları sınırlamasına olanak tanıyan, sistem tarafından başlatılan yeni durumlar tanımlama.
  • Web geliştiricilerinin sistem tarafından başlatılan bu yeni durumlara giden ve bu durumlardan çıkan geçişlere yanıt vermesine olanak tanıyan yeni API'ler ve etkinlikler oluşturma.

Bu çözüm, web geliştiricilerin sistem müdahalelerine dayanıklı uygulamalar derlemek için ihtiyaç duyduğu öngörülebilirliği sağlar ve tarayıcıların sistem kaynaklarını daha agresif bir şekilde optimize etmesine olanak tanıyarak sonuç olarak tüm web kullanıcılarına fayda sağlar.

Bu yayının geri kalanında, yeni Sayfa Yaşam Döngüsü özellikleri tanıtılacak ve bu özelliklerin mevcut tüm web platformu durumları ve etkinliklerle nasıl bir ilişki içinde olduğu keşfedilecek. Ayrıca, geliştiricilerin her eyalette yapması gereken (ve yapmaması gereken) iş türleriyle ilgili öneriler ve en iyi uygulamalar da sunulacaktır.

Sayfa Yaşam Döngüsü durumlarına ve etkinliklerine genel bakış

Tüm Sayfa Yaşam Döngüsü durumları ayrı ve karşılıklı olarak birbirini dışlar. Diğer bir deyişle bir sayfa, aynı anda yalnızca bir durumda olabilir. Bir sayfanın yaşam döngüsü durumunda yapılan çoğu değişiklik genellikle DOM etkinlikleri aracılığıyla gözlemlenebilir (istisnalar için her bir eyalet için geliştirici önerilerine bakın).

Sayfa Yaşam Döngüsü durumlarını ve bunlar arasında geçişlere işaret eden etkinlikleri açıklamanın en kolay yolu bir şema kullanmaktır:

Bu belgede açıklanan durum ve etkinlik akışının görsel bir temsili.
Page Lifecycle API durumu ve etkinlik akışı.

Eyaletler

Aşağıdaki tabloda her bir durum ayrıntılı olarak açıklanmaktadır. Ayrıca, geliştiricilerin değişiklikleri gözlemlemek için kullanabileceği etkinliklerin yanı sıra öncesinde ve sonrasında oluşabilecek olası durumları da listeler.

Eyalet Açıklama
Etkin

Bir sayfa görünüyorsa ve giriş odağı varsa etkin durumdadır.

Olası önceki durumlar:
pasif (focus etkinliği aracılığıyla)
donduruldu (resume etkinliği, ardından pageshow etkinliği aracılığıyla)

Olası sonraki durumlar:
pasif ( blur etkinliği aracılığıyla)

Pasif

Bir sayfa görünüyorsa ve giriş odağı yoksa pasif durumda demektir.

Olası önceki durumlar:
active (blur etkinliği aracılığıyla)
hidden ( visibilitychange etkinliği aracılığıyla)
dondu (resume etkinliği ve ardından etkinlik aracılığıyla) pageshow

Olası sonraki durumlar:
active (focus etkinliği aracılığıyla)
hidden ( visibilitychange etkinliği aracılığıyla)

Gizli

Bir sayfa görünmüyorsa (ve dondurulmamış, silinmemiş veya sonlandırılmamışsa) gizli durumundadır.

Olası önceki durumlar:
pasif ( visibilitychange etkinliği aracılığıyla)
donma (resume etkinliği, ardından pageshow etkinliği aracılığıyla)

Olası sonraki durumlar:
pasif ( visibilitychange etkinliği aracılığıyla)
donduruldu (freeze etkinliği aracılığıyla)
silindi (etkinlik tetiklenmedi)
sonlandırılmadı

Donmuş

Dondurulmuş durumundayken tarayıcı, sayfa dondurma işlemi kaldırılana kadar sayfanın görev sıralarındaki dondurulabilir görevlerin yürütülmesini askıya alır. Bu, JavaScript zamanlayıcıları ve geri çağırmaların çalışmadığı anlamına gelir. Zaten çalıştırılan görevler tamamlanabilir (en önemlisi freeze geri çağırması) ancak yapabilecekleri şeyler ve ne kadar süreyle çalışabilecekleri konusunda sınırlı olabilir.

Tarayıcılar, CPU/pil/veri kullanımını korumak için sayfaları dondurur. Aynı zamanda bu özelliği, daha hızlı geri-ileri gezinme olanağı sunarak tam sayfa yeniden yükleme ihtiyacını ortadan kaldırır.

Olası önceki durumlar:
hidden (freeze etkinliği aracılığıyla)

Olası sonraki durumlar:
active (resume etkinliği ve ardından pageshow etkinliği aracılığıyla)
pasif resume etkinliği aracılığıyla, ardından pageshow etkinliği aracılığıyla, ardından pageshow etkinliği
açık

etkin etkinliği tetikler
resume

Sonlandırıldı

Bir sayfa, yüklemesi kaldırılmaya ve tarayıcı tarafından bellekten silinmeye başladıktan sonra sonlandırıldı durumunda olur. Bu durumda hiçbir yeni görev başlayamaz ve devam eden görevler çok uzun sürerse sonlandırılabilir.

Olası önceki durumlar:
hidden (pagehide etkinliği aracılığıyla)

Olası sonraki durumlar:
NONE

Silindi

Kaynakları korumak amacıyla bir sayfa tarayıcı tarafından kaldırıldığında silindi durumunda olur. Silme işlemleri genellikle yeni işlemlerin başlatılmasının imkansız olduğu kaynak kısıtlamaları altında gerçekleştiğinden hiçbir görev, etkinlik geri çağırması veya herhangi bir türde JavaScript bu durumda çalışamaz.

Silindi durumunda, sayfa kaldırılmış olsa bile sekmenin kendisi (sekme başlığı ve site simgesi dahil) genellikle kullanıcı tarafından görülebilir.

Olası önceki durumlar:
hidden (hiçbir etkinlik tetiklenmedi)
donduruldu (etkinlik tetiklenmedi)

Olası sonraki durumlar:
NONE

Etkinlikler

Tarayıcılar çok sayıda etkinlik gönderir, ancak bunların yalnızca küçük bir kısmı Sayfa Yaşam Döngüsü durumunda olası bir değişikliğe işaret eder. Aşağıdaki tabloda, yaşam döngüsüyle ilgili tüm etkinlikler özetlenmiş ve hangi durumlara geçiş yapılabileceği listelenmiştir.

Ad Ayrıntılar
focus

Bir DOM öğesine odaklanıldı.

Not: focus etkinliği mutlaka durum değişikliği olduğunu göstermez. Yalnızca sayfada önceden giriş odağı yoksa durum değişikliği sinyali verir.

Olası önceki durumlar:
pasif

Olası geçerli durumlar:
etkin

blur

Bir DOM öğesinin odağı kayboldu.

Not: blur etkinliği mutlaka durum değişikliği olduğunu göstermez. Yalnızca sayfanın artık giriş odağı yoksa (yani sayfa yalnızca odağı bir öğeden diğerine geçirmediyse) bir durum değişikliği olduğunu gösterir.

Olası önceki durumlar:
etkin

Olası geçerli durumlar:
pasif

visibilitychange

Dokümanın visibilityState değeri değişti. Kullanıcı yeni bir sayfaya gittiğinde, sekmeleri değiştirdiğinde, bir sekmeyi kapattığında, tarayıcıyı simge durumuna küçülttüğünde veya kapattığında ya da mobil işletim sistemlerinde uygulama değiştirdiğinde bu durum ortaya çıkabilir.

Olası önceki durumlar:
pasif
gizli

Olası geçerli durumlar:
pasif
gizli

freeze *

Sayfa az önce donduruldu. Sayfanın görev sıralarındaki dondurulabilir görevler başlatılmaz.

Olası önceki durumlar:
gizli

Olası geçerli durumlar:
dondurulmuş

resume *

Tarayıcı, dondurulmuş bir sayfayı devam ettirmiştir.

Olası önceki durumlar:
dondurulmuş

Olası geçerli durumlar:
etkin (ardından pageshow etkinliği varsa)
pasif (ardından pageshow etkinliği geliyorsa)
gizli

pageshow

Bir oturum geçmişi girişine yönlendiriliyor.

Bu, yepyeni bir sayfa yükleme veya geri-ileri önbellekten alınmış bir sayfa olabilir. Sayfa geri-ileri önbellekten alınmışsa etkinliğin persisted özelliği true, aksi takdirde false olur.

Olası önceki durumlar:
Dondurulmuş (bir resume etkinliği de tetiklenecektir)

Olası geçerli durumlar:
etkin
pasif
gizli

pagehide

Bir oturum geçmişi girişine geçiş yapılıyor.

Kullanıcı başka bir sayfaya gidiyorsa ve tarayıcı, geçerli sayfayı daha sonra yeniden kullanılmak üzere geri-ileri önbelleğe ekleyebiliyorsa etkinliğin persisted özelliği true olur. true olduğunda sayfa dondurulmuş durumuna, aksi takdirde sonlandırıldı durumuna geçer.

Olası önceki durumlar:
gizli

Olası geçerli durumlar:
Dondurulmuş (event.persisted doğru, freeze etkinliği sona erdi)
sonlandırıldı (event.persisted yanlıştır, unload etkinlik gerçekleşir)

beforeunload

Pencere, doküman ve kaynakları kaldırılmak üzere. Belge hâlâ görünür durumda ve etkinlik bu noktada hâlâ iptal edilebilir.

Önemli: beforeunload etkinliği yalnızca kullanıcıyı kaydedilmemiş değişiklikler konusunda uyarmak için kullanılmalıdır. Bu değişiklikler kaydedildikten sonra etkinlik kaldırılır. Bazı durumlarda performansı olumsuz olabileceğinden sayfaya hiçbir zaman koşulsuz olarak eklenmemelidir. Ayrıntılı bilgi için eski API'ler bölümünü inceleyin.

Olası önceki durumlar:
gizli

Olası geçerli durumlar:
sonlandırıldı

unload

Sayfa kaldırılıyor.

Uyarı: Güvenilir olmadığı ve bazı durumlarda performansı düşürebileceği için unload etkinliğinin kullanılması hiçbir zaman önerilmez. Daha fazla bilgi edinmek için eski API'ler bölümünü inceleyin.

Olası önceki durumlar:
gizli

Olası geçerli durumlar:
Sonlandırıldı

* Page Lifecycle API tarafından tanımlanan yeni bir etkinliği gösterir

Chrome 68'de eklenen yeni özellikler

Önceki grafikte, kullanıcı tarafından değil sistem tarafından başlatılan iki durum gösterilmektedir: dondurulmuş ve silinmiş. Daha önce de belirtildiği gibi, tarayıcılar bugün ara sıra gizli sekmeleri donduruyor ve siliyor (kendi takdirlerine bağlı olarak), ancak geliştiricilerin bu durumun ne zaman olduğunu bilmeleri mümkün değildir.

Chrome 68'de geliştiriciler artık document üzerindeki freeze ve resume etkinliklerini dinleyerek gizli bir sekmenin ne zaman donduğunu ve dondurulduğunu gözlemleyebilir.

document.addEventListener('freeze', (event) => {
  // The page is now frozen.
});

document.addEventListener('resume', (event) => {
  // The page has been unfrozen.
});

Chrome 68'den itibaren document nesnesi artık masaüstü Chrome'da bir wasDiscarded özelliği içeriyor (Android desteği bu sorunda izleniyor). Bir sayfanın gizli sekmedeyken silinip silinmediğini belirlemek için sayfa yükleme zamanında bu özelliğin değerini inceleyebilirsiniz. (Not: Silinen sayfaların tekrar kullanılabilmesi için yeniden yüklenmesi gerekir).

if (document.wasDiscarded) {
  // Page was previously discarded by the browser while in a hidden tab.
}

freeze ve resume etkinliklerinde yapılması gerekenlerin önemli olduğu, ayrıca silinecek sayfaları ele alma ve bu tür durumlara hazırlanma konusunda tavsiyeler için her durum için geliştirici önerilerini inceleyin.

Sonraki birkaç bölümde, bu yeni özelliklerin mevcut web platformu durumları ve etkinlikleri ile nasıl uyumlu olduğuna dair bir genel bakış sunulmaktadır.

Kodda Sayfa Yaşam Döngüsü durumları nasıl gözlemlenir?

active, pasif ve hidden durumlarında, mevcut web platformu API'lerinden geçerli Sayfa Yaşam Döngüsü durumunu belirleyen JavaScript kodu çalıştırmak mümkündür.

const getState = () => {
  if (document.visibilityState === 'hidden') {
    return 'hidden';
  }
  if (document.hasFocus()) {
    return 'active';
  }
  return 'passive';
};

Öte yandan, dondurulmuş ve sonlandırıldı durumları ise durum değiştikçe yalnızca ilgili etkinlik işleyicilerde (freeze ve pagehide) tespit edilebilir.

Durum değişikliklerini gözlemleme

Daha önce tanımlanan getState() işlevini temel alarak, tüm Sayfa Yaşam Döngüsü durum değişikliklerini aşağıdaki kodu kullanarak gözlemleyebilirsiniz.

// 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);

Bu kodun işlevi üç şeydir:

  • getState() işlevini kullanarak başlangıç durumunu ayarlar.
  • Sonraki durumu kabul eden bir işlev tanımlar ve değişiklik varsa durum değişikliklerini konsola kaydeder.
  • Gerekli tüm yaşam döngüsü etkinlikleri için yakalama etkinlik işleyicileri ekler. Bunlar da logStateChange() çağrısı yaparak bir sonraki duruma geçer.

Bu kodla ilgili unutulmaması gereken bir nokta, tüm etkinlik işleyicilerin window öğesine eklenmesi ve tümünün {capture: true} değerini iletmesidir. Bu durumun birkaç nedeni vardır:

  • Tüm Sayfa Yaşam Döngüsü etkinlikleri aynı hedefe sahip değildir. window üzerinde pagehide ve pageshow tetiklendi. visibilitychange, freeze ve resume document tarihinde tetiklendi, focus ve blur ise ilgili DOM öğelerinde tetiklendi.
  • Bu etkinliklerin çoğu baloncuk olarak açılmaz, yani ortak bir üst öğe öğesine yakalama yapmayan etkinlik işleyiciler ekleyip bunların tümünü gözlemlemek imkansızdır.
  • Yakalama aşaması, hedef veya balon aşamalarından önce yürütüldüğünden dinleyicileri buraya eklemek, diğer kod tarafından iptal edilmeden önce dinleyicilerin çalışmasını sağlar.

Her eyalet için geliştirici önerileri

Geliştiriciler olarak, hem Sayfa Yaşam Döngüsü durumlarını anlamanız hem de bunları kod içinde nasıl gözlemleyeceğinizi bilmeniz önemlidir. Çünkü yapmanız (ve yapmamanız) gereken iş türü, büyük ölçüde sayfanızın hangi durumda olduğuna bağlıdır.

Örneğin, sayfa gizli durumdayken kullanıcıya geçici bir bildirim göstermenin bir anlamı yoktur. Bu örnek oldukça açık olsa da, belirtmeye değecek kadar açık olmayan başka öneriler de vardır.

Eyalet Geliştirici önerileri
Active

Etkin durum, kullanıcı için en kritik zamandır ve bu nedenle sayfanızın kullanıcı girişlerine duyarlı olması için en önemli zamandır.

Ana iş parçacığını engelleyebilecek, kullanıcı arayüzü olmayan tüm çalışmaların önceliği boşta kalma sürelerine düşürülmeli veya bir web çalışanına devredilmelidir.

Passive

Pasif durumda, kullanıcı sayfayla etkileşimde bulunmaz ancak sayfayı görebilir. Bu, kullanıcı arayüzü güncellemelerinin ve animasyonlarının sorunsuz olması gerektiği anlamına gelir. Ancak bu güncellemelerin zamanlaması daha az önemlidir.

Sayfanın etkin olan ayarı pasif olarak değiştiğinde, kaydedilmemiş uygulama durumunun devam ettirilmesi için uygun bir zamandır.

Hidden

Sayfa pasif iken gizli olarak değiştiğinde, kullanıcı yeniden yüklenene kadar sayfayla tekrar etkileşimde bulunmayabilir.

Gizli'ye geçiş genellikle geliştiriciler tarafından güvenilir şekilde gözlemlenebilen son durum değişikliğidir (bu özellikle mobil cihazlarda kullanıcılar sekmeleri veya tarayıcı uygulamasının kendisini kapatabildiği için geçerlidir ve bu durumlarda beforeunload, pagehide ve unload etkinlikleri tetiklenmez).

Yani, gizli durumunu, kullanıcı oturumunun olası son kısmı olarak ele almanız gerekir. Başka bir deyişle, kaydedilmemiş tüm uygulama durumlarını koruyun ve gönderilmemiş analiz verilerini gönderin.

Ayrıca, kullanıcı arayüzü güncellemeleri yapmayı (kullanıcı tarafından görülmeyeceğinden) durdurmalı ve kullanıcının arka planda çalışmasını istemediği tüm görevleri durdurmalısınız.

Frozen

Dondurulmuş durumundayken, görev sıralarındaki dondurulabilir görevler sayfa dondurulana kadar askıya alınır.Bu durum hiçbir zaman gerçekleşmeyebilir (ör. sayfa silinirse).

Yani, sayfa gizli iken dondurulmuş olarak değiştiğinde, dondurulduğunda aynı kaynaktaki diğer açık sekmeleri etkileyebilecek veya tarayıcının sayfayı geri-ileri önbelleğe yerleştirmesini etkileyebilecek zamanlayıcıları durdurmanız veya bağlantıları koparmanız önemlidir.

Özellikle şunları yapmanız önemlidir:

Ayrıca, sayfa silinip daha sonra yeniden yüklenirse geri yüklenmesini istediğiniz tüm dinamik görünüm durumlarını (ör. kaydırma konumu) sessionStorage (veya commit() aracılığıyla IndexedDB) olarak değiştirmelisiniz.

Sayfa dondurulmuş durumdan gizli durumuna geçerse kapalı bağlantıları yeniden açabilir veya sayfa ilk kez dondurulmuşken durdurduğunuz yoklamayı yeniden başlatabilirsiniz.

Terminated

Bir sayfa sonlandırıldı durumuna geçtiğinde genellikle herhangi bir işlem yapmanız gerekmez.

Kullanıcı işlemi sonucunda yüklemesi kaldırılan sayfalar, sonlandırıldı durumuna geçmeden önce her zaman gizli durumundan geçtiğinden, gizli durumu, oturum sonlandırma mantığının (ör. kalıcı uygulama durumu ve Analytics'e raporlama) gerçekleştirilmesi gereken yerdir.

Ayrıca (gizli durum önerilerinde de belirtildiği gibi) geliştiricilerin, sonlandırılmış duruma geçişin birçok durumda (özellikle mobilde) güvenilir şekilde tespit edilemediğini fark etmeleri çok önemlidir.Bu nedenle, sonlandırma etkinliklerine (ör. beforeunload, pagehide ve unload) bağımlı olan geliştiriciler muhtemelen veri kaybediyordur.

Discarded

Bir sayfa silindiğinde geliştiriciler silindi durumu gözlemleyemez. Bunun nedeni, sayfaların genellikle kaynak kısıtlamaları altında silinmesi ve bir silme etkinliğine yanıt olarak komut dosyasının çalışmasına izin vermek için bir sayfanın dondurulmasının çoğu durumda mümkün olmamasıdır.

Sonuç olarak, gizli değerinden dondurulmuş değerine yapılan değişikliğin silinme olasılığına karşı hazırlıklı olmanız gerekir. Daha sonra, sayfa yüklenme süresinde, silinen bir sayfanın geri yüklenmesi için document.wasDiscarded değerini işaretleyebilirsiniz.

Bir kez daha, yaşam döngüsü olaylarının güvenilirliği ve sıralaması tüm tarayıcılarda tutarlı bir şekilde uygulanmadığından, tablodaki önerileri uygulamanın en kolay yolu PageLifecycle.js öğesini kullanmaktır.

Kaçınılması gereken eski yaşam döngüsü API'leri

Aşağıdaki etkinliklerden mümkün olduğunca kaçınılmalıdır.

unload etkinliği

Birçok geliştirici unload etkinliğini garantili geri çağırma olarak görür ve durumu kaydetmek ve analiz verilerini göndermek için oturum sonu sinyali olarak kullanır. Ancak bunu yapmak, özellikle mobil cihazlarda son derece güvenilir değildir. Mobil cihazlarda sekme değiştiriciden bir sekmenin kapatılması veya uygulama değiştiriciden tarayıcı uygulamasının kapatılması da dahil olmak üzere, birçok tipik kaldırma durumunda unload etkinliği tetiklenmez.

Bu nedenle, bir oturumun ne zaman sona ereceğini belirlemek için visibilitychange etkinliğine güvenmek ve gizli durumu uygulama ile kullanıcı verilerini kaydetmek için son güvenilir zaman olarak kabul etmek her zaman daha iyidir.

Ayrıca, yalnızca kayıtlı bir unload etkinlik işleyicisinin (onunload veya addEventListener() aracılığıyla) bulunması, tarayıcıların daha hızlı geri-ileri yüklemeler için sayfaları geri-ileri önbelleğe yerleştirmesini engelleyebilir.

Tüm modern tarayıcılarda, olası sayfa yükleme işlemlerini algılamak için unload etkinliği yerine her zaman pagehide etkinliğinin kullanılması önerilir. Bu etkinlik, sonlandırıldı durumu olarak da bilinir. Internet Explorer 10 ve önceki sürümlerini desteklemeniz gerekiyorsa pagehide etkinliğini algılamalı ve unload tarayıcısını yalnızca tarayıcı pagehide desteklemiyorsa kullanmalısınız:

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.
});

beforeunload etkinliği

beforeunload etkinliğinde unload etkinliğiyle benzer bir sorun vardır. Bu nedenle, geçmişte bir beforeunload etkinliğinin varlığı sayfaların geri-ileri önbelleğe uygun olmasını engelleyebilir. Modern tarayıcılarda bu kısıtlama yoktur. Bazı tarayıcılar önlem olarak, bir sayfayı geri-ileri önbelleğe yerleştirmeye çalışırken beforeunload etkinliğini tetiklemez. Bu da, etkinliğin oturum sonu sinyali olarak güvenilir olmadığı anlamına gelir. Ayrıca, bazı tarayıcılar (Chrome dahil), beforeunload etkinliğinin tetiklenmesine izin vermeden önce sayfada kullanıcı etkileşimi yapılmasını gerektirir ve bu etkinliğin güvenilirliğini daha da artırır.

beforeunload ile unload arasındaki farklardan biri, beforeunload kodunun meşru kullanımlarının olmasıdır. Örneğin, kullanıcıyı kaydedilmemiş değişiklikleri olduğu konusunda uyarmak isterseniz, sayfanın yüklemesini kaldırmaya devam ederse bu kullanıcıyı kaybedeceklerini anlarsınız.

beforeunload kullanmak için geçerli nedenler bulunduğundan, yalnızca kullanıcıda kaydedilmemiş değişiklikler varsa beforeunload işleyicileri eklemeniz, ardından bunları kaydettikten hemen sonra kaldırmanız önerilir.

Başka bir deyişle, bunu yapmayın (koşulsuz olarak bir beforeunload dinleyicisi eklediği için):

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);
  }
});

Bunun yerine, beforeunload işleyicisini yalnızca gerektiğinde ekleyip gerekmediğinde kaldırdığı için şunu yapın:

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);
});

SSS

Neden "yükleniyor" durumu görünmüyor?

Sayfa Yaşam Döngüsü API'sı, durumları ayrı ve karşılıklı olarak dışlayacak şekilde tanımlar. Bir sayfa etkin, pasif veya gizli durumda yüklenebildiği ve yüklenme tamamlanmadan önce durumu değiştirebildiği (hatta sonlandırılabildiği) için ayrı bir yükleme durumu bu paradigmada mantıklı değildir.

Sayfam gizlendiğinde önemli çalışıyor. Dondurulmasını veya silinmesini nasıl durdurabilirim?

Web sayfalarının gizli durumda çalışırken dondurulmamasının birçok geçerli nedeni vardır. En belirgin örnek müzik çalan bir uygulamadır.

Chrome'un bir sayfayı silmesinin riskli olabileceği durumlar da vardır. Örneğin, sayfada gönderilmemiş kullanıcı girişleri olan bir form olabilir veya sayfa kaldırılırken uyarı veren bir beforeunload işleyici olabilir.

Şu an için Chrome, sayfaları silerken tedbirli olacaktır ve bunu yalnızca kullanıcıları etkilemeyeceğinden emin olduğunda yapar. Örneğin, gizli durumdayken aşağıdakilerden herhangi birini yaptığı gözlenen sayfalar, aşırı kaynak kısıtlamaları olmadığı sürece silinmez:

  • Ses çalınıyor
  • WebRTC'yi kullanma
  • Tablo başlığını veya site simgesini güncelleme
  • Uyarılar gösteriliyor
  • Push bildirimleri gönderme

Bir sekmenin güvenli bir şekilde dondurulup dondurulamayacağını veya silinip silinemeyeceğini belirlemede kullanılan mevcut liste özellikleri için Chrome'daki Dondurma ve Silmeyle ilgili Bulgular bölümüne göz atın.

Geri-ileri önbellek nedir?

Geri-ileri önbellek, bazı tarayıcıların uyguladığı ve geri-ileri düğmelerinin daha hızlı kullanılmasını sağlayan bir gezinme optimizasyonunu tanımlamak için kullanılan bir terimdir.

Kullanıcı bir sayfadan ayrıldığında, bu tarayıcılar sayfanın bir sürümünü dondurur. Böylece, kullanıcının geri veya ileri düğmelerini kullanarak geri gitmesi durumunda sayfa hızlı bir şekilde devam ettirilebilir. unload etkinlik işleyici eklemenin, bu optimizasyonun mümkün olmasını engellediğini unutmayın.

Tüm amaçlar ve amaçlar doğrultusunda bu dondurma işlemi, işlevsel olarak dondurulan tarayıcıların CPU/pil tasarrufu sağlamak için yaptığı işlemlerle aynıdır; bu nedenle, donmuş yaşam döngüsü durumunun bir parçası olarak kabul edilir.

Dondurulmuş veya sonlandırılmış durumlarda eşzamansız API'leri çalıştıramıyorsam verileri IndexedDB'ye nasıl kaydedebilirim?

Dondurulmuş ve sonlandırılmış durumlarda, bir sayfanın görev sıralarındaki dondurulabilir görevler askıya alınır. Bu, IndexedDB gibi eşzamansız ve geri çağırmaya dayalı API'lerin güvenilir şekilde kullanılamayacağı anlamına gelir.

Gelecekte IDBTransaction nesnelerine bir commit() yöntemi ekleyeceğiz. Bu sayede geliştiriciler, geri çağırma gerektirmeyen ve etkili bir şekilde salt yazma gerektiren işlemleri gerçekleştirebilirler. Diğer bir deyişle, geliştirici sadece IndexedDB'ye veri yazıyorsa ve okuma ile yazmalardan oluşan karmaşık bir işlem gerçekleştirmiyorsa commit() yöntemi, görev sıraları askıya alınmadan (IndexedDB veritabanının zaten açık olduğu varsayılarak) işlemi tamamlayabilir.

Ancak bugün çalışması gereken kod için geliştiricilerin iki seçeneği vardır:

  • Oturum Depolamasını Kullanma: Oturum Depolama eşzamanlıdır ve sayfa silme işlemleri boyunca kalıcıdır.
  • Hizmet çalışanınızdan IndexedDB'yi kullanın: Service Worker, sayfa sonlandırıldıktan veya silindikten sonra IndexedDB'de veri depolayabilir. freeze veya pagehide etkinlik işleyicide postMessage() üzerinden Service Worker'a veri gönderebilirsiniz. Service Worker ise veri kaydetme işlemini gerçekleştirebilir.

Uygulamanızı donmuş ve silinmiş durumlarda test etme

Uygulamanızın donmuş ve silinmiş durumlarda nasıl davrandığını test etmek üzere açık sekmelerinizi gerçekten dondurmak veya silmek için chrome://discards adresini ziyaret edebilirsiniz.

Chrome Kullanıcı Arayüzünü Siliyor
Chrome Kullanıcı Arayüzünü Siliyor

Böylece, silindikten sonra sayfalar yeniden yüklendiğinde sayfanızın freeze ve resume etkinliklerinin yanı sıra document.wasDiscarded işaretini de doğru bir şekilde işlediğinden emin olabilirsiniz.

Özet

Kullanıcılarının cihazlarındaki sistem kaynaklarına saygı duymak isteyen geliştiriciler, uygulamalarını Sayfa Yaşam Döngüsü durumlarını düşünerek oluşturmalıdır. Web sayfalarının kullanıcının beklemediği durumlarda aşırı sistem kaynakları tüketmemesi önemlidir.

Yeni Sayfa Yaşam Döngüsü API'larını ne kadar çok geliştirici uygulamaya başlarsa tarayıcıların kullanılmayan sayfaları dondurması ve silmesi de o kadar güvenli olur. Bu durum, tarayıcıların daha az bellek, CPU, pil ve ağ kaynağı tüketeceği anlamına gelir. Bu da kullanıcılar için bir avantajdır.