JavaScript patří mezi základní technologie, které používám při vývoji interaktivních webových aplikací a nástrojů běžících v prohlížeči.
Používám jej pro klientskou aplikační logiku, interakci s uživatelem, komunikaci s API, zpracování souborů, práci s API prohlížeče, dynamická rozhraní a funkcionalitu aplikačního charakteru běžící přímo v prohlížeči.
JavaScript pro mě není pouze jazyk pro přidávání efektů na webové stránky.
Je to běhová vrstva, která z dokumentu vytváří aplikaci.
Jak používám JavaScript
JavaScript používám například pro:
- interaktivní webová rozhraní,
- aplikace běžící v prohlížeči,
- komunikaci s REST API,
- lokální zpracování souborů,
- dynamický obsah,
- logiku formulářů,
- validaci na straně klienta,
- úložiště v prohlížeči,
- zpracování na pozadí,
- multimediální nástroje,
- vizualizaci dat,
- simulační logiku,
- frontendovou funkcionalitu ve WordPressu.
Nativní možnosti prohlížeče využívám všude tam, kde poskytují čisté a vhodné řešení, a frameworky přidávám pouze tehdy, když řeší skutečný architektonický problém.
JavaScript v prohlížeči
Prohlížeč je plnohodnotná aplikační platforma.
JavaScript může pracovat s:
- DOMem,
- soubory,
- zvukem,
- grafikou,
- úložišti,
- síťovou komunikací,
- workery,
- WebAssembly,
- funkcemi zařízení.
To znamená, že mnoho aplikací, které dříve vyžadovaly nativní desktopový software, dnes může běžet přímo v prohlížeči.
JavaScript je jazyk, který tyto možnosti koordinuje.
DOM
Document Object Model představuje strukturu webové stránky.
JavaScript používám k tomu, abych:
- četl prvky,
- vytvářel prvky,
- aktualizoval obsah,
- měnil atributy,
- reagoval na interakci uživatele.
Vyhýbám se zbytečným manipulacím s DOMem.
DOM je velmi výkonný, ale časté nebo špatně strukturované aktualizace mohou zhoršit udržovatelnost aplikace a zpomalit vykreslování.
Událostmi řízené programování
Aplikace v prohlížeči jsou řízené událostmi.
JavaScript reaguje například na:
- kliknutí,
- vstup z klávesnice,
- výběr souboru,
- odeslání formuláře,
- drag-and-drop,
- dokončení síťové operace.
Typický průběh může vypadat například takto:
Akce uživatele
↓
Obsluha události
↓
Aplikační logika
↓
Změna stavu
↓
Aktualizace UI
Obsluhy událostí udržuji úzce zaměřené a vyhýbám se tomu, aby obsahovaly velké množství obchodní nebo aplikační logiky.
Stav aplikace
S rostoucí složitostí rozhraní v prohlížeči je stále důležitější explicitní práce se stavem.
Dávám přednost jasně definovanému stavu před tím, aby se jediným zdrojem pravdy stal samotný DOM.
Například:
stav
→ logika vykreslování
→ rozhraní
Díky tomu je snazší pochopit, v jakém stavu se podle aplikace právě nachází.
Funkce
Funkce jsou základní jednotkou znovupoužitelného chování v JavaScriptu.
Používám je k oddělení odpovědností, jako jsou:
- validace,
- transformace,
- vykreslování,
- přístup k API,
- výpočty.
Dávám přednost malým a jasně zaměřeným funkcím před rozsáhlými bloky obsahujícími nesouvisející logiku.
Moduly
U netriviálních aplikací rozděluji JavaScript do modulů.
Projekt může obsahovat samostatné moduly například pro:
- přístup k API,
- stav,
- UI,
- práci se soubory,
- pomocné funkce.
Použití import a export udržuje závislosti explicitní.
Taková struktura je výrazně lépe udržovatelná než umístění všeho do globálního prostoru.
Omezení globálního stavu
Globální proměnné mohou usnadnit napsání malého skriptu, ale u rozsáhlejší aplikace výrazně ztěžují orientaci v jejím chování.
Zbytečnému globálnímu měnitelnému stavu se vyhýbám.
Data místo toho držím uvnitř:
- modulů,
- objektů,
- funkcí,
- explicitně definovaného stavu aplikace.
Tím se snižuje množství skrytých závislostí.
ES moduly
Moderní JavaScript podporuje moduly nativně.
U vhodných aplikací tak mohu strukturovat kód bez nutnosti zavádět robustní bundler.
Prohlížeč může moduly načítat přímo například pomocí:
import { loadData } from "./api.js";
To je užitečné pro lehké aplikace, které nepotřebují rozsáhlý frontendový framework.
Asynchronní programování
Mnoho operací v prohlížeči probíhá asynchronně.
Patří mezi ně například:
- HTTP požadavky,
- operace se soubory,
- workery,
- zpracování médií.
Používám Promises a async / await, aby asynchronní workflow zůstalo čitelné.
Například:
async function loadData() {
const response = await fetch("/api/data");
return response.json();
}
Syntaxe je jednoduchá, ale zpracování chyb a přechody mezi stavy je stále potřeba navrhovat pečlivě.
Promises
Promise reprezentuje operaci, která bude dokončena později.
Používám je pro:
- síťové operace,
- API prohlížeče,
- asynchronní workflow.
Vyhýbám se hluboce vnořeným řetězcům Promise tam, kde async / await poskytuje přehlednější tok řízení.
Zpracování chyb
Asynchronní operace mohou selhat.
Počítám například se situacemi, jako jsou:
- síťové chyby,
- neplatné odpovědi,
- nedostupné soubory,
- zrušené operace.
Dávám přednost explicitním chybovým stavům před tím, aby odmítnuté Promise končily jako neošetřené chyby za běhu.
Fetch API
Fetch API používám pro HTTP komunikaci v aplikacích běžících v prohlížeči.
Typické použití zahrnuje:
- REST API,
- WordPress REST API,
- backendové služby.
HTTP odpověď kontroluji explicitně.
Dokončený fetch automaticky neznamená, že server vrátil úspěšný výsledek aplikace.
REST API
JavaScript běžně funguje jako klientská vrstva využívající REST API.
Typická architektura může vypadat například takto:
Prohlížeč
↓
JavaScript
↓
REST API
↓
Backend
Tam, kde je to praktické, odděluji síťovou komunikaci od prezentační logiky.
Díky tomu lze backend později snáze nahradit nebo upravit.
JSON
JSON je nejběžnější formát, se kterým v JavaScriptových aplikacích pracuji.
Používám jej pro:
- odpovědi API,
- konfiguraci,
- úložiště v prohlížeči,
- komunikaci s workery.
Nepředpokládám, že úspěšně naparsovaný JSON je automaticky validní.
Externí data je stále potřeba validovat za běhu.
Validace vstupů
JavaScript může uživateli poskytovat okamžitou zpětnou vazbu.
Validaci na straně klienta používám ke zlepšení použitelnosti.
Validace v prohlížeči však nepředstavuje bezpečnostní hranici.
Každá hodnota odeslaná na backend musí být znovu validována na serveru.
Formuláře
JavaScript používám k rozšíření formulářů například o:
- dynamická pole,
- validaci,
- asynchronní odesílání,
- vypočítávané hodnoty.
Kde je to praktické, zachovávám nativní chování HTML formulářů.
JavaScript by měl rozhraní vylepšovat, nikoli zbytečně nahrazovat funkce, které prohlížeč už poskytuje.
API prohlížeče
Jednou z největších předností JavaScriptu je přímý přístup k platformě prohlížeče.
Pracuji s API, jako jsou:
- File API,
- Canvas API,
- Web Audio API,
- Web Workers,
- WebGL,
- úložná API.
Tyto možnosti dovolují aplikacím v prohlížeči provádět složité lokální operace, aniž by pro každý krok potřebovaly server.
File API
JavaScript může přímo pracovat se soubory vybranými uživatelem.
Používám jej v aplikacích pracujících například s:
- obrázky,
- zvukem,
- videem,
- lokálními daty.
Oprávnění prohlížeče omezují přístup pouze na soubory, které uživatel výslovně vybere.
Blob a object URL
U generovaných nebo zpracovaných souborů používám koncepty prohlížeče, jako jsou:
Blob,- object URL.
Díky tomu lze vytvářet soubory ke stažení přímo v prohlížeči.
Object URL také uvolňuji ve chvíli, kdy už nejsou potřeba.
Canvas
Canvas poskytuje programovatelnou plochu pro 2D vykreslování.
JavaScript s Canvas používám například pro:
- zpracování obrazu,
- vizualizaci,
- vlastní vykreslování,
- interaktivní nástroje.
Pro náročnější vykreslování mohu místo něj použít WebGL.
WebGL
JavaScript tvoří aplikační vrstvu nad WebGL.
Spravuje například:
- stav scény,
- buffery,
- interakci uživatele,
- řízení vykreslování.
U složitějších 3D aplikací mohu použít Three.js jako vyšší abstrakční vrstvu nad WebGL.
Three.js
Three.js umožňuje v mnoha případech řídit 3D scény v prohlížeči pomocí JavaScriptu efektivněji než při přímé práci s WebGL.
JavaScript používám ke správě:
- objektů,
- kamer,
- interakce,
- stavu simulace,
- procedurálního obsahu.
To je užitečné pro simulace a vizualizační nástroje běžící v prohlížeči.
Web Workers
JavaScript běžně běží v hlavním vlákně prohlížeče.
Pro výpočetně náročné operace používám Web Workers.
Typická architektura může vypadat například takto:
Hlavní vlákno
→ UI
Worker
→ zpracování
Rozhraní tak zůstává responzivní i během náročnějších operací.
Komunikace s workery
Workery komunikují prostřednictvím zpráv.
Komunikaci s nimi udržuji strukturovanou a předvídatelnou.
U složitějších aplikací definuji jasné typy zpráv a datové struktury namísto posílání libovolných objektů mezi vlákny.
Přenositelné objekty
U velkých binárních bufferů může být předání vlastnictví efektivnější než kopírování dat.
To je užitečné v aplikacích zpracovávajících například:
- média,
- obrázky,
- rozsáhlé datové sady.
Omezení zbytečného kopírování paměti může výkon aplikace v prohlížeči výrazně zlepšit.
WebAssembly
JavaScript často funguje jako integrační vrstva kolem WebAssembly.
Typická architektura může vypadat například takto:
UI
↓
JavaScript
↓
WebAssembly
↓
Výpočetně náročné zpracování
Díky tomu může v prohlížeči běžet výpočetně náročný kód napsaný například v C nebo C++.
FFmpeg v prohlížeči
Při práci s FFmpeg zkompilovaným do WebAssembly JavaScript spravuje:
- vstupní soubory,
- komunikaci s workery,
- stav zpracování,
- generování výstupu.
Samotné zpracování médií provádí FFmpeg.
JavaScript kolem něj zajišťuje aplikační architekturu.
Lokálně orientované aplikace
Vytvářím aplikace v prohlížeči, které dokážou významnou část práce provádět lokálně.
To může zlepšit:
- soukromí,
- latenci,
- náklady na serverovou infrastrukturu.
Příklady zahrnují:
- konverzi souborů,
- zpracování médií,
- vizualizaci.
JavaScript koordinuje celý lokální pracovní postup.
Úložiště v prohlížeči
Úložiště prohlížeče používám v případech, kdy aplikace potřebuje trvale uchovávat lokální stav.
Podle konkrétních požadavků může jít například o:
- localStorage,
- IndexedDB.
Mechanismus ukládání volím podle velikosti a struktury dat.
localStorage
localStorage je vhodné pro malé množství jednoduchých perzistentních dat.
Příkladem mohou být:
- uživatelské preference UI,
- menší konfigurace.
Nepoužívám jej jako databázi pro velké strukturované datové sady.
IndexedDB
Pro větší objemy strukturovaných dat v prohlížeči může být vhodnější IndexedDB.
Podporuje výrazně větší množství dat a asynchronní operace.
Kde je to praktické, odděluji přístup k úložišti pomocí abstrakční vrstvy, aby aplikace nebyla příliš těsně svázaná s jedním mechanismem perzistence.
Výkon
Výkon JavaScriptu výrazně závisí na architektuře aplikace.
Sleduji zejména:
- zbytečné aktualizace DOMu,
- opakované výpočty,
- rozsáhlé smyčky,
- alokace paměti,
- síťové požadavky.
Optimalizuji na základě skutečných měření, nikoli pouze předpokladů.
Výkon hlavního vlákna
Cokoli, co blokuje hlavní vlákno, může způsobit, že rozhraní působí zamrzle.
Vyhýbám se spouštění náročných operací přímo v obsluze kliknutí nebo ve vykreslovacím kódu.
Pro náročnější úlohy zvažuji:
- Web Workers,
- WebAssembly,
- postupné zpracování.
Event loop
Pochopení event loopu JavaScriptu je důležité pro správnou práci s asynchronním chováním.
JavaScript dokáže koordinovat mnoho asynchronních operací, aniž by pro každou úlohu vytvářel samostatné vlákno.
Synchronní práce však hlavní vlákno stále blokuje.
Tento rozdíl je zásadní při diagnostice problémů s odezvou aplikace.
Časovače
Pro vhodné plánování používám časovače, jako jsou:
setTimeout,setInterval
.
Vyhýbám se časovačům s vysokou frekvencí tam, kde je vhodnější událostmi řízené řešení nebo mechanismus určený přímo pro vykreslování.
requestAnimationFrame
Pro vizuální animace používám requestAnimationFrame.
Umožňuje prohlížeči koordinovat aktualizace s vykreslováním.
Pro animace po jednotlivých snímcích je to vhodnější než používání libovolně nastavených intervalů časovače.
Správa paměti
JavaScript používá garbage collection, ale spotřeba paměti je stále důležitá.
Aplikace mohou zdroje nechtěně držet například prostřednictvím:
- event listenerů,
- referencí,
- velkých bufferů,
- object URL.
U dlouhodobě běžících aplikací v prohlížeči proto explicitně řeším životní cyklus a uvolňování zdrojů.
Odstraňování event listenerů
U dynamicky vytvářených rozhraní tam, kde je to vhodné, odstraňuji event listenery ve chvíli, kdy už nejsou potřeba.
Pomáhá to předcházet:
- únikům paměti,
- duplicitnímu zpracování událostí.
Stejná disciplína při správě životního cyklu platí také pro observery a další externí zdroje.
AbortController
AbortController používám tam, kde může být potřeba probíhající operaci zrušit.
Může jít například o:
- síťové požadavky,
- zpracování spuštěné uživatelem.
Možnost zrušení pomáhá předcházet zbytečné práci a aktualizacím založeným na již neaktuálním stavu.
Bezpečnost
JavaScript v prohlížeči běží v nedůvěryhodném klientském prostředí.
Nikdy jej nepovažuji za vhodné místo pro uchovávání tajných údajů.
Cokoli, co je odesláno do prohlížeče, může uživatel zkontrolovat.
Citlivé přihlašovací a autentizační údaje patří na backend.
XSS
Cross-site scripting patří mezi hlavní bezpečnostní rizika frontendového vývoje.
Vyhýbám se vkládání libovolného nedůvěryhodného obsahu do DOMu jako HTML.
Dávám přednost:
- DOM API pracujícím s textem,
- důvěryhodným mechanismům vykreslování,
- sanitizaci na straně serveru.
S dynamickým HTML je potřeba zacházet opatrně.
innerHTML
innerHTML je výkonné, ale při práci s nedůvěryhodnými daty také nebezpečné.
Bez rozmyslu jej nepoužívám pro:
- uživatelský vstup,
- data z externích API.
Pokud je to možné, používám DOM API, která s hodnotami zacházejí jako s textem.
Content Security Policy
Silně nastavená Content Security Policy může přidat další bezpečnostní vrstvu.
Může pomoci omezit:
- skripty,
- zdroje,
- externí připojení.
Vnímám ji jako součást širší bezpečnostní architektury, nikoli jako náhradu bezpečně napsaného kódu.
Autentizace
Frontendový JavaScript se může účastnit autentizačních procesů, ale rozhodování o autorizaci patří na server.
Prohlížeč může o operaci požádat.
Backend rozhodne, zda je povolena.
Skrytí tlačítka na straně klienta nepředstavuje bezpečnostní opatření.
OAuth
JavaScriptové aplikace se mohou účastnit OAuth toků.
Tyto toky navrhuji podle typu konkrétní aplikace.
Citlivé client secrets by neměly být vloženy do veřejně dostupného kódu běžícího v prohlížeči.
Progresivní vylepšování
U webových stránek, které nejsou plnohodnotnými aplikacemi, dávám tam, kde je to praktické, přednost tomu, aby JavaScript rozšiřoval funkční HTML základ.
To zlepšuje:
- odolnost,
- přístupnost,
- udržovatelnost.
Ne každá stránka se musí změnit v single-page application.
Přístupnost
Interakce implementované v JavaScriptu musí zachovávat přístupnost.
Vlastní komponenty by měly podporovat:
- ovládání klávesnicí,
- správu focusu,
- sémantický stav.
Vyhýbám se vytváření vizuálně interaktivních prvků, které nelze používat bez myši.
Správa focusu
U dialogů, navigace a dynamických rozhraní je potřeba focus řídit záměrně.
Když se komponenta otevře, zavře nebo změní kontext, uživatelé ovládající rozhraní klávesnicí by neměli ztratit svou pozici.
Responzivní aplikace
JavaScript někdy musí reagovat na změny prostředí.
Pro čistě vizuální responzivní chování však preferuji CSS.
JavaScript by měl vstupovat do hry až tehdy, když změna layoutu ovlivňuje také skutečné chování aplikace.
Frameworky
JavaScript má rozsáhlý ekosystém frameworků.
Framework ale nevolím automaticky.
Pro malé a středně velké nástroje v prohlížeči může být nativní JavaScript jednodušším a dlouhodobě udržitelnějším řešením.
U větších aplikací může framework nabídnout užitečnou architekturu pro práci se stavem a komponentami.
Volba by měla vycházet ze složitosti projektu, ne z módních trendů.
Nativní JavaScript
Moderní JavaScript a API prohlížeče jsou natolik schopné, že mnoho projektů rozsáhlý frontendový framework vůbec nepotřebuje.
Nativní JavaScript používám tehdy, když díky němu aplikace zůstává:
- lehká,
- srozumitelná,
- úsporná z hlediska závislostí.
To je zvlášť užitečné u úzce zaměřených nástrojů a vložených aplikací.
Správa závislostí
Každá JavaScriptová závislost přidává:
- další kód,
- větší bezpečnostní plochu,
- požadavky na aktualizace,
- větší výsledný bundle.
Vyhýbám se přidávání knihoven pro funkcionalitu, kterou lze čistě implementovat pomocí samotné platformy prohlížeče.
Závislosti by měly přinášet skutečnou hodnotu.
Build nástroje
Některé JavaScriptové projekty vyžadují build nástroje.
Jiné nikoli.
Preferuji co nejjednodušší build proces, který požadavky projektu skutečně pokrývá.
Malá aplikace by neměla potřebovat komplikovaný build pipeline pouze proto, že jej moderní frontendové projekty často používají.
TypeScript
U větších JavaScriptových aplikací používám TypeScript tam, kde přinášejí hodnotu silnější typové kontrakty.
TypeScript zlepšuje:
- refaktoring,
- kontrakty API,
- modelování stavu,
- vývojářské nástroje.
JavaScript pod ním stále zůstává základní běhovou vrstvou.
WordPress
Ve WordPressu používám JavaScript například pro:
- dynamická rozhraní,
- komunikaci s REST API,
- filtry,
- frontendové aplikace,
- vlastní interakce.
Odpovědnosti na straně serveru ponechávám v PHP a JavaScript používám pro chování v prohlížeči.
Bricks Builder
V Bricks používám vlastní JavaScript tam, kde vestavěné interakce nestačí.
Může jít například o:
- komunikaci s API,
- aplikační logiku,
- vlastní chování UI.
Skripty nepřidávám tam, kde požadavek čistě řeší CSS nebo nativní funkce Bricks.
WordPress REST API
JavaScript může přímo využívat endpointy WordPress REST API.
Například:
Prohlížeč
↓
JavaScript
↓
WordPress REST API
↓
PHP
Díky tomu lze stránky WordPressu proměnit v interaktivnější aplikační rozhraní.
PHP
V mnoha mých projektech tvoří JavaScript a PHP dvě strany téže aplikace.
PHP zajišťuje:
- serverovou logiku,
- perzistenci dat,
- autorizaci.
JavaScript zajišťuje:
- interakci,
- stav na straně klienta,
- API prohlížeče.
Hranici mezi nimi často tvoří HTTP nebo REST rozhraní.
Backendy v Pythonu
JavaScript může sloužit také jako frontend pro backendové systémy postavené v Pythonu.
Typická architektura může vypadat například takto:
Prohlížeč
↓
JavaScript
↓
REST API
↓
Python / Flask
Jednotlivé vrstvy přitom zůstávají nezávislé.
Debugování
Vývojářské nástroje prohlížeče jsou zásadní součástí mého JavaScriptového workflow.
Používám je ke kontrole:
- chyb za běhu,
- síťových požadavků,
- stavu DOMu,
- výkonu,
- úložišť.
Dávám přednost diagnostice skutečného stavu aplikace před přidáváním oprav založených pouze na domněnkách.
Logování do konzole
Logování do konzole je při vývoji užitečné.
V produkčním prostředí se vyhýbám ponechávání nadměrného množství debugovacích výpisů.
Logy by měly poskytovat užitečné diagnostické informace, aniž by odhalovaly citlivá data.
Kontrola síťové komunikace
Když se API nechová správně, kontroluji:
- metodu požadavku,
- hlavičky,
- payload,
- stav odpovědi,
- tělo odpovědi.
To pomáhá určit, zda problém vzniká v:
- frontendovém kódu,
- síťové komunikaci,
- backendové logice.
Testování
JavaScript testuji tam, kde je chování natolik důležité, že by regrese byly nákladné.
Může jít například o:
- transformace dat,
- přechody mezi stavy,
- validaci,
- aplikační logiku.
U interaktivních aplikací testuji také skutečné chování v reálném prohlížeči.
Defenzivní programování
Aplikace v prohlížeči komunikují s řadou nespolehlivých hranic:
- uživateli,
- soubory,
- API,
- úložišti,
- sítěmi.
Počítám s tím, že každá z nich může přinést neočekávaný výsledek.
Defenzivní kontroly na těchto hranicích zabraňují tomu, aby se chyby šířily hlouběji do aplikace.
Udržovatelnost
JavaScript se může stát obtížně udržovatelným, pokud je logika rozptýlena mezi:
- anonymní obsluhy událostí,
- globální proměnné,
- inline skripty,
- stav uložený v DOMu.
Dávám přednost explicitním modulům, stavu a jasně definovaným hranicím.
Aplikace v prohlížeči by měla zůstat srozumitelná i tehdy, když vyroste nad rámec svého původního rozsahu.
JavaScript v mém technologickém stacku
JavaScript běžně používám společně s technologiemi, jako jsou:
- TypeScript,
- HTML a CSS,
- WordPress,
- Bricks Builder,
- WordPress REST API,
- REST API,
- JSON,
- Browser APIs,
- File API,
- Canvas,
- Web Workers,
- WebAssembly,
- WebGL,
- Three.js,
- FFmpeg.
JavaScript představuje běhovou vrstvu, která tyto technologie propojuje uvnitř prohlížeče.
Proč používám JavaScript
JavaScript používám proto, že je jazykem prohlížeče a poskytuje přímý přístup k jedné z nejschopnějších aplikačních platforem, které jsou dnes k dispozici.
Dokáže obsloužit jednoduchou interakci, ale zároveň může koordinovat:
- lokální zpracování souborů,
- vykreslování,
- zvuk,
- síťovou komunikaci,
- workery na pozadí,
- WebAssembly,
- kompletní stav aplikace.
Jeho flexibilita je současně výhodou i odpovědností.
JavaScript umožňuje vytvářet mimořádně schopné aplikace i s velmi malým množstvím počáteční struktury.
Mým přístupem je udržet tuto flexibilitu pod kontrolou pomocí jasných modulů, explicitního stavu, defenzivní validace a vhodného využití platformy prohlížeče.
Tak JavaScript používám: ne jako soubor jednotlivých skriptů, ale jako aplikační runtime moderního interaktivního webového softwaru.