Zobrazují se příspěvky se štítkemjavascript. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemjavascript. Zobrazit všechny příspěvky

středa 27. srpna 2008

Na Web přijde JavaScript s více vlákny

Jednovláknovost JavaScriptu ve webových prohlížečích skýtá jistá omezení. Přitom v jednom vlákně neběží pouze skript jedné stránky, ale pokud se stránka skládá z více rámů nebo otevřela vyskakovací okno, pak všechny jejich skripty poběží v jednom jediném vláknu. Přitom se mezi sebou střídají pro obsluhování jednotlivých událostí. Celé to silně připomíná starý kooperativní multitasking. HTML5 se snaží dát zpracování události jistý řád a navíc umožní použití více vláken.

Event loops

Princip a pořadí obsluhování událostí je v HTML5 specifikován pomocí Event loops. Event loops zavádí fronty úloh, do kterých se ukládají např. události uživatelského rozhraní, události parseru nebo síťového rozhraní. Specifikace popisuje, v jakém pořadí mají být dále zpracovávány.

Ačkoliv jsou webové prohlížeče s námi již řadu let, jedná se, pokud vím, o historicky první specifikaci tohoto druhu. Dosud se prohlížeče mohly chovat každý jinak, což také i víceméně dělaly (přečtěte si loňskou diskusi u Misantropa). Ve výsledku tak zmizí další rozdíl způsobující, že webová aplikace v jednom prohlížeči běžela v pořádku a ve druhém způsobila nepochopitelný problém.

Přichází vlákna

Mnohem zajímavější je ovšem zavedení vláken do skriptování webových prohlížečů. Je jim věnována zvláštní specifikace Web Workers (zkráceně WW), čítá asi 30 stran a v budoucnu se pravděpodobně stane součástí velké specifikace HTML5.

Web Workers navíc ke stávajícímu vykonávání JavaScriptu definují pracovní vlákna, která běží na pozadí (mimo interakci s uživatelským rozhraním prohlížeče) a mají sloužit ke zpracování výkonnostně nebo časově náročnějších činností. Jelikož neblokují uživatelské rozhraní, nebudou omezovány, mohou tedy bez přestání běžet desítky minut nebo i hodin (průběh stávajících skriptů totiž bývá omezen např. na desítky vteřin ve Firefoxu, což komplikuje vykonávání náročnějších úloh).

Ukažme si jednochuché použití pracovního vlákna. Všimněte si, že pracovní vlákno s vláknem uživatelského rozhraní komunikuje prostřednictvím zpráv (událost message) - online verze:

<script>
var worker = new Worker('worker.js');
worker.onmessage = function(event){ document.getElementById('result').innerHTML = event.message;
};
</script>


Pracovní vlákno může získávat data pro svou práci pomocí událostí, database storage nebo pomocí síťové komunikace (komunikace s webovými servery pomocí AJAXu nebo nového rozhraní Web Sockets - o tom jindy). Přímý přístup k uživatelskému rozhraní nebo k zobrazované webové stránce pracovní vlákno NEMÁ.

Pracovní vlákno má navíc některé metody, např. importScripts(url1, url2...), která zajístí načtení dalších skriptů (potřebná metoda, nemůžeme totiž použít běžnou značku script, jelikož nemáme přístup k HTML dokumentu).

Kromě konstruktoru Worker existuje kontruktor SharedWorker, který založí pracovní vlákno, jenž má být sdíleno více rámy (nebo okny) aplikace.

Celá specifikace je v počátečním stádiu a výrobci prohlížečů se k ní postupně vyjadřují. Troufnu si odhadovat, že ačkoliv přináší velké změny, nakonec se do prohlížečů dostane, byť je pravděpodobné, že před tím ještě projde úpravami. S ohledem na to, že JavaScript je v prohlížečích stále rychlejší, začíná být srovnáván nejen s dalšími skriptovacími jazyky, ale třeba s céčkem, začíná být představa složitějších skriptů běžících na pozadí reálná.

středa 16. července 2008

PersistJS pro překonání cookies

PersistJS je JavaScriptová knihovna uchovávající (perzistentí) data na straně klienta. K tomu používá všechny možné prostředky od úložišť HTML5, přes Google Gears po Flash.

Knihovna nabízí jednotné rozhraní, programátor tedy nemusí řešit, jaké úložiště se ve výsledku použije, zda běží v prohlížeči s podporou HTML5 nebo zda se prostě použije Flash. Data se ukládají v jednoduché formě klíč + hodnota:
// create a new client-side data store
var store = new Persist.Store('MyDataStore');

// pretend data
var data = "pretend this is really long data that won't fit in a cookie";

// save data in store
store.set('saved_data', data);

Autorem knihovny je Paul Duncan. Verze 0.1 je první vývojovou verzí a autor přiznává, že se v ní ještě mohou objevovat chyby.

Knihovny jako je PersistJS pomohou elegantně překlenout období, ve kterém novinky HTML5 budou v některých prohlížečích podporovány a v jiných nikoliv. Pokud cookies pro vaše aplikace nestačí, doporučuji vývoj PersistJS sledovat.

pondělí 21. dubna 2008

HTML5 a spouštění skriptů

Specifikace HTML5 se zaměřuje i na spouštění skriptů ve stránce. Zmíním dvě zajímavosti týkající se spouštění skriptů.

Atributy defer a async

V HTML4 byl u značky script definován atribut defer, který umožňuje prohlížeči pokračovat ve zpracovávání dokumentu, aniž by musel čekat na proběhnutí daného skriptu (skript ovšem nesmí měnit stránku během načítání, výsledek by pak byl nepredikovatelný). Specifikace bohužel již nijak neříká, kdy přesně má být skript spuštěn.

Atribut defer zatím implementuje pouze Internet Explorer, ale tato implementace je považován za "nekonzistentní" (nekonzistentní uvádím v uvozovkách, jelikož specifikace chování nepopisuje, nelze žádné chování označit za správné či nikoliv).

Pro vyřešení situace HTML5 u značky script zavádí dva atributy defer a async. Oba slouží podobnému účelu, ovšem zatímco:
  • skript označený jako async bude spuštěn, jakmile je dostupný (Zpracování stránky se u značky skript nezastaví, pokračuje dále a skript je spuštěn, jakmile se načte, tedy v nepredikovatelnou dobu.)
  • skript označený jako defer bude spuštěn až v momentě, kdy se dokončí zpracování (parsování) celé stránky (Tedy v predikovatelnou a vždy stejnou dobu. Specifikace hovoří o dokončení parsování stránky, prohlížeč tedy v tu dobu může stále ještě načítat další zdroje, např. obrázky.)
Autoři webových aplikací by mohli správným použitím těchto atributů načítání stránek urychlit. Za zmínku stojí, že vývojáři WebKitu jsou trochu jiného názoru. Místo, aby vývojáři do svých stránek museli vkládat jeden atribut async za druhým, snaží se problém řešit i na straně prohlížeče.

Událost dokončení načítání stránky

Druhá zajímavost se týká událostí načtení stránky. Klasická událost load totiž vždy nestačí, ta je totiž vyvolána až v momentě kompletního načtení celé stránky. Pokud webová stránka obsahuje veliké obrázky, čeká událost load na jejich načtení.

To je často v rozporu s požadavky uživatelů i vývojářů (když se vám načítá stránka s galerií, je žádoucí, aby její vrchní část fungovala nezávisle na spodní části, do které se stále ještě načítají další fotografie).

Jednoduché řešení fungující ve všech prohlížečích neexistuje, a proto byla vymyšlena celá řada triků, jak toho docílit.

HTML5 specifikuje událost DOMContentLoaded, která je vyvolána právě v kýženém momentu - tedy hned po zpracování celé stránky. V tuto chvíli ji podporuje trojka prohlížečů S.O.F. (Safari, Opera, Firefox), v IE lze emulovat některým z odkázaných triků.

čtvrtek 27. prosince 2007

Funkce getElementsByClassName má již několik implementací

Nedávno byla oznámena implementace funkce getElementsByClassName ve WebKitu. Po její implementaci v Opeře (dle Wikipedie již v připravované verzi 9.5) a implementaci v chystaném Firefoxu 3 máme opět trojku prohlížečů S.O.F. (neboli Safe Our Fear) kompletní.

Funkce getElementsByClassName je součástí specifikace HTML5, konkrétně části rozšiřující stávající DOM2 HTML. Své popularity se dočkala zejména s rozšířením tzv. přístupu unobtrusive JavaScript, který se snaží o lepší oddělení obsahu HTML stránky od popisu jejího chování pomocí JavaScriptu, a který výběr značek podle nastavené třídy hojně používá.

Funkce getElementsByClassName zpopularizovala, když se stala součástí trendových JavaScriptových knihoven, prostřednictvím kterých ji weboví vývojáři již delší dobu používají. Není divu, že někteří po jejím začlenění do DOM už nějaký čas volali.

Jelikož nativní implementace getElementsByClassName je rychlejší než jak její stávající JavaScriptová implementace, tak její implementace pomocí XPath, bude jistě v nových verzích trendových JavaScriptových knihoven využita.

Je to další ukázka, kdy nevadí, že v některých prohlížečích není novinka HTML5 dosud implementována. (Ostatně právě s tímto přístupem začala být HTML5 specifikace vytvářena.) Weboví vývojáři používající některou knihovnu (např. prototype) budou tvořit aplikace fungující všude. Ale v prohlížečích, které mají nativní podporu getElementsByClassName, bude aplikace běhat o něco rychleji.