name: tzlint-performance description: Hot-path performance rules — no JSON/per-node deserialize, absolute spans, native-only single traversal, instance reuse.
Rule.
- Never JSON-serialize the AST, and never
Deserializethe archive to native nodes per-node in the hot path — rules read the archived form in place viaNodeRef<'ast>. Spanis an absolute byte range intoAst.text; never passsourceas a separate payload; no node-relative rebasing.- Single-traversal is a native-rule property only. Plugins receive the whole archive once per (file, plugin) and self-traverse; never call a plugin per node.
- Config membership lookups use
HashSet; precompute outside the file loop. - Share the compiled WASM
ModuleviaArc; reuseStore/Instanceper rayon worker (reset between files); the host-written AST is read withaccess_unchecked(no O(N) re-validation per plugin).
Why. The original design's JSON serialization in the hot path negated the AST's cache locality; per-node boundary crossings and per-plugin revalidation are the other cliffs.
How to apply. If a change adds an allocation/copy/serialize per node, or a host↔guest crossing per node, stop — it is almost certainly wrong. Benchmark the real WASM path.