Minimalistické zvýrazňování syntaxe
Nastal čas, abych tady na DEADBEEF přidal zvýrazňování syntaxe. To samo o sobě není nic převratného, existuje spousta knihoven a nástrojů, pro majoritní blogo-software často ve formě jednoduchého pluginu. Já tu ale pochoduji podle vlastního rytmu a mám specifické preference. Jedním z nich je minimalizace všechno nedůležitého. Proto asciiblog generuje statické html soubory téměř bez javascriptu a je napsaný ve Scale tak, aby pracoval co nejrychleji.
Jak tedy na zvýrazňování syntaxe s tímto omezením? Na výběr je ze dvou
přístupů: Buď se provede na serveru nebo na klientu. Zvýraznění na serveru
nepotřebuje javascript, ale na druhou stranu musí do HTML vložit <span>
elementy a to nabobtná generované stránky. Zvýrazňování na klientu potřebuje
javascript a musí stáhnout knihovny pro parsování každého použitého jazyka a jeho zvýrazňování. To taky vede ke zbytečně přeneseným datům a ty se snažím za
každou cenu minimalizovat.
Existuje ještě jedna varianta: Parsování provedu na serveru a do stránky vložím jen informace co se má jak obarvit pro maličkou javascriptovou smyčku, která nemusí nic vědět o syntaxi žádného jazyka. Tato informace je ve své podstatě polem trojic hodnot (vzdálenost od konce posledního zvýraznění, délka zvýraznění, barva) a je ho třeba kompaktně reprezentovat tak, aby se dalo snadno dekódovat. Komplikovanější schéma může ušetřit pár bajtů, ale bude potřebovat delší JS logiku, která převáží všechny zisky. V ASCII tabulce leží nepřerušovaná sekvence 87 znaků, které se můžou nacházet v HTML data atributu bez escapování a ty se hodí pro jakési base87 kódování.
Javascriptová smyčka je minimální (jen 405 bajtů), každý obarvený segment
potřebuje pouhé 3 bajty informace, kdežto <span class=hl1></span> zabere 23
bajtů + (120 bajtů pro CSS styl). Když se ve stránce nachází víc jak ~15
obarvených oblastí, hybridní přístup si vyžádá nejméně místa. (Je jasné, že
příčetní jedinci by se ničím takovým vůbec nezabývali a plácli by tam první JS
knihovnu, kterou na ně vyklopí google, ale jak jsem řekl, tady pochodujeme
podle specifického rytmu & počítáme bajty.)
Na ničem z toho ale nezáleží, protože server servíruje dokumenty komprimovaně.
Hlavní stránka DEADBEEFu obsahuje 203 zvýrazněných oblastí. Zvýrazňování přes
na serveru generované <span> elementy navýší její velikost o 4.8 kB, hybridní
JS by přidalo jen čtvrtinu tohoto. Ale jak to vypadá pro komprimované stránky?
Takhle:
| * | bez syntaxe | se syntaxí | rozdíl |
| plaintext | 30069 B | 34869 B | 4800 B |
| gzip | 11604 B | 11998 B | 394 B |
| brotli | 10261 B | 10544 B | 283 B |
S gzipem je rozdíl mezi stránkou bez jakéhokoli zvýraznění syntaxe a zvýrazněním na serveru jen 400 bajtů, přesně tolik, kolik by zabral JS zvýrazňovač. Neušetřil bych tedy nic a vyžadovalo by to javascript. Ta nejjednodušší cesta je zároveň tou nejlepší. Komprese dělá přesně to, co bych dělal ručně – najde často opakované sekvence znaků a nahradí je kratším zástupným symbolem. Jen to nedělá ad-hoc.
To je taky důvod, proč minifikace javascriptových souborů, která zkrátí jména proměnných, je často k ničemu. Komprese udělá to samé, jenom lépe a systematičtěji. Místo toho se vyplatí zredukovat počet různých tokenů, jako jsou zbytečné mezery, závorky, středníky a podobné.