Většina produktů Google komunikuje téměř výhradně pomocí Protocol Buffers. V tomto formátu se komunikuje s úložištěm, mezi servery a posílají se v něm data i do klienta a z klienta. Na serveru se protocol buffery přenáší v binárním formátu, na klienta se posílá řetězec obsahující JavaScriptový literál pro pole. Ve srovnání třeba s JSONem jde o formát mnohem úspornější, protože názvy polí se vůbec nepřenáší. Srovnejte:
{"id":1,"name":"Jakub"} // JSON
[1,"Jakub"] // Protobuf
Při buildu se vygenerují metody jako getName
a setName
, pomocí kterých se s protocol bufferem pracuje. To má zároveň tu výhodu, že když uděláte v názvu metody překlep, tak build spadne. U JSONu tato ochrana chybí, protože např. obj.anme
je platná hodnota při čtení i zápisu. Closure Compiler vygenerované metody potom obvykle zase inlinuje, taže i výsledný JavaScriptový kód je malý.
Na klientu se řetězec obsahující protocol buffer dá přeložit do JavaScriptového pole v zásadě dvěma způsoby: eval
nebo JSON.parse
. Oba způsoby jsou v moderních prohlížečích velmi rychlé, JSON.parse
o něco rychlejší. eval
má zase tu výhodu, že nepoužitá pole lze vynechat: eval('[1,,,"Jakub"]')
versus JSON.parse('[1,null,null,"Jakub"]')
. Tahle výhoda ale není příliš zásadní, protože mnohokrát opakovaný fragment ,null
lze dobře komprimovat. Při mnoha prázdných polích se pak použije formát {"1":1,"2000":"Jakub"}
.
Většina produktů Google v současnosti pro zpracování protocol bufferů používá eval
. Důvod je ten, že JSON nepodporuje speciální číselné hodnoty, které podporuje protobuf i JavaScript. Jde o NaN, Infinity a -Infinity. Nekonečno se dá simulovat pomocí obřího čísla (1e404 se zaokrouhlí na Infinity), ale s NaN je problém. Přenášená data jsou tak rozmanitá, že tu a tam se NaN bohužel někde vyskytne.
Rozhodli jsme se proto NaN přenášet jako řetězec "NaN"
a při deserializaci ho přeložit zase zpátky na NaN. Opačnou změnu je samozřejmě potřeba udělat i při serializaci, protože JSON.stringify
převádí NaN na null
. Díky tomu budeme moci z kódu odstranit eval
a z CSP potom vyhodit unsafe-eval
.
Diskuse je zrušena z důvodu spamu.