Page Visibility API: Kouká na mě vůbec někdo?

Možná znáte výrok: „Vesmír existuje, jen když se na něj někdo dívá“. Mottem dnes popisované novinky – Page Visibility API – by mohla být parafráze tohoto výroku, nějak takto: „Stránka pracuje, jen když si ji někdo prohlíží“. Jak to celé funguje a jaký to má praktický význam? Ukážeme si v článku.

Seriál: Webdesignérův průvodce po HTML5 (21 dílů)

  1. Webdesignérův průvodce po HTML5 – díl nultý 25.5.2010
  2. Webdesignérův průvodce po HTML5 – nová sémantika 1.6.2010
  3. Webdesignérův průvodce po HTML5 – nová sémantika II 8.6.2010
  4. Webdesignérův průvodce po HTML5 – pohyblivé obrázky 15.6.2010
  5. Webdesignérův průvodce po HTML5 – používáme pohyblivé obrázky 22.6.2010
  6. Webdesignérův průvodce po HTML5 – taháme data od návštěvníka 29.6.2010
  7. HTML5 Audio: rádio ve vašich stránkách 13.7.2010
  8. Webdesignérův průvodce po HTML5: Microdata 20.7.2010
  9. AppCache: webové aplikace i bez připojení 27.7.2010
  10. Webdesignérův průvodce po HTML5: WebStorage 3.8.2010
  11. Webdesignérův průvodce po HTML5: Multithreading s WebWorkers 10.8.2010
  12. Webdesignérův průvodce po HTML5: Databáze v prohlížečích 17.8.2010
  13. Webdesignérův průvodce po HTML5: Shrnutí a rozhrnutí 24.8.2010
  14. HTML5: ukládáme si data k elementům 6.12.2010
  15. Webdesignérův průvodce po HTML5: Táhni a srůstej 5.1.2011
  16. HTML5: První krůčky s FileSystem API 15.2.2011
  17. Mobilizujeme web v HTML5 4.4.2011
  18. Single Page Apps a řešení problémů s historií 1.6.2011
  19. Page Visibility API: Kouká na mě vůbec někdo? 10.8.2011
  20. Práce se soubory v prohlížeči, díl 1 15.8.2011
  21. Práce se soubory v prohlížeči, díl 2 5.9.2011

Novinka, dostupná zatím v prohlížeči Chrome od verze 13 umožňuje obsloužit programem změny ve viditelnosti stránky. Page Visibility API umožňuje programátorovi zjistit, jestli je stránka právě viditelná nebo ne. K tomu umožňuje na změny viditelnosti reagovat.

Prohlížeče dnes už celkem běžně nabízejí prohlížení v panelech. Jednotlivé otevřené stránky, respektive skripty v nich spuštěné, běží nezávisle na sobě, a především běží nejen na stránce, na kterou se uživatel právě dívá v aktivním panelu, ale i na ostatních. Pokud máte v panelech otevřené stránky, které se pravidelně aktualizují, kde běží nějaké náročné skripty, bujné animace či se přehrává video, představuje to poměrně velkou zátěž, která navíc běží „do zdi“. Zcela zbytečně se zatěžuje procesor, a u mobilních zařízení bude jistě mít nemalý vliv na výdrž baterie.

Implementace v Chrome

Page Visibility API je, jak jsme si už říkali, implementován v Chrome od verze 13 a jeho implementace je „vendor-prefixed“, viz http://code.google.com/chro­me/whitepapers/pagevisibi­lity.html. Funkce si proto popíšeme v podobě, v jaké jsou dostupné v prohlížeči Chrome, tedy s prefixem „webkit“, a mějme, prosím, na paměti, že po jejich rozšíření přijde sjednocení na „neprefixové“ verzi – použijte tedy nějaký „shim“, kterým si tyto funkce zpřístupníte v „normovaném“ tvaru.

Page Visibility API přidává dva atributy objektu document  – atribut hidden a atribut visibilityState. V implementaci Chrome jsou dostupné jako document.webkitHidden a document.webkitVisibilityState.

webkitHidden je boolovská hodnota, která je true v případě, že stránka není vidět – tedy v případech, kdy je prohlížeč minimalizován, kdy je počítač zamknutý, kdy je stránka v panelu, který je na pozadí, dokonce i v případě, kdy je prohlížeč minimalizován a zobrazuje se jen jeho náhled. Hodnotu „False“ bude mít tehdy, když bude stránka zobrazená na popředí.

Na místě je podotknout, že v ostatních prohlížečích bude hodnota „undefined“, která je vyhodnocena jako „false“. Před prací s tímto atributem je rozumné udělat kontrolu pomocí  if (typeof document.webkitHidden === "undefined")

