perf(v4): dedupe factory def boilerplate in core/api.ts (-2.3% tree-shaken) - #6348
perf(v4): dedupe factory def boilerplate in core/api.ts (-2.3% tree-shaken)#6348zirkelc wants to merge 3 commits into
Conversation
|
Closing this one. The headline is minified bytes, and that reduction doesn't survive compression. I re-measured the branch against its own merge-base: the ~1.6 kB minified drop on That isn't a flaw in the measurement, it's the metric: gzip already encodes duplicated function bodies almost for free, so factoring the repetition out buys nothing on the wire while the new helper names are fresh bytes. Dedupe-shaped changes are size-neutral at best, and minified bytes aren't a proxy for what users download. So this stands or falls as a readability change, and I'd rather keep the explicit def literals in the factory layer — they're easy to scan and easy to diff, and |
What this PR does
Dedupes the repeated def-literal boilerplate in the
core/api.tsfactory functions. Dozens of factories build near-identical def objects that the minifier cannot compress because property names are not mangled. Three commits, each preserving def key order and key presence byte-for-byte:1. String-format schema factories (
_sf/_sfa). 27 factories (_email,_uuid,_ipv6, the ISO family, ...) each spelled out{ type: "string", format: X, check: "string_format", abort: false, ...normalizeParams(params) }. They now delegate to two small helpers;_sfasupplies theabort: falsedefault,_sfis used by the ISO factories that never setabort, and per-factory extras (version: "v4",precision: null, ...) pass through adefaultsargument in the original key position. Public signatures unchanged.2. Check factories (
_ck/_ckf). Same treatment for 17 check factories (_lt/_gte,_minLength-family,_regex/_includes/_startsWith/_endsWith, ...). Trailing fields still spread afternormalizeParams, so user params cannot overridevalue/inclusive/pattern, exactly as before.3. Shared
_defaultDef. ThedefaultValue-getter def literal (unwrap function values,shallowClonestatic ones) appeared five times acrosscore/api.ts,classic/schemas.ts, andmini/schemas.ts; it is now built by one exported helper.All three are construction-time only; no parse-path code is touched. The schema-init benchmark (
pnpm bench init) was smoked around the round-1 factory change with results inside run-to-run noise.Verification (this branch vs
main)Per case, minified bytes (gzip tracked alongside; judged on minified):
import * as z(standard)import { z }(full)import { string }_sf/_sfastring-format factories_ck/_ckfcheck factories_defaultDefFull suite green after every commit (3,847 tests + typecheck on current
main). One trade-off to disclose: minimalzod/miniconsumers retain the_ckhelper once, +45 bytes on a 7.4 kB bundle (commit 2); classic consumers see no regression anywhere. Net source delta: 3 files, +111/-323.Reproducing the numbers
The harness below is the one used for the verification runs. From a checkout of this repo:
pnpm installSave the file below as
sizecheck/compare.mts(the directory must live inside the repo so the materialised trees resolvenode_modules;sizecheck/{a,b,meta}/are created automatically and safe to delete).Fetch this PR's head ref and compare it against
main:A run takes ~15s and prints per-case minified/gzip bytes for both sides with exact deltas; the
namespace-import-classicrow is the standardimport * as zconsumer,z-import-classictheimport { z }style,named-import-classictheimport { string }style. A control run with the same rev on both sides (pnpm tsx sizecheck/compare.mts main main) prints all-zero deltas — the pipeline is deterministic, so single runs are conclusive.sizecheck/compare.mts— A/B bundle-size harness