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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions