Výkon webových aplikací

4IZ278 – Webové aplikace

Jirka Kosek

Poslední modifikace: $Date: 2017/04/20 20:06:10 $

Úvod

  • stránky, které se pomalují načítají, a aplikace, která má pomalou odezvu, odradí uživatele

  • reakce na akci uživatele do 1 sekundy – přijatelné

  • reakce na akci uživatele trvá déle než sekundu – uživatel začne myslet na něco jiného

  • reakce na akci uživatele trvá více než 10 sekund – uživatel obvykle odchází

  • rychlost načítání a reakce aplikace záleží na mnoha faktorech

    • rychlost a latence internetového připojení

    • rychlost zpracování požadavku pomocí serveru

    • rychlost vykreslení stránky

    • počet a celkový objem požadavků nutných pro obsloužení akce uživatele

Zrychlení přenosu

Zmenšení objemu přenášených dat

  • nepřenášíme to, co není potřeba (např. lazy-loading obrázků do karuselu)

  • minifikace HTML/CSS/JS kódu

  • komprimace přenášených dat (GZIP)

  • obrázky SVG ukládat jako komprimované (.svgz)

  • optimalizace obrázků

    • vhodný formát (bitmapa/vektor)

    • jednoduché obrázky lze někdy nahradit CSS efekty

Snížení počtu požadavků

  • kompilace několika CSS a JS souborů do jednoho

  • nenačítání zbytečností ze serverů třetích stran

  • obrázkové sprity (více obrázků v jednom, správné zobrazení zajistí ořez pomocí CSS)

  • menší obrázky lze vložit přímo do HTML stránky pomocí data: URL schématu

Další možnosti

  • načítání objektů z více domén najednou (prohlížeče respektují maximální počet paralelních požadavků na jednu doménu)

  • ukládání „statických“ částí webu do vyrovnávací paměti prohlížeče

  • prefetch – nápověda pro prohlížeč, na co se má připravit

    <link rel="prefetch" href="http://www.example.com/">
    <link rel="dns-prefetch" href="http://example.com/">
    <link rel="prerender" href="/page/to/prerender">
  • minimalizace přenášených hlaviček HTTP (velikost cookies, zbytečné hlavičky, …)

HTTP/2

  • nová verze protokolu HTTP odstraňující zejména výkonostní problémy předchozích verzí

  • protokol je binární, ne textový

  • multiplexing – po jednom TCP spojení se paralelně a asynchronně přenáší více objektů

  • server push – server může poslat do prohlížeče data dříve než si je prohlížeč vyžádá

  • komprimace hlaviček

  • většina „optimalizačních technik“ pro HTTP/1.x nedává při použití HTTP/2 smysl

Vykreslení a odezva stránky

Základní pravidla

  • snaha o co nejjednodušší HTML/CSS/JS kód

  • odkazy na styly CSS by měly být na začátku stránky – pro další vykreslování je potřeba mít k dispozici DOM a CSSOM

  • dokud se nestáhne CSS, nemůže se začít s vykreslováním stránky

  • JavaScript načítat až na konci stránky

  • používat <script src="…" async>, které dovolí asynchronní načtení skriptu (neblokuje vytváření DOM)

  • nepoužívat inline <script>, protože blokuje vytváření DOM

JavaScript Event loop

  • události, které musí prohlížeč obsloužit, se přidávají do fronty

  • během obsluhy jedné události se nedělá nic jiného

  • pokud je obsluha dlouhá, zablokuje to zbytek aplikace, UI nereaguje, …

  • většina JS API je proto asynchronních, aby k blokování docházelo co nejméně

  • dlouhé výpočty je tak potřeba provádět buď pomocí WebWorkers nebo rozdělit na menší úlohy a volat postupně pomocí setTimeout()/setInterval()

Zpracování požadavku na serveru

Úzké hrdlo

  • vždy je potřeba nejprve zjistit, co přesně vyřízení požadavku zdržuje

  • v mnoha případech je největší zpoždění způsobeno čekáním na výsledky dotazu do databáze

    • zvážit výběr databázové technologie

    • správná konfigurace databáze (vyhledávací indexy, …)

    • minimalizace dotazů do databáze

    • ukládání výsledků do vyrovnávací paměti

Příklad 1. Využití vyrovnávací paměti phpFastCache
<?php
// Načtení knihovny
use phpFastCache\CacheManager;
require_once("src/phpFastCache/phpFastCache.php");
$cache = CacheManager::Files();

// pokus o načtení stránky o produktu z vyrovnávací paměti
$products = $cache->get("product_page");

if(is_null($products)) {
    // pokud stránka ve vyrovnávací paměti není nebo je stará, načteme ji z databáze
    $products = … načtení hodnot z databáze (pomalé) …;
    // uložení stránky do vyrovnávací paměti
    $cache->set("product_page",$products , 600);
}

// vrácení stránky, ve většině případů z vyrovnávací paměti
echo $products;

Další zdroje informací

Povinná četba

Nástroje pro „minifikaci“