Zod validācijas shēma parasti strādā tā: katrā izsaukumā bibliotēka iziet cauri shēmas kokam un pārbauda katru mezglu no jauna. Zod Compiler šo darbu pārceļ uz būvēšanas laiku — kompilators shēmu pārraksta par parastu JavaScript funkciju, un rezultāts validē datus 2 līdz 75 reizes ātrāk. Pirmkoda izmaiņas nav vajadzīgas.
Rīku uztur Gajus Kuizinas, un tas izplatīts ar BSD-3-Clause licenci. Projekts sākās kā zod-aot atzarojums, ko izstrādāja Kadzuma Vakita (@wakita181009). Abi risina vienu problēmu: Zod shēmas forma ir zināma jau tad, kad izstrādātājs to uzrakstījis, tāpēc nav jēgas interpretēt to koku katrā validācijas reizē.
Kā tas strādā
Zod v4 shēma darbības laikā tiek staigāta kā datu struktūra: katram laukam ir savs mezgls, un validācija nozīmē rekursīvu apstaigāšanu ar funkciju izsaukumiem. Zod Compiler shēmu izlasa būvēšanas laikā un ģenerē tieši to validatoru, kas atbilst konkrētajai formai — bez koka, bez dispečera un bez papildu datiem katram mezglam.
Autora publicētie mērījumi rāda, cik daudz tas dod. Vidēja izmēra objekta validācija sasniedz 10,3 miljonus operāciju sekundē, kamēr Zod v4 tur pašā testā izdara 2,4 miljonus. Liels objekts ar 100 elementiem pieaug no 19 tūkstošiem operāciju sekundē līdz 1,4 miljoniem. Rekursīvs koks ar 121 mezglu strādā aptuveni 16 reižu ātrāk.
Vakitas oriģinālais zod-aot dod līdzīgu ainu pa shēmu tipiem: vienkārša virknes pārbaude paātrinās aptuveni 1,8 reizes, vidējs objekts — 5 reizes, tas pats objekts ar nederīgu ievadi — 23 reizes, liels ligzdots objekts ar 100 elementiem — līdz 64 reizēm, bet diskriminēta savienība — aptuveni 10 reizes.
Jo lielāka un sarežģītāka shēma, jo lielāks ir kompilācijas ieguvums.
Trīs veidi, kā to iedarbināt
Noklusējuma režīms strādā automātiski: spraudnis atrod visas eksportētās Zod shēmas un tās kompilē, neprasot ne wrapper funkcijas, ne importus no pašas bibliotēkas pirmkodā. Kas grib skaidru kontroli, var ietīt konkrētas shēmas ar compile() funkciju. Ir arī komandrindas rīks, kas ģenerē validatorus bez būvju sistēmas vispār.
Izstrādes laikā compile() vienkārši nodod izsaukumu tālāk parastajai Zod bibliotēkai, un tikai produkcijas būvējumā spraudnis to aizstāj ar ģenerēto kodu. Tas nozīmē, ka atkļūdošana notiek ar pazīstamo Zod uzvedību, bet lietotājs saņem kompilēto ātrumu.
Ko tas kompilē un kur atkāpjas
Pilnībā kompilējas virknes, skaitļi, objekti, masīvi, savienības, diskriminētas savienības, uzskaitījumi, datumi, rekursīvas lazy shēmas un tādi transform vai refine izsaukumi, kas neko nepārtver no ārējā konteksta. Ģenerētais kods saglabā pilno Zod saskarni — .shape, instanceof pārbaudes un Standard Schema saderību — tāpēc tRPC, Hono un React Hook Form strādā bez papildu darba.
Kompilators atkāpjas atpakaļ uz darbības laika Zod tur, kur nevar iztikt bez interpretācijas: pie atgriezeniskajiem izsaukumiem, kas pārtver ārējos mainīgos, pie superRefine un custom, kā arī pie lazy shēmām, kuras nevar atrisināt būvēšanas laikā. Vēl viens ierobežojums — atbalstīta ir tikai Zod v4, ne vecā v3.
Būvju rīki un bundle izmērs
Zod Compiler pieslēdzas Vite, webpack, esbuild, SWC, Rollup, Rolldown, rspack, Bun un Farm. Ātrāks validators nozīmē vairāk ģenerētā koda, tāpēc rīks mēģina to kompensēt. Kad vienādas formas atkārtojas, strukturālā dedublēšana samazina ģenerēto kodu aptuveni par 50 % neapstrādāti un 34 % pēc gzip. Ar output: "compact" režīmu ietaupījums pieaug līdz aptuveni 73 % neapstrādāti un 71 % pēc gzip. Shēmu pacelšana (hoisting) pārvieto funkciju iekšienē definētās shēmas uz moduļa līmeni, lai tās varētu koplietot.
Kur tas iekļaujas ainā
Zod Compiler nav pirmais mēģinājums validāciju kompilēt. Typia jau sen ģenerē validatorus, kas testos sasniedz ap 76 miljoniem operāciju sekundē, bet tas prasa TypeScript tipu definīcijas, ne Zod shēmas — tātad citu rakstīšanas veidu. AJV standalone režīms izmanto tādu pašu pieeju, bet JSON Schema pasaulē. Zod Compiler priekšrocība ir tā, ka esošās Zod shēmas paliek nemainītas: nekādas migrācijas, tie paši objekti, tikai ātrāka izpilde produkcijā.
Praktiski tas nozīmē, ka projektiem ar lielām, ligzdotām API atbildēm vai formu validāciju ieguvums ir vislielākais tieši tur, kur Zod līdz šim bija lēnākais — pie simtiem elementu lieliem objektiem, kur starpība sniedzas no 19 tūkstošiem līdz 1,4 miljoniem operāciju sekundē.
Ko der paturēt prātā
Skaitļi nāk no rīku autoru pašu mērījumiem, tāpēc reālais ieguvums būs atkarīgs no konkrētās shēmas un tā, cik bieži validācija notiek karstajā ceļā. Vienkāršai virknes pārbaudei 1,8 reižu paātrinājums pie jau tā ātras darbības neko daudz nemaina. Toties tur, kur serveris katrā pieprasījumā pārbauda lielu ligzdotu objektu, atšķirība starp 19 tūkstošiem un 1,4 miljoniem operāciju sekundē nozīmē mazāku procesora slodzi un īsāku atbildes laiku.
Otrs praktiskais jautājums ir bundle izmērs. Ģenerētais kods ir garāks par shēmas definīciju, tāpēc frontend projektiem ar daudzām mazām shēmām compact režīms un strukturālā dedublēšana kļūst svarīga. Backend projektos, kur bundle izmērs nav problēma, var ģenerēt pilno kodu un iegūt maksimālo ātrumu. Tā kā compile() izstrādes laikā uzvedas tāpat kā parasts Zod, izmēģināt to var vienā būvējumā, nemainot nevienu shēmu.
Komentāri
Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.