Proč má stránka žere baterie?

V dnešní době je responzivní web důležitou součástí každé firemní stránky. A dá se předpokládat, že takový responzivní web bude hlavně zobrazován na mobilních zařízeních jako jsou chytré telefony a tablety, které mají dost omezenou kapacitu baterie a při vydatném používání vydrží jen pár hodin.

A jistě žádného návštěvníka nepřesvědčí o kvalitách Vašich stránek nebo nabízených produktů to, že při jejich procházení se výdrž jeho baterie sníží na polovinu. Častým příznakem problémů je pomalé nebo trhané skrolování na slabších (starších) strojích a zařízeních.

Jak tedy zabránit tomu, aby Vaše stránky doslova sežrali uživatelům baterie jejich zařízení?

I když to možná může vyznít podivně, tak i obyčejná HTML stránka s pár CSS styly a JS skripty může snížit výdrž baterie kvůli tomu, že svým nešetrným návrhem nutí prohlížeč (WebView) neustále provádět nějaké činnosti, čímž průběžně zatěžuje procesor mobilního zařízení, zabraňuje mu přejít do úsporného režimu (podtaktováním) a spotřebovává tedy energii baterie.

Podle vlastních zkušeností vím, že taková stránka může průběžně vytěžovat procesor na 25% až 50%, což při dnešních 4jádrových procesorech běžících na frekvencích v řádu gigaherz má pak devastující důsledky na výdrž baterie.

JavaScript

První, co vás asi napadne, že může neustále provádět nějakou činnost, je nějaká JavaScript funkce nešikovně pověšená na timer (setInterval(..., 100);) nebo event ($(document).on('scroll', ...);), který se vyvolává příliš často .

Najít takovou metodu ale není příliš problém díky JS Profileru, který najdete v každém debuggeru (v případě Android a iOS stačí vzdálené debugování v Chrome resp. Safari). Metoda, která z měření vyjde jako nejnáročnější (má nejvíce procent nebo času v kolonce Total time), je nejlepším kandidátem na optimalizaci, refaktoring nebo úplné vyhození („opravdu potřebujete každých 100ms přepočítat rozměry stránky?!?“).

Pokud vám ale z profileru vyjde, že JavaScripty vlastně nic nedělají („100% idle“) a přesto je procesor zařízení zatížený na desítky procent, bude nejspíše problém někde jinde.

Animované GIFy

Již od počátku věků (tedy od roku 1995) jsou animované GIFy součástí většiny stránek; až už jde o logo, které se otáčí (čistě pro efekt), nebo načítací kytičku zobrazenou během natahování stránky.

Animace znamená změnu a změna znamená přepočtení a překreslení stránky a přepočtení stránky znamená zátěž pro procesor a … asi už víte, kam to vede.

Nejlépe tedy uděláte, pokud animované obrázky úplně odstraníte – logo firmy nemusí být animované, aby bylo hezké (přeci jen už jsme trocho dál než v roce 1995) a kytička, která se neustále točí a prozrazuje uživately AJAXové updaty na pozadí, jde klidně nahradit za nějaké statické obrázky (např. zelený a červený puntík). Samozřejmě animace, která se zobrazí na pár sekund, než se stáhne nový obsah ze serveru, zase tolik nevadí (pokud není příliš častá).

Pozor na to, že některé prohlížeče animují i obrázky, které nejsou přímo vidět a jsou mimo obraz nebo schované pod něčím jiným. Hlavně se to týká obrázků tzv. „pod okrajem“ („below-fold“) – tedy ty, které jsou níže na stránce a zobrazí se teprve až na ně uživatel naskroluje. Pokud máte na stránce lazy-loading obrázků, jejiž placeholder je animovaný GIF, můžete tím úplně zabít CPU i baterii.

Pokud nepotřebujete animovaný obrázek zobrazovat, bude nejlépe ho úplně skrýt nebo nahradit statickým obrázkem:

/* špatně */
.loading {
    background-image: url(load.gif);
}
.loading.hidden {
    position: absolute;
    left: -10000px;
    top: -10000px;
}

/* správně - možnost A */
.loading.hidden {
    position: absolute;
    left: -10000px;
    top: -10000px;
    background-image: url(load.png);
}
/* správně - možnost B */
.loading.hidden {
    display: none;
}

Konkrétní možnost záleží na situaci – ne vždy je vhodné nebo možné obrázek úplně skrýt (např. proto, aby šlo spočítat jeho rozměry).

CSS animace

U animací provedených pomocí CSS je situace úplně stejná jako v případě animovaných obrázků – změna vede k spotřebovávání baterie.

Pokud vás tedy v předchozí kapitole napadlo nahradit animované obrázky propracovanými CSS3 animacemi, rychle na to zase zapomeňte.

Např. nahradit načítací kytičku CSS3 animací znamená přidat do DOMu celou řadu prvků, z nichž každý musí mít vlastní animaci, a prohlížeč pak místo jednoho obrázku překresluje několik prvků současně a má s tím daleko více práce.

Navíc, stejně jako u obrázků, platí, že prohlížeč musí překreslovat i animace prvků, které nejsou přímo vidět.

U animací tedy buď nastavte display:none nebo animaci svažte s nějakou konkrétní CSS třídou, kterou prvku přiřadíte jen pokud je vidět („in-viewport“).

/* špatně */
@keyframes anim-logo{
    from { background: red; }
    to { background: yellow; }
}
#logo {
     animation: anim-logo 5s infinite;
}

/* správně - možnost A */
#logo {
    background: red;
}
#logo.visible {
    animation: anim-logo 5s infinite;
 }
/* správně - možnost B */
#logo {
    animation: anim-logo 5s infinite;
}
#logo.hidden {
    display: none;
}

Uspání Cordova aplikace

Aplikace, která používá Cordova knihovnu a zobrazuje HTML obsah ve WebView, má na Android jednu nevýhodu – zatímco Java se zastaví poté, co aplikace přejde do pozadí (např. uživatel stiskně HOME tlačítko), JavaScripty a animace běží dál a spotřebovávají baterii. Abyste tomu zabránili, budete potřebovat říct knihovně, aby skripty zastavila nebo – v případě starší verze – to provést sami.

<preference
    name="keepRunning"
    value="false" 
/>

Kontrola CPU

Pro kontrolu, kolik vaše aplikace spotřebovává CPU, se vám mohou hodit následující rady:

Na Windows můžete spustit Správce úloh (po stisku CTRL+ALT+DELETE), přejít na záložku Procesy a nechat si výpis seřadit podle Procesoru. Na Windows 8 může být potřeba kliknout na „Více detailů“. Pro více podrobností (např. zatížení GPU) si stáhněte Sysinternals (Microsoft) Process Explorer.

Na MacOS najdete v /Aplikace/Utility nástroj Monitor Aktivit, kde si můžete nechat běžící aplikace seřadit podle „% CPU“. Případě můžete pod /Aplikace/Utility spustit Terminál a zadat příkaz „top“ (viz další odstavec pro Linux).

Na Linuxu můžete použít příkaz „top“ případně ještě doplněný o grep jména příslušného prohlížeče:

> top | grep chromium

A v případě Android můžete po zapnutí nástrojů pro vývojáře, stažení SDK a připojení telefonu k počítači, spustit ADB shell, ve které použijete příkaz top:

//Windows konzole, PowerShell, Terminál, apod.
./android-sdk/platform-tools/adb shell

//v ADB Shell
> top | grep com.android.chrome
> top | grep org.mozzila.firefox
> top | grep com.opera.browser
//pro Cordova/Phonegap aplikaci:
> top | grep org.mycompany.myapp

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *