Context
PR #641 (Server-Side Ad Templates Design) introduces URL-matched slot templates so the edge can fire auctions before the browser receives HTML.Section 3 lists dynamic slot discovery as an explicit non-goal — the spec
trades Smart Slots' DOM-scan flexibility for ~2s of latency improvement via pre-configured slots.
That trade is sound for Phase 1, but it caps the design. The static-config approach cannot:
- Select between configured formats based on actual rendered column width
- Compute real above-the-fold position for variable-length content
- Place slots at natural content breaks (end-of-section, mid-article)
- Emit measured viewability signals in the OpenRTB bid request
All four are gated on a single missing capability: server-side text layout measurement. Today that capability lives only in the browser's layout engine, which is why ad tech has historically required client JS.
Proposal
Investigate chenglou/pretext as a candidate primitive. Pretext performs multi-line text measurement (line count, height, per-line widths, wrap points) without a DOM, using Canvas measureText as its only browser dependency. The API splits cleanly into a one-time prepare() step (measurement) and a hot-path layout() step (pure arithmetic, ~0.09ms for a 500-text batch per the README).
The question this issue answers: does a Pretext-style primitive belong in the trusted-server pipeline, and if so, where?
Deliverables
-
Accuracy test. Run Pretext in Node (@napi-rs/canvas) against a corpus of real publisher article HTML — minimum 10 templates, varied lengths, at 3+ viewport widths. Compare predictions to headless Chrome ground truth. Report divergence per font stack and viewport.
-
Integration options doc. Three viable paths, each with scope estimate:
- Tier 1 — offline audit tool (Node-based, no edge integration)
- Tier 2 — split
prepare() at build / layout() at edge (JS Compute)
- Tier 3 — Rust/WASM port using
cosmic-text or rustybuzz
-
Impact model. Using the accuracy spike data on one real publisher config, estimate:
- % of configured ATF slots that are provably not ATF on mobile
- % of multi-format slots where one format never fits the column
- Directional CPM lift if measured ATF + single-format bid requests were sent
-
Recommendation. One concrete next step — audit tool, edge integration, or Rust port — with scope and owner.
Open Questions
- Does Pretext's Canvas ground truth match Chromium closely enough for publisher SLAs? (README flags
system-ui as unsafe for layout() accuracy on macOS.)
- Can
PreparedText handles be serialized into Fastly KV and rehydrated at the edge, or does prepare() need to run in-process each time?
- What is the cache-fragmentation cost of device-bucketed layout vs. a single pre-computed pass?
- Does this work share a content-inspection path with the third-party tag firewall — i.e. is there a single "parse and reason about origin HTML" pipeline worth building once?
Scope
Analysis and recommendation only. No implementation in this ticket. If the test recommends integration, a follow-up spec covers design.
Related: #641
Context
PR #641 (Server-Side Ad Templates Design) introduces URL-matched slot templates so the edge can fire auctions before the browser receives HTML.Section 3 lists dynamic slot discovery as an explicit non-goal — the spec
trades Smart Slots' DOM-scan flexibility for ~2s of latency improvement via pre-configured slots.
That trade is sound for Phase 1, but it caps the design. The static-config approach cannot:
All four are gated on a single missing capability: server-side text layout measurement. Today that capability lives only in the browser's layout engine, which is why ad tech has historically required client JS.
Proposal
Investigate chenglou/pretext as a candidate primitive. Pretext performs multi-line text measurement (line count, height, per-line widths, wrap points) without a DOM, using Canvas
measureTextas its only browser dependency. The API splits cleanly into a one-timeprepare()step (measurement) and a hot-pathlayout()step (pure arithmetic, ~0.09ms for a 500-text batch per the README).The question this issue answers: does a Pretext-style primitive belong in the trusted-server pipeline, and if so, where?
Deliverables
Accuracy test. Run Pretext in Node (
@napi-rs/canvas) against a corpus of real publisher article HTML — minimum 10 templates, varied lengths, at 3+ viewport widths. Compare predictions to headless Chrome ground truth. Report divergence per font stack and viewport.Integration options doc. Three viable paths, each with scope estimate:
prepare()at build /layout()at edge (JS Compute)cosmic-textorrustybuzzImpact model. Using the accuracy spike data on one real publisher config, estimate:
Recommendation. One concrete next step — audit tool, edge integration, or Rust port — with scope and owner.
Open Questions
system-uias unsafe forlayout()accuracy on macOS.)PreparedTexthandles be serialized into Fastly KV and rehydrated at the edge, or doesprepare()need to run in-process each time?Scope
Analysis and recommendation only. No implementation in this ticket. If the test recommends integration, a follow-up spec covers design.
Related: #641