Předchozí atribut určuje, jestli stránku někdo může sledovat (jestli je viditelná), nebo zda je někde skrytá. Další atribut, document.webkitVisibilityState vrací řetězec, který udává přesněji stav, v jakém se stránka nachází:

hidden
Stránka je skrytá, není vidět, nezobrazuje se atd.
visible
Stránka je viditelná
prerender
Stránka byla vykreslena do cache, ještě ale není zobrazená
preview
Stránka se zobrazuje pouze v systémovém náhledu (např. při najetí kurzorem myši na minimalizovaný prohlížeč v panelu / docku) – tuto hodnotu Chrome zatím neimplementuje

Hodnoty „prerender“ a „preview“ nemusí prohlížeče poskytovat. Preferovaný způsob rozhodování, zda je stránka vidět nebo není, je podle atributu hidden (webkitHidden).

Vidí mě někdo?

Informace o viditelnosti samy o sobě nejsou až tak užitečné. Proto Page Visibility API nabízí i novou událost – visibilitychange (v implementaci Chrome jako „ webkitvisibilitychange “). Jak už název napovídá, tato událost je vyvolána ve chvíli, kdy se změní stav viditelnosti. Událost můžeme skriptem odchytit a zareagovat na ni.

Co si s touto informací skript má počít? Můžete např. snížit frekvenci periodického dotazování serveru a načítání novinek – když je stránka s chatem na pozadí nebo minimalizovaná, jistě není zapotřebí ji obnovovat co deset sekund, delší interval postačí. V případě, že se přehrává na stránce video, můžete jej „zapauzovat“ – viz pěkné demo od Sama Duttona. Pusťte si jej (v Chrome 13+, samosebou) a sledujte, co se bude dít, když si přepnete do jiného panelu, když prohlížeč minimalizujete atd.

Pro zajímavost – zdrojový kód výše odkázaného příkladu:

var videoElement = document.getElementById("videoElement");

// if the page is hidden, pause the video
// if the page is shown, play the video
function handleVisibilityChange() {
    if (document.webkitHidden) {
        videoElement.pause();
    } else {
        videoElement.play();
    }
}

// warn if the browser doesn't support document.webkitHidden
if (typeof document.webkitHidden === "undefined") {
    alert("This demo requires a browser such as Google Chrome 13 that supports the Page Visibility API.");
}

// avoid errors from browsers that don't support addEventListener
if (typeof document.addEventListener !== "undefined") {
    // handle page visibility change
    // see https://developer.mozilla.org/en/API/PageVisibility/Page_Visibility_API
    document.addEventListener("webkitvisibilitychange",  handleVisibilityChange, false);

    // revert to existing favicon for site when the page is closed
    // otherwise the favicon will remain as paused.png
    window.addEventListener("unload", function(){
        favicon.change('/favicon.ico');
    }, false);

    // when the video pauses, set the favicon
    videoElement.addEventListener("pause", function(){
        favicon.change('images/paused.png');
    }, false);

    // when the video plays, set the favicon
    videoElement.addEventListener("play", function(){
        favicon.change('images/playing.png');
    }, false);

    // set the document (tab) title from the current video time
    videoElement.addEventListener("timeupdate", function(){
        document.title = Math.floor(videoElement.currentTime) + " second(s)";
    }, false);
}

Využití najde v budoucnu toto API v nejrůznějších webových aplikacích, kde pomůže „snížit odběr“ ve chvílích, kdy budou aplikace minimalizované či „vypnuté“. Určitě naleznete další případy, v nichž má smysl, aby skript ve chvílích, kdy stránku nikdo nesleduje, takříkajíc „ubral plyn“.

Odkazy ke čtení

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Komentáře: 16

Přehled komentářů

evilcroco Proč k objektu document?
Štěpán Bechynský Podpora v IE10 PP2
Martin Soušek nebezpečná hloupost
JakubS Re: nebezpečná hloupost
Senior Database Developer Re: nebezpečná hloupost
biggringo bezpečnost
v6ak Re: bezpečnost
Jakub Vrána Hodnota undefined
undefined = true/false Re: Hodnota undefined
Jakub Vrána Re: Hodnota undefined
Martin Malý Re: Hodnota undefined
Jakub Vrána Starší prohlížeče
v6ak Re: Starší prohlížeče
Jakub Vrána Re: Starší prohlížeče
juraj Re: Starší prohlížeče
v6ak Re: Starší prohlížeče
Zdroj: https://www.zdrojak.cz/?p=3528