PATTERN Cited by 1 source
View placeholder async embed¶
When to use¶
You are rendering a server-driven page where:
- The main content can be delivered quickly but one or more nested sub-views are slower (different backend, heavier computation, less critical to first paint).
- The sub-views are independent enough that the parent should render without them.
- Sub-views may be owned by different teams or served by different backends than the parent view.
- You want a consistent SDUI primitive rather than one-off progressive-loading components per feature.
The pattern¶
Include a ViewPlaceholder component in the parent view. The
client:
- Renders the parent view immediately.
- Shows a loading state (default spinner or a custom component) where the placeholder sits.
- Fires a separate CHAOS request for the nested view's configuration.
- Once the nested view's configuration arrives, replaces the loading state with the nested view's rendered content.
The parent response is independent of the nested response's latency.
The Yelp CHAOS shape¶
Verbatim spec of ViewPlaceholderV1 from the 2025-07-08 post:
@dataclass
class ViewPlaceholderV1(_ComponentData):
viewName: str
featureContext: Optional[ChaosJsonContextData]
loadingComponentId: Optional[ComponentId]
errorComponentId: Optional[ComponentId]
emptyComponentId: Optional[ComponentId]
headerComponentId: Optional[ComponentId]
footerComponentId: Optional[ComponentId]
estimatedContentHeight: Optional[int]
defaultLoadingComponentPadding: Optional[Padding]
component_type: str = field(
init=False, default="chaos.component.view-placeholder.v1"
)
Notable design choices:
viewNameidentifies the nested CHAOS view to fetch.featureContextis an optional JSON blob passed to the nested view's backend at build time — the parent can inject context the nested view needs to specialise its output.- Four optional state components (
loadingComponentId,errorComponentId,emptyComponentId,headerComponentId,footerComponentId) let the parent customise the three failure / empty states and wrap the content with fixed header/footer chrome defined in the parent view's components dictionary. estimatedContentHeightlets the client reserve layout space so the parent view doesn't reflow when content arrives — a concrete layout-stability lever.
Motivating example (Yelp for Business home)¶
Verbatim (2025-07-08): "the 'Reminders' feature is another standalone CHAOS view supported by a different CHAOS backend service. A ViewPlaceholder is used to asynchronously fetch the Reminders after the home screen has loaded and position it in the appropriate location."
The home screen is owned by one team, Reminders is owned by another, and they're served by different CHAOS backends. The placeholder is the composition primitive that lets the home screen render quickly while Reminders loads.
Benefits¶
- Decoupled latency budgets. Parent view and nested view can have different latency profiles; the parent is never blocked on the slow one.
- Team-owned backends can compose. The home team doesn't need to call the Reminders backend directly or understand its data model — just name the view.
- Graceful degradation. Built-in error / empty states mean a failed nested view produces a predictable fallback UI, not a broken page.
- Layout stability.
estimatedContentHeightreserves space so content arrival doesn't cause content shift (Core Web Vitals CLS analogue on mobile).
Trade-offs¶
- Extra round trip. The nested view is a separate network request; total time-to-fully-interactive increases.
- Loading-state UX complexity. Designers need to think about three non-happy-path states (loading, error, empty) in addition to the content.
- Cache invalidation split. Parent and nested views have independent caching semantics; keeping them consistent requires per-system discipline.
- Render-order surprises. Nested content arrives after the parent is rendered; users may be mid-scroll when the layout changes unless the estimated height was accurate.
Contrast with adjacent patterns¶
- Preloaded view flow — for predictable sequential navigation; all views arrive upfront in one response. View placeholders are for nested async loads, not sequential navigation.
- Progressive hydration (web) — shape-wise similar, but at the SSR streaming layer, not the SDUI layer.
- React Suspense fallback — the same user-facing UX; the placeholder is the server-driven equivalent, where the SDUI framework (not the client framework) decides when and how to render the fallback.
Hard problems¶
- Cascading placeholders. A nested view can itself contain placeholders, leading to multi-level async loads. Latency discipline must apply transitively.
- featureContext serialisation. The parent's injected context arrives as an opaque JSON blob (concepts/json-string-parameters-for-schema-stability). Schema drift between parent and nested backend is a runtime failure class.
- Auth / scope for nested views. A nested view may be fetched with the same user credentials but targets a different backend with different auth expectations.
Seen in¶
- sources/2025-07-08-yelp-exploring-chaos-building-a-backend-for-server-driven-ui
— Yelp CHAOS
ViewPlaceholderV1; first wiki instance. Yelp for Business home screen + Reminders feature is the named concrete example.
Related¶
- systems/yelp-chaos
- concepts/server-driven-ui
- patterns/preloaded-view-flow-for-predictable-navigation — complementary pattern for predictable navigation
- concepts/json-string-parameters-for-schema-stability —
the mechanism for
featureContextinjection