Skip to content

Investigate Pretext as a server-side layout primitive for dynamic ad template slot resolution #652

@jevansnyc

Description

@jevansnyc

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

  1. 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.

  2. 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
  3. 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
  4. 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions