Mobilizujeme web v HTML5

Vývoj pro mobilní zařízení je v současnosti žhavým tématem. Letos poprvé překročily počty prodaných smartphonů prodeje klasických PC. Stále víc uživatelů používá k procházení webu mobilní zařízení, což klade nároky na vývojáře, kteří jsou nuceni své stránky upravit tak, aby byly použitelné i na těchto zařízeních.

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

Článek je překladem článku „Mobifying“ Your HTML5 Site z webu html5rocks.com, jehož autorem je Eric Bidelman, Google.

Pro významnou část vývojářů jsou mobilní weby stále velkou neznámou. Velké množství lidí má weby, které zanedbávají uživatele s mobilními zařízeními; weby navržené pro prohlížení na desktopu, které na mobilních zařízeních vypadají hrozně. Tento web (html5rocks.com) není výjimkou. Při jeho startu jsme věnovali mobilním zařízením minimální péči.

Vytvoření mobile-friendly verze html5rocks.com

Zajímavým příkladem by mohlo být vzít html5rocks.com (tedy existující web v HTML5) a rozšířit jej o mobilní verzi. Hlavním záměrem bylo věnovat tomu minimum práce. Cílem nebylo vytvořit kompletně nový web a udržovat dvě verze; to jsme si zkusili dřív a je to obrovská ztráta času. Máme definovanou strukturu webu (markup), máme vzhled (CSS) a máme nějaké funkce řešené pomocí JS. Tedy jsme ve stejné situaci, v jaké je velké množství webů.

V tomto článku popíšeme, jak jsme vytvářeli mobilní verzi webu html5rocks.com, optimalizovanou pro zařízení s Androidem a iOS. Načtěte si html5rocks.com na takovém zařízení, a zjistíte, v čem je rozdíl. Nejsou žádné redirekty na m.html5rocks.com nebo jiné podivnosti tohoto typu. Přistupujete na stejnou stránku jako desktopy… jen s tou výhodou, že dostáváte něco, co vypadá dobře a funguje i na mobilním zařízení.

     

Desktopová verze stránek (vlevo) a mobilní vzhled (vpravo)

CSS Media Queries

HTML4 a CSS2 začaly s podporou stylů podle zařízení. Například:

<link rel="stylesheet" media="print" href="printer.css">

definovalo styl pro tiskárny a poskytovalo specifické stylování pro obsah stránky při tisku. CSS3 tuto ideu dále rozpracovává a vylepšuje o tzv. media queries. Media queries rozšiřuje použití „typů médií“ tím, že umožňuje mnohem přesnější cílení. Výsledkem je, že formu prezentace obsahu můžeme velmi přesně přizpůsobit konkrétnímu zařízení bez toho, abychom zasahovali do obsahu samotného. Pokud tedy máte stránky hotové, je to perfektní cesta.

Můžete použít media queries v atributu media u externího stylopisu a cílit na konkrétní šířku zobrazovací plochy, zařízení, orientaci apod. Plný seznam naleznete ve W3C media query specification.

Cílení na velikost displeje

V následujícím příkladu použijeme stylopis phone.css, který bude aplikovaný na prohlížeče, které o sobě prohlašují, že jsou „handheld“, a na zařízení s displejem užším než 320px.

<link rel="stylesheet" media="handheld, only screen and (max-device-width: 320px)" href="phone.css">

Pomocí prefixu „ only“ zajistíme, že prohlížeče, které nepodporují CSS3, budou pravidlo ignorovat.

Další stylopis bude použit pro zařízení se šířkou displeje mezi 641px a 800px:

<link rel="stylesheet" media="only screen and (min-width: 641px) and (max-width: 800px)" href="ipad.css">

Media queries se mohou rovněž objevit v tagu <style>. Následující pravidlo bude platné pro všechna ( all) média, která jsou „na výšku“ (portrait):

<style>
  @media only all and (orientation: portrait) { ... }
</style>

media=„handheld“

Musíme se na chvíli zastavit u media="handheld". Skutečnost je taková, že Android a iOS media="handheld" ignorují. Vysvětlují to tím, že by uživatelé přišli o mnohé pokročilé funkce, které jsou k dispozici pro media="screen", protože vývojáři neradi udržují „očesané“ verze pro media="handheld". Takže v rámci hesla „Plný web!“ většina moderních smartfonů stylopisy pro handheld zařízení zkrátka ignorují.

Bylo by skvělé použít tuto vlastnost pro cílení stylopisu na mobilní zařízení, ale problém je v tom, že si každý prohlížeč toto pravidlo vykládá jinak:

  • Některé načítají pouze styl pro handheld.
  • Některé načítají styly pro handheld, pokud jsou, jinak používají styl pro „screen“.
  • Některé načítají obojí.
  • Některé handheld ignorují a načítají pouze screen.

Opera Mini pravidlo media="handheld" neignoruje. Pomocí jednoduchého triku lze donutit i Windows Mobile, aby rozpoznal media="handheld"  – uvedeme „screen“ s velkým počátečním písmenem:

<!-- media="handheld" trik pro Windows Mobile -->
<link rel="stylesheet" href="screen.css" media="Screen">
<link rel="stylesheet" href="mobile.css" media="handheld">

Jak html5rocks používá media queries

Mobilní verze html5rocks.com používá media queries intenzivně. Díky nim můžeme přiohnout vzhled webu bez toho, abychom museli nějak významně zasahovat do šablon v Djangu, což je výhoda k nezaplacení! Navíc je jejich podpora v prohlížečích poměrně dobrá.

V <head>  u každé stránky najdete následující stylopisy:

<link rel="stylesheet" media="all" href="/static/css/base.min.css" />
<link rel="stylesheet" media="only screen and (max-width: 800px)" href="/static/css/mobile.min.css" />

base.css definuje vždy hlavní vzhled stránky html5rocks.com, ale pro zařízení s šířkou displeje pod 800 px nyní aplikujeme nový styl (mobile.css ). Jeho media query pokrývá smartfony (~320px) i iPad (~768px). V tomto stylu přidáváme a přepisujeme pravidla z  base.css (pokud je potřeba), aby web vypadal dobře i na mobilech.

Změny vzhledu v mobile.css  zahrnují:

  • Zmenšení okrajů a mezer. Na malém displeji je prostor velmi cenný!
  • Odstraňuje efekty :hover. Viděli jste je někdy na zařízení s dotykovým displejem?
  • Mění layout na jednosloupcový (podrobnosti později)
  • Odstraňuje box-shadow okolo hlavního kontejnerového div-u. Stíny u velkých boxů snižují výkon při zobrazování.
  • Používá box model box-ordinal-group ke změně pořadí sekcí na domovské stránce. V desktopové verzi je např. sekce „LEARN BY MAJOR HTML5 FEATURE GROUPS“ na úvodní stránce umístěná před sekcí „TUTORIALS“, ale v mobilní je tomu opačně. Takové řazení dává na mobilu lepší smysl a přitom nevyžadovalo změny v HTML.
  • Odstraňuje změny opacity. Změna průhlednosti na mobilním zařízení je poměrně náročná záležitost.

Mobilní meta tagy

WebKit pro mobily podporuje pár zajímavých věcí, které zlepšují uživatelský prožitek při práci s takovým webem.

Nastavení viewportu

První meta tag (a zároveň ten, který budete používat asi nejvíc) je nastavení viewportu. Toto nastavení říká prohlížeči, jak má rozmístit obsah na displej a informuje prohlížeč o tom, že stránka je optimalizovaná pro mobily. Například:

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">

říká prohlížeči, aby nastavil viewport na šířku zařízení a zachoval měřítko. Zároveň povoluje zoom, tedy něco, co může být žádoucí na webu, ale ne v aplikaci. Můžeme tomu zabránit pomocí user-scalable=no nebo omezit zoom na určitou hodnotu:

<meta name=viewport content="width=device-width, initial-scale=1.0, minimum-scale=0.5 maximum-scale=1.0">

Poznámka: width může mít zadanou hodnotu i v pixelech. Nastavení width=320 bude mít stejný efekt jako width=device-width na iPhone a několika dalších smartphonech. Pamatujte si, že ne všechny telefony mají přesně tento rozměr, takže je lepší zadat device-width a nechat prohlížeč, aby se postaral o zbytek.

Android rozšiřuje tento meta tag a umožňuje vývojáři specifikovat, pro jaké rozlišení je web určen:

<meta name="viewport" content="target-densitydpi=device-dpi">

Možné hodnoty pro target-densitydpi jsou device-dpi, high-dpi, medium-dpilow-dpi.

Pokud chcete modifikovat web pro různá DPI, použijte media query  -webkit-device-pixel-ratio nebo vlastnost window.devicePixelRatio v JavaScriptu a nastavte target-densitydpi na device-dpi. Tímto nastavením zajistíte, že Android nebude zkoušet měnit rozlišení a nechá veškerá nastavení v tomto směru na vás, resp. na CSS a JavaScriptu.

Další informace viz WebView documentation pro Androidy.

Prohlížení na celou stránku

Další dva meta tagy jsou specifické pro iOS. apple-mobile-web-app-capable a apple-mobile-web-app-status-bar-style vykreslí stránku přes celý displej stejně jako se vykreslují aplikace a zakryje status bar:

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

Další informace viz Safari reference documentation (a také článek Píšeme aplikaci pro iPad – pozn.překl.)

Ikonky na plochu

iOS a Android rovněž akceptují rel="apple-touch-icon" (iOS) a rel="apple-touch-icon-precomposed" (Android) u tagu link. Pomocí tohoto nastavení můžeme specifikovat ikonku, která bude použitá, když si váš web uživatel umístí na plochu:

<link rel="apple-touch-icon" href="/static/images/identity/HTML5_Badge_64.png" />
<link rel="apple-touch-icon-precomposed" href="/static/images/identity/HTML5_Badge_64.png" />

Jak mobilní meta tagy používá html5rocks

Když to dáme vše dohromady, získáme toto:

<head>
  ...
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />

  <link rel="apple-touch-icon"
        href="/static/images/identity/HTML5_Badge_64.png" />
  <link rel="apple-touch-icon-precomposed"
        href="/static/images/identity/HTML5_Badge_64.png" />
  ...
</head>

Vertikální layout

Na malých obrazovkách je mnohem přirozenější scrollovat vertikálně než horizontálně. Proto mobilní weby preferují jednosloupcový vertikální layout. Na html5rocks jsme takový layout vytvořili pomocí CSS3 media queries. Opět, bez zásahu do HTML kódu.

 Jednosloupcový vertikální layout

Optimalizace pro mobily

Většina optimalizací, které jsme dělali, jsou věci, které byste měli udělat v první řadě. Věci jako snížení počtu požadavků, komprese CSS/JS, gzip dat a minimalizace počtu operací s DOMem. Tyto techniky patří k základním dobrým zvykům, ale jakmile je web jednou venku, často jej přehlížíme.

Automatické skrývání adresního řádku

U prohlížení webu na mobilních zařízeních je ve srovnání s desktopem velmi důležité šetření plochou obrazovky. Pokud chcete uživatelský prožitek zhoršit, nechte uživatelům zobrazený ošklivý velký adresní řádek i ve chvíli, kdy je stránka načtená.

Snadný způsob, jak schovat tento řádek, je po načtení posunout stránku pomocí JavaScriptu. I scrollování o jeden pixel naznačí prohlížeči, že je načase schovat adresní řádek. Takže jsme na html5rocks napsali handler pro událost onload, který scrolluje stránku o jeden pixel vertikálně:

  Adresní řádek zabírá drahocennou plochu

{% if is_mobile % }
  // Hides mobile browser's address bar when page is done loading.
  window.addEventListener('load', function(e) {
    setTimeout(function() { window.scrollTo(0, 1); }, 1);
  }, false);
{% endif % }

Tento skript je použit pouze pro mobilní zařízení, na desktopu není potřeba (zde je rozdíl v kódu pro mobilní zařízení a pro desktop. – pozn.překl.)

Menší počet síťových požadavků znamená šetření přenosového pásma

Je známý fakt, že snížení počtu HTTP požadavků může výrazně zvýšit výkon webové stránky. Mobilní zařízení mívají omezený počet současně otevřených spojení ještě výrazněji než desktopové, takže snížení počtu požadavků se zde projeví ještě výrazněji. Navíc se zde každý ušetřený bajt počítá, protože přenesená data jsou na mobilech často limitována. Neutrácejte svým uživatelům peníze!

Na html5rocks.com jsme použili pro ušetření přenosového pásma následující postupy::

  • Odstranili jsme iframy – iframy jsou pomalé! Největším zdrojem zpomalení našeho webu byly „sdílecí“ widgety od dalších služeb (Buzz, Google Friend Connect, Twitter, Facebook) na stránkách s tutoriály. Jejich API jsou vložena přes tagy <script> a vytvářejí iframy, co výrazně zpomalují načítání webu. Proto jsme je z mobilní verze odstranili.
  • display:none  – V některých případech jsme obsah, co se nám nehodil na mobilní verzi, prostě skryli. Příkladem budiž čtyři boxy na vršku úvodní stránky:

    V mobilní verzi nejsou. Je důležité si uvědomit, že mobilní prohlížeč posílá požadavek na tyto ikonky, i když je celý kontejner schovaný pomocí  display:none. Proto nestačilo prostě schovat tato tlačítka, nejen proto, že plýtvají přenesenými daty, ale taky proto, že uživatel nemá z tohoto plýtvání naprosto žádný užitek! Výsledkem bylo vytvoření proměnné „is_mobile“ v našich šablonách pro Django, pomocí které jsme vynechávali podobné části na stránkách, určených pro mobilní zařízení. Když uživatel přistupuje z mobilu, tlačítka jsou pryč.

  • Application Cache – nejen že nabízí podporu prohlížení offline, ale taky zrychluje načítání stránky.
  • Komprese CSS/JS – použili jsme YUI compressor namísto Closure compileru, hlavně proto, že obslouží CSS i JS. Jeden problém, na který jsme narazili, byl, že inline media queries, které se objevily v CSS souborech, YUI compressor 2.4.2 zničil (viz bugreport). YUI Compressor 2.4.4+ tento problém už nemá.
  • Použili jsme CSS sprity tam, kde to bylo možné.
  • Obrázky jsme komprimovali pomocí pngcrush.
  • Pro malé obrázky jsme použili dataURI. Base64 je sice o cca 30 procent větší, ale sníží to počet síťových požadavků.
  • Google Custom Search načítáme pomocí vlastního skriptu namísto dynamického načítání přes google.load(). Opět ušetřený požadavek.
    <script src="//www.google.com/jsapi?autoload={"modules":[{"name":"search","version":"1"}]}"></script>
  • Náš zvýrazňovač kódu a Modernizr byly vkládány do každé stránky, i v případě, že nebyly použité. Modernizr je skvělý, ale dělá při každém načtení spoustu testů. Některé z těchto testů používají náročné modifikace DOMu a zpomalují načítání stránek. Teď vkládáme tyto knihovny pouze tam, kde jsou použité. Mínus dva požadavky.

Další úpravy pro zvýšení výkonu:

  • Kde to šlo, tam jsme přesunuli JS na konec stránky.
  • Odstranili jsme vložené tagy <style>.
  • Cachujeme prohledávání DOMu a minimalizujeme operace s ním – pokaždé, když sáhnete do DOMu, udělá prohlížeč reflow. Reflow je na mobilních zařízeních velmi náročný.
  • Zdržující skripty jsme přesunuli na server. Například takové zjišťování, jaká část navigace má být na stránce vidět:
    var lis = document.querySelectorAll('header nav li');
    var i = lis.length;
    while (i--) {
      var a = lis[i].querySelector('a');
      var section = a.getAttribute("data-section");
      if (new RegExp(section).test(document.location.href)) {
        a.className = 'current';
      }
    }
  • Elementy s pevnou šířkou byly nadefinovány s šířkou width:100% nebo  width:auto.

Application Cache

Mobilní verze html5rocks používá Application Cache ke zvýšení rychlosti načítání a k tomu, aby uživatelé mohli číst obsah i offline. (Viz článek o AppCache na Zdrojáku – pozn. překl.)

Když používáte AppCache, je velmi důležité, abyste si necachovali manifest (buď nastavením cache hlaviček nebo explicitně v manifestu). Jakmile bude manifest součástí cache, stane se ladění noční můrou. iOS i Android neposkytují snadný způsob, jak obsah této cache zahodit, jako mají desktopové prohlížeče.

Proto jsme v první řadě nastavili App Engine tak, aby nikdy necachoval manifest:

- url: /(.*.(appcache|manifest))
  static_files: 1
  mime_type: text/cache-manifest
  upload: (.*.(appcache|manifest))
  expiration: "0s"

Za druhé jsme použili JS API k tomu, abychom informovali uživatele o tom, že se stáhla nová verze webu a vyzvali ho ke znovunačtení:

window.applicationCache.addEventListener('updateready', function(e) {
  if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    window.applicationCache.swapCache();
    if (confirm('A new version of this site is available. Load it?')) {
      window.location.reload();
    }
  }
}, false);

Udržujte svůj manifest jednoduchý, ušetříte tím síťový provoz. Tedy jinými slovy: necachujte vše, co na webu máte. Uložte jen důležité obrázky, CSS a JavaScript. To poslední, co chcete, je donutit mobilní prohlížeč stahovat obrovské množství dat při každé změně appcache. Místo toho mějte na paměti, že prohlížeč implicitně cachuje HTML stránky ve chvíli, kdy je uživatel navštíví (a ty obsahují atribut  <html manifest="...">).

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: 3

Přehled komentářů

Tomaso Mobify?
Petr_ iOS ikonka
Jakub Vrána Posunutí při onload
Zdroj: https://www.zdrojak.cz/?p=3468