• Nebyly nalezeny žádné výsledky

Kritéria pro optimální PWA (Brightscout, 2018)

Lighthouse

CPWA1 Aplikace používá protokol HTTPS Ano

CPWA2 Aplikace je responzivní na všech velikostech obrazovky Ano CPWA3 Aplikace je instalovatelná (využívá a má správně konfigurovaný

service worker a web app manifest)

Ano

CPWA4 Doba k interaktivitě2 přes 3G připojení je do 10 vteřin Ano CPWA5 Aplikace je funkční ve všech prohlížečích Ne CPWA6 Aplikace je částečně funkční v off-line režimu Ne

CPWA7 Každá webová stránka má své URL Ne

Tabulka 2 Kritéria pro optimální PWA (Brightscout, 2018) ID Kritérium

OPWA1 Obsah stránek je indexovatelný vyhledavačem společnosti Google OPWA2 Metadata Schema.org jsou v případě potřeby k dispozici

OPWA3 Sociální metadata jsou v případě potřeby k dispozici OPWA4 Kanonické URL adresy jsou v případě potřeby k dispozici OPWA5 Stránky využívají History API

OPWA6 Při načítání stránky je pozice obsahu nehybná

OPWA7 Vrácením se ze stránky se zachová scrollovací pozice předešlé stránky OPWA8 Textová pole, při jejich plnění, nejsou překryta klávesnicí

OPWA9 Obsah stránek je možný sdílet i z celoobrazovkového režimu

2 Doba k interaktivitě pochází z anglického pojmu Time To Interactive (zkráceně TTI). Doba k interaktivitě je metrika, která měří dobu, po které je stránka plně interaktivní (Google, 2019).

OPWA10 Stránka se přizpůsobuje velikostem všech zobrazovacích zařízení (desktop, telefon i tablet)

OPWA11 Aplikace uživateli nabídne aplikaci přidat na domovskou stránku

OPWA12 Výzvy k přidání aplikace na domovskou stránku nejsou zobrazovány nadměrně OPWA13 Doba k interaktivitě přes 3G připojení je do 5 vteřin

OPWA14 Aplikace používá cache-first přístup (aplikace načítá prvně data z mezipaměti zařízení)

OPWA15 Pokud není zařízení připojeno k internetu, aplikace uživatele vhodně informuje OPWA16 Aplikace poskytuje uživateli informace o tom, jak budou notifikace použity OPWA17 Oznámení povzbuzující uživatele k zapnutí push notifikací nesmí být příliš

agresivní

OPWA18 Při zobrazení žádosti o povolení se jas obrazovky ztlumí OPWA19 Push notifikace jsou včasná, přesná a relevantní

OPWA20 Aplikace poskytuje možnost push notifikace vypnout a zapnout

OPWA21 K placení se využívá Native UI, které je poskytováno Payment Request API

1.4 Struktura PWA

Tato kapitola se zabývá důležitými prvky tvorby PWA. Kapitola je rozdělena tak, aby byly souhrnně popsány možnosti naplnění všech požadavků PWA uvedených v předchozí kapitole. Při dodržení všech bodů v této kapitole by měla aplikace splňovat všechna kritéria uvedených v kontrolním seznamu.

Předpokladem v této kapitole je SPA webová aplikace, která se bude rozšiřovat o funkcionality, které PWA nabízí.

1.4.1 Service Worker

Service Worker (česky služba na pozadí) je script běžící na pozadí. Je kompletně oddělen od webové stránky a nemá tedy přímý přístup k DOM. Místo toho komunikuje s webovou stránkou prostřednictvím rozhraní. Service worker je nedílnou součástí PWA a umožňují vývojářům implementovat funkce, které dělají běžné webové aplikace progresivními.

Webová aplikace se bez service worker spouští pouze na serverové nebo klientské části webové aplikace. Service worker v podstatě funguje jako proxy server, který je umístěn mezi

webovou aplikací, prohlížečem a sítí (je-li k dispozici). Z této mezivstrvy může service worker reagovat na události webové aplikace.

Service worker funguje nezávisle na připojení k internetu. V případě, že samotná aplikace nebude připojena k internetu, service worker nedostupnost rozpozná, zachytí požadavek a vrátí obsah, který byl uložen v cache.

Obdobně funguje i při zavření záložky prohlížeče s aplikací. Service worker na pozadí stále poslouchá a komunikuje se serverem. Tímto způsobem může provádět různé akce, jako je např. upozornění uživatele posíláním notifikací (GDev, 2019).

Životní cyklus

První událostí životního cyklus service worker je registrace, která je prvním krokem instalace. Registrace probíhá pomocí javascriptového kódu. Po úspěšné instalaci nastává aktivační krok, kdy je možné spouštět další akce jako je např. manipulace dat v cache. Po aktivaci může být service worker v jednom ze dvou stavů: buď bude service worker

ukončen, aby se šetřilo pamětí, nebo bude zpracovávat události načítání a zpráv, ke kterým dojde při odeslání požadavků z webové aplikace (GDev, 2019).

Obrázek 3 Životní cyklus service workeru při první instalaci (GDev, 2019)

Registrace service workeru

Nejvyšší prioritou by mělo být zajištění pozitivního zážitku pro uživatele z první návštěvy.

Je tedy nutné, aby registrace service workeru proběhla až po načtení stránky.

if ('serviceWorker' in navigator) {

window.addEventListener('load', () => {

navigator.serviceWorker.register('/service-worker.js').then((registration)

=> {

// Registrace úspěšná

console.log('Registrace service workeru úspěšná se scopem: ', registra-tion.scope);

}, function(err) { // Registrace selhala

console.log('Registrace service workeru selhala: ', err);

});

});

}

Výpis zdrojového kódu 1: Registrace service worker (GDev, 2019)

Tato část javascriptového kódu kontroluje, zda je service worker API dostupný. Pokud je API dostupné, registrace proběhne až při úplném načtení obsahu webové stránky.

Argumentem metody register() je cesta k javascriptovému souboru service-worker.js, ve kterém je samotný service worker definován. Při úspěšné registrace kód informuje vývojáře o scope, který definuje, k jakým souborům má service worker přístup (GDev, 2019).

Úspěšnost registrace lze zjistit přímo v prohlížeči. Kontrolu lze provést např. DevTools nástrojem, který integrován přímo v prohlížeči Google Chrome. Na chrome://inspect/#service-workers je zobrazen seznam všech registrovaných service workerů (viz obrázek 4).

Obrázek 4: DevTools - seznam registrovaných service workerů (GDev, 2019) Instalace service workeru

Po úspěšné registraci následuje instalace. Instalace je spouštěna událostí install, kterou zachycuje service worker a která dále volá další akce. Jednou z těchto akcí může být uložení stránky do cache prohlížeče (viz Výpis zdrojového kódu 2) (GDev, 2019).

var CACHE_NAME = 'my-site-cache-v1';

caches.open(CACHE_NAME) .then(function(cache) {

return cache.addAll(urlsToCache);

}) );

});

Výpis zdrojového kódu 2: Instalace service workeru (GDev, 2019)

V momentě, kdy se do cache prohlížeče uloží všechny soubory, bude instalace service workeru úspěšně ukončena. V opačném případě instalace selže a nový pokus o instalaci proběhne až při dalším načtení stránky.

Aktivace service workeru

Po instalačním kroku následuje krok aktivační. V případě, že je nějaká část aplikace stále řízena předchozím service workerem, přejde nově nainstalovaný service worker do stavu čekání. Service worker je aktivován jen v případě, kdy již není žádná část aplikace řízena předchozím service workerem. Metoda activate tedy zajišťuje to, že v daný okamžik běží pouze jedna verze service workeru (GDev, 2019).

self.addEventListener('activate', evet => { // Dělej něco

});

Výpis zdrojového kódu 3: Aktivace Service Workeru (GDev, 2019) Další události

Service worker je řízen událostmi. Procesy instalace a aktivace spouští odpovídající instalační a aktivační události, na které je service worker schopen odpovídat. Mezi tyto události patří (GDev, 2019):

- Message – událost, pomocí které service worker přijímá informace z jiných skriptů - Fetch – událost, pomocí které service worker reaguje na HTTP požadavek

- Push – událost, pomocí které service worker posílá notifikace

- Sync – událost, pomocí které service worker synchronizuje data

1.4.2 Bezpečnost

Service worker je schopen manipulovat s odpověďmi, které uživatel dostane. Proto je nezbytné, aby veškerá komunikace mezi klientem, service workerem a serverem byla šifrovaná. Jedním z útoků, na který by mohl uživatel na nezabezpečené aplikaci narazit je tzv. man-in-the-middle útok3.

Proti útokům tohoto typu je možné se bránit protokolem HTTPS, který společně s SSL nebo novějším TLS certifikátem ověřuje identitu webového serveru. O vystavení certifikátu lze zažádat u certifikačních autorit jako je např. Let's Encrypt. Po vystavení je třeba certifikát na serveru nainstalovat.

Ověření, zda aplikace používá HTTPS protokol, je možné zjistit z webového prohlížeče.

Pokud webová adresa na adresním řádku začíná na https, nutně to neznamená, že je stránka zabezpečená. Dále je nutné zkontrolovat i platnost certifikátu (Google, 2021).

Obrázek 5: Ukázka HTTPS protokolu a platného certifikátu

1.4.3 Web app manifest

Web app manifest dokument poskytující informace o webové aplikaci v JSON formátu, který umožňuje stažení a správného zobrazení webové aplikace na ploše zařízení. PWA manifest obsahuje mnoho klíčů. K tomu, aby se dala aplikace přidat na plochu zařízení je třeba definovat alespoň tyto klíče4 (Mozilla, 2021):

- name – název aplikace, které bude zobrazeno na ploše zařízení

3 Man in the middle útok je útok na kryptografii, kde se útočník snaží odposlouchávat a měnit komunikaci mezi účastníky tak, že se stane aktivním prostředníkem (Wikipedia, 2021).

4 Kompletní seznam klíčů je popsán v dokumentaci Web App Manifests (Mozilla, 2021).

- start_url – preferovaná adresa, která se načte při spuštění aplikace - icons – ikona aplikace, která bude zobrazena na ploše zařízení

- display – určuje preferovaný režim zobrazení webu. Může se jednat např. o režim celé obrazovky, kde nejsou zobrazeny žádné ovládací prvky webového prohlížeče.

Manifest se vkládá do HTML stránky aplikace pomocí elementu <link> v <head>

dokumentu.

{

"name": "HackerWeb",

"short_name": "HackerWeb", "start_url": ".",

"display": "standalone",

"description": "A readable Hacker News app.", "icons": [{

"src": "images/touch/homescreen48.png", "sizes": "48x48",

"type": "image/png"

}, {

"src": "images/touch/homescreen72.png", "sizes": "72x72",

"type": "image/png"

}]

}

Výpis zdrojového kódu 4: Příklad web app manifestu (Mozilla, 2021)

Aby se dala aplikace přidat na plochu, je třeba zajistit následující kritéria (Mozilla, 2021):

- šifrovaná komunikace přes HTTPS

- správně nadefinovaný web app manifest dokument, který obsahuje alespoň minimum klíčů uvedených výše

- k dispozici je vhodná ikona pro zobrazení na ploše zařízení

- prohlížeč Google Chrome navíc vyžaduje registrovaného service workera

1.4.4 Cache a přípojení k internetu

Aplikace by měla alespoň omezeně fungovat i bez připojení k internetu. V případě, že připojení k internetu není dostupné, je nutné uživatele upozornit o nedostupnosti připojení a omezené funkcionalitě prostřednictvím push notifikací. Skutečnost, zda je klient připojen k internetu, lze zjistit zachycováním událostí offline a online (Mozilla, 2021).

function updateOnlineStatus(event) {

Výpis zdrojového kódu 5: Zachycení stavu připojení (Mozilla, 2021)

Aby aplikace fungovala částečně i offline, je nutné ukládat statický obsah (HTML, JavaScript, CSS, obrázky atd.) a data do cache prohližeče. Obecně je doporučeno využívat Cache Storage API (součást service worker) na statický obsah aplikace a pro ostatní data využívat IndexedDB (Web.dev, 2019).

Ukládání zdrojů

(Google, 2019) ve své dokumentaci uvádí několik situací, kdy ukládat zdroje do cache:

Při instalaci (jako dependency) – Přístup vhodný pro ukládání statického obsahu webové aplikace. Jedná se o HTML, JavaSript, CSS soubory nebo obrázky. Ukládání probíhá s počáteční instalací service workeru. Depedency je chápáno, jako závislost při instalaci.

Pokud by instalace service workeru nebo ukládání do cache selhalo, proces selže a celá akce se opakuje.

Při instalaci – Přístup vhodný pro ukládání většího obsahu, kdy obsah není potřebný při počáteční instalaci, ale až v pozdější fázi. Příkladem může být např. hra, která si při instalaci uloží jen první část hry. Druhá část se nainstaluje po skončení první části.

Při aktivaci – Přístup vhodný pro smazání či migraci dat z cache. Jakmile se nainstaluje nový service worker a předchozí verze se nevyužívá, nový service worker se aktivuje a zachytí událost activate. Zvolená data se přesunou do nové cache a zbytek se smaže.

Při interakci s uživatelem – V případě, že celou webovou stránku nelze uložit do cache prohlížeče, si uživatel zvolí část obsahu, která se do cache uloží a bude dostupná i bez internetového připojení. Může se jednat např. o video, článek, obrázek apod.

Při požadavku ze sítě – Pokud nejsou data v cache, jsou data získána ze sítě. Data se zobrazí uživateli v prohlížeči a uloží do cache. Je třeba dbát opatrnosti, aby se nezaplnilo uložiště.

Načítání zdrojů z cache

Dále (Google, 2019) představuje strategie načítání dat z cache a ze sítě. Mezi nejčastěji využívané strategie patří:

Výhradně z cache – Strategie ideální pro ukládání statické části aplikace, která se nemění. Jedná se např. o statický soubor pro vykreslování webové stránky, který je uložen v cache při instalaci service workeru.

Obrázek 6: Výhradně z cache (Web.dev, 2020)

Výhradně ze sítě – Strategie ideální pro obsah, který se neustále mění a je třeba mít jeho nejaktuálnější verzi. Také se jedná o všechny HTTP dotazovací metody kromě metody GET – HEAD, POST, PUT, DELETE atd.

Obrázek 7: Výhradně ze sítě (Web.dev, 2020)

Prvně z cache, potom ze sítě – Strategie ideální pro aplikace tvořené s konceptem offline-first. Jedná se kombinaci první a druhé strategie, kdy se zdroje načtou prvně z cache a vše co není uloženo v cache se načte ze sítě.

Obrázek 8: Prvně z cache, potom ze sítě (Web.dev, 2020)

Prvně ze sítě, potom z cache – Strategie ideální pro obsah, který je nutný mít aktuální při dostupnosti připojení. V případě, že připojení není dostupné, se načte starší obsah z cache. Tento přístup má však nedostatky. Pokud by měl uživatel přerušované či pomalé

připojení, musel by čekat, až připojení kompletně selže, aby se mu načetl obsah alespoň z cache. To by způsobilo velkou dobu čekání a aplikace by působila celkově negativně. Proto je doporučeno využívat spíše přístup Prvně z cache, potom ze sítě, kdy se při horší konektivitě načtou alespoň data z cache a při kvalitnějším připojení se data aktualizují.

Obrázek 9: Prvně ze sítě, potom z cache (Web.dev, 2020)

Cache/siť závod – Strategie ideální pro obsah, který dosahuje pouze několika kilobajtů.

V tomto přístupu jde primárně o výkon na zařízeních s pomalým diskem. Data se načtou z cache/sítě podle toho, který je rychlejší.

Obrázek 10: Cache/síť závod (Web.dev, 2020)

1.4.5 Výkon

Jednou z hlavních podmínek při tvorbě webových aplikací je svižné počáteční i opětovné načítání aplikace. Tato podkapitola pojednává pouze o klientské části a možnostech optimalizace.

Zdroje špatně navrhnuté aplikace mohou dosahovat obrovských velikostí. Při nekvalitním internetovém připojení by se zdroje ze serverové části stahovali velmi dlouho a uživatel by tak musel čekat na první načítání a vykreslování aplikace.

Na výkonnost aplikace má nejčastěji vliv neoptimalizovaná multimédia a Javascript (Mozilla, 2021).

Optimalizace multimédií

Média, hlavně videa a obrázky, tvoří průměrně více než 70 % při stahování zdrojů ze serveru.

Proto by neměla být zanedbána. Technik optimalizace je několik, mezi ty nejpoužívanější patří (Mozilla, 2021):

- Lazy loading – načítání multimédií pouze v případě potřeby. Příkladem může být galerie fotek, kde se fotky nenačtou hned při spuštění, ale až poté, co uživatel posune stránkou.

- Výběr optimálního formátu – Optimální formát souboru obvykle závisí na charakteru obrázku. Formát SVG je vhodnější pro obrázky, které mají málo barev a nejsou fotorealistické. PNG formát je vhodný pro ilustrační grafiku, loga, mapy apod. Pokud to situace dovoluje, je doporučeno používat moderní formáty WebP nebo AVIF, které jsou vhodné pro obrázky i animované obrázky.

- Používání optimální velikosti – Pro menší obrazovky budou obrázky v menším rozlišení, a naopak pro větší obrazovky budou obrázky ve větším rozlišení.

Optimalizace javascriptového kódu

Přestože multimédia tvoří většinu stažených zdrojů. Javascript může mít na výkonnost aplikace větší negativní dopad. Podobně jako u multimédií, nejlepší způsob, jak zvýšit výkonnost, je vynechat to, co není opravdu nutné.

Mezi hlavní praktiky optimalizace Javascriptu patří (Mozilla, 2021):

- Snížení množství potřebného kódu – použití knihoven a jejich funkci může zlepšit vývojářskou zkušenost. Prohlížeč si knihovnu stáhne celou i přesto, že se použije pouze jedna funkce, a tím se zvýší množství stažených dat. Proto je nutné zvážit, zda je knihovna zapotřebí či nikoliv.

- Odstranění nepoužitého kódu

- Rozdělení kódu do menších souborů – Technice dělení kódu do menších souborů se nazývá code-splitting. Kód se dělí do kritických a nekritických částí. Pro rozdělení je možné použít nástroje pro zpracování souborů, jako je např. Webpack.

- Optimalizace menších souborů

o Minifikace – Minifikace je proces odstranění nepotřebných nebo nadbytečných dat, aniž by to ovlivnilo způsob, jakým prohlížeč soubory zpracovává. Může zahrnovat odstranění komentářů, prázdných míst a nepoužitého kódu, zkrácení názvů funkcí a proměnných.

o Komprese souborů – Ke kompresi souborů se většinou používá Gzipping či Brotli. Komprese dokáže snížit velikost souboru až o 95 % a je doporučeno používat kompresi v každém případě.

1.4.6 History API

Přístup k historii relací prohlížeče je poskytován prostřednictvím objektu history. Objekt umožňuje procházení vpřed a zpět v historií uživatele a manipulovat s obsahem history stacku5. History API také umožňuje to, aby každá webová stránka měla unikátní URL adresu (Mozilla, 2021).

History API také dovoluje webovým aplikacím explicitně nastavit výchozí chování scrollování při přechodu na předešlou stránku. Tohoto chování je docíleno pomocí scrollRestoration (Mozilla, 2021).

window.onpopstate = function(event) {

alert(`location: ${document.location}, state:${JSON.stringify(event.state)}`) }

history.pushState({page: 1}, "title 1", "?page=1") history.pushState({page: 2}, "title 2", "?page=2") history.replaceState({page: 3}, "title 3", "?page=3") history.back()

history.back() history.go(2)

Výpis zdrojového kódu 6: History API (Mozilla, 2021)

1.4.7 Indexace ve webových vyhledávačích

Indexace javascriptových aplikací funguje v každém vyhledávači odlišně. Proces indexace bude popsán pouze pro nejvyužívanější vyhledávač od společnosti Google.

K indexaci používá tzv. Googlebot. Googlebot zpracovává javascriptové aplikace ve třech fázích (Google, 2021):

1) Crawling (prohledávání) 2) Rendering (vykreslování) 3) Indexace

Proces procházení začíná se seznamem webových adres z minulých vyhledávání a mapami webů, které byli poskytnuty jejich vlastníky. Prohledávač (crawler) zkontroluje soubor robots.txt, kde si ověří oprávnění k prohledávání. Dále Googlebot načte všechny povolené stránky k vykreslování a dochází k vyhodnocení důležitých parametrů – od klíčových slov až po stáří webové stránky. Vše se následně zaznamená do indexu vyhledávání.

Procházení webových stránek vytvořených v javascriptu je problematické, jelikož počáteční HTML soubor neobsahuje v HTTP hlavičce skutečný obsah stránek. Tento problém se dá

5 Stack, nebo také zásobník, je obecná datová struktura, která se používá jako uložiště pro dočasná data (Wikipedia, 2021)

vyřešit pomocí tzv. server side rendering (dále jen SSR), což je technika, ve které se stránky vykreslují na serverové části. Server dále vykreslenou stránku pošle ve formě odpovědi klientovi (Google, 2021).

Framework React obsahuje balíček react-dom, který umožňuje na serveru vygenerovat textovou podobu toho, co se má vykreslit na klientské části (Facebook, 2021).

Metadata Schema.org

Schema.org je slovník, který slouží k popisu strukturovaných dat. Strukturovaná data jsou standardizovaný formát pro poskytování informací o stránce a pro třídění obsahu stránky.

Vyhledávání Google také strukturovaná data používá k aktivaci zvláštních funkcí a vylepšení výsledků vyhledávání. Popis dat by měl být ve formátu JSON-LD (Google, 2021).

<div itemscope itemtype ="https://schema.org/Movie">

<h1 itemprop="name">Avatar</h1>

<div itemprop="director" itemscope itemtype="https://schema.org/Person">

Director: <span itemprop="name">James Cameron</span>

(born <span itemprop="birthDate">August 16, 1954</span>) </div>

<span itemprop="genre">Science fiction</span>

<a href="../movies/avatar-theatrical-trailer.html"

itemprop="trailer">Trailer</a>

</div>

Výpis zdrojového kódu 7: Metadata Schema.org (Google, 2021) Kanonické URL

Kanonická adresa URL je adresa URL nejlepší reprezentativní stránky ze skupiny duplicitních stránek podle vyhledávače. Jestliže existují např. dvě adresy URL pro jednu stránku (priklad.cz?priklad=1234 a priklad.cz/priklady/1234), vyhledávač jednu vybere jako kanonickou. Podobně platí, že pokud existuje více stránek, které jsou téměř totožné, může je vyhledávač seskupit. Jedná se např. o stránky, které se liší pouze řazením nebo filtrováním obsahu, třeba podle ceny nebo barvy položky (Google, 2021).

Vyhledávačům je možné explicitně sdělit, která URL je kanonická. Zapisuje se do hlavičky stránky do tagu <link> s atributem rel=”canonical”.

1.4.8 Metadata sociálních sítí

Metadata sociálních sítí

Informace, které se při sdílení odkazu na nějaký web objeví na sociálních sítích nejsou načítány náhodně. Obrázek, název článku i doplňkový text lze ovlivnit pomocí protokolu Open Graph. Jedná se o speciální meta značky v HTML souboru stránky. Je možné upravit URL, titulek, popisek, typ obsahu a obrázek (OGP, 2021).

<head>

<meta property="og:title" content="Titulek" />

<meta property="og:description" content="Popisek"/>

<meta property="og:type" content="Typ obsahu" />

<meta property="og:image" content="obrázek.webp" />

<meta property="og:url" content="https://www.url.cz" />

</head>

Výpis zdrojového kódu 8: Příklad umístění značek Open Graph v hlavičce HTML (zdroj: autor)

1.4.9 Responzivní web design

Aplikace s responzivním web designem se automaticky přizpůsobuje různým rozlišením a

Aplikace s responzivním web designem se automaticky přizpůsobuje různým rozlišením a