Performance and assets

21. Rendering efficiency, scheduling and memory

Performance follows demanded work

HLD — Arrows show demanded work and its measurement. A cost test for controls cannot qualify an entire graph scene. Open the diagram for full size.

21.1 Performance begins with the dependency that changed

A control function running again is not the same event as a layout pass, a draw, a host-tree publication or a frame reaching the display. An optimization that reduces one count can leave the expensive work untouched.

A useful investigation starts with a concrete change. A message reaction changed. Which state projection observed it? Which component recalculated? Did layout change? Was the whole conversation encoded across the bridge? Did an image request restart? These questions connect the visible symptom to actual work.

Figure 40. A reaction change belongs to one message's relevant state projection. The architecture should not require every conversation region to rebuild or cross a runtime boundary for that local change. See the illustrated PDF for the diagram.

The governing rule is: invalidate the smallest correct scope, at the latest stage that can express the change. The word “correct” matters. A stale component that never rerenders is not an optimization. A font change that genuinely affects geometry must invalidate measurement.

21.2 Recomposition and rerendering are normal mechanisms

Declarative frameworks recalculate output when dependencies change. That is their normal operation, not inherently a defect. The performance question is how much work the recalculation causes and whether it meets the interaction deadline.

In Compose, stable identity, dependency placement and compiler behavior influence skipping. Strong skipping changes which restartable composables can be skipped and how some parameters are compared. It does not make false immutability annotations safe or remove the need to model state correctly. 38

In React, narrow subscriptions and coherent snapshots come before indiscriminate memoization. A component may still update because its own state or consumed context changed. Surface's graph bindings should expose useful projections rather than force every control to subscribe to one rapidly changing application-root value.

A model aggregate is still appropriate when several fields must change together. The aim is not to split everything into independent streams. Doing so can expose inconsistent intermediate combinations. Dependency granularity and transactional coherence have to be designed together.

21.3 Cache according to actual dependencies

A resolved button recipe can be cached by the inputs that determine it. A measurement can be cached by text, font metrics and constraints. An image decode can be cached by asset identity and target dimensions. These caches have different keys because they preserve different results.

Incorrect keys create subtle stale behavior. A text measurement cache that ignores locale or font change can clip content. A recipe cache that ignores reduced-motion policy can retain an unwanted transition. A resource key that ignores authorization scope can expose private media incorrectly.

The reference correctness path remains available. An incremental projection can be compared with full recomputation. A cached measurement can be checked after relevant environmental changes. Optimization should reduce repeated work without silently changing meaning.

21.4 Schedule immediate and speculative work differently

Typing, focus and current pointer feedback are urgent. Preparing a panel that might be opened next is speculative. If both compete without priority, the system can spend resources on an invisible future feature while delaying the current input.

Bounded concurrency is therefore a first-class execution policy. Asset requests, host commits and expensive preparations should not accumulate without limit. Cancellation must release work that is no longer useful. Coalescing is appropriate only when the older value can actually be discarded.

React's scheduling transitions can make eligible rendering updates interruptible, but they do not move arbitrary work to another thread and are not visual animation transitions. Surface keeps immediate editing feedback outside delayed presentation work. 39

For CMP, the same architectural priority applies even though the scheduling mechanism differs. The renderer and its frame clock remain the owners of immediate presentation. Graph state processing and resource preparation should not hold a UI-thread critical section unnecessarily.

21.5 Frames are deadlines shared with the rest of the system

At 60 Hz, a frame interval is approximately $1000/60=16.7$ milliseconds. At 120 Hz, it is approximately $8.3$ milliseconds. These intervals are not budgets available exclusively to Surface code. Input, layout, drawing, compositing and other system work share the path.

Average frame rate can hide pauses. A workload may be smooth most of the time but repeatedly stall when an image decodes or a panel opens. Qualification should examine deadline misses, latency distributions and sustained behavior on named devices and release-like builds.

The portable contract does not promise identical performance across runtimes. It promises a measurable execution model and target-specific budgets. A capability can select a reduced material treatment when the full effect exceeds the supported profile.

21.6 Memoization, caching and pooling are different techniques

Memoization retains the result of a computation for repeated inputs. A cache retains useful data or a resource for future use. A pool retains storage or objects so they can be reset and reused for a different operation.

These techniques solve different problems. Pooling ordinary props or route entries can complicate identity and retain memory without improving the expensive part of the workload. Buffer reuse can help a measured serialization hotspot, provided ownership is explicit. Android's memory guidance warns that pools can be counterproductive because of retention, reset and synchronization costs. 40

Surface therefore uses pooling selectively. A lease or ownership rule must prevent a buffer from returning to a pool while another runtime still reads it. “Zero copy” is a lifetime obligation, not a label that removes ownership costs.

Memory budgets are expressed in bytes as well as object counts. One retained image can be more expensive than thousands of small model values. Hidden views can release textures or editor resources while retaining the workflow state needed to restore them.

22. Assets, lazy loading and resource delivery

22.1 An image has several sizes and several lifetimes

An image has an encoded transfer size, decoded pixel dimensions, a displayed logical size and potentially a graphics-resource footprint. These quantities are related but not equal.

A highly compressed 4096 by 4096 image still needs 64 MiB for one four-byte-per-pixel decoded buffer. Additional copies and graphics resources are separate. Downloading fewer bytes does not guarantee a small memory footprint.

This is why an asset system needs more than a preferred format. It must choose variants, reserve geometry, prioritize work, decode at useful dimensions, account for memory and release resources when their owners stop using them.

Figure 41. The resource pipeline covers both delivery and ownership. A format decision affects transfer, while size-aware decoding and resource leases affect memory and rendering cost. See the illustrated PDF for the diagram.

22.2 The manifest makes asset requirements explicit

An asset manifest identifies the resource and its available variants. Useful metadata includes dimensions or aspect ratio, encoded format, byte size, color and orientation information, fallback choices and cache/privacy policy.

The renderer can then request a variant appropriate to display constraints and pixel density. A thumbnail does not need the original camera image. A zoomable editor can request more detail when the viewport actually requires it.

The returned handle is a lease. The component owns its use while visible or retained under policy. The resource system can cache underlying data independently, but must respect its byte budget and authorization scope.

22.3 Choose formats for the asset's job

Photographs can use modern compressed formats such as WebP or AVIF where the target decoder and quality requirements support them. Simple icons often benefit from vector representation. Pixel-sensitive artwork can require lossless encoding. Video, animated images and fonts need their own delivery policies. Web image guidance treats correct dimensions and delivery behavior as important alongside format choice. 41

A single mandatory format would obscure these differences. A vector can be small yet computationally complex. A photograph can be tiny on the screen but enormous after decoding. A font subset can save bytes while accidentally omitting a script the product must display.

The manifest records what the runtime needs to choose intelligently. Untrusted media is also bounded: encoded and decoded limits, resource-origin checks and a policy for active or external content in vector assets. Privacy metadata should be removed where product policy requires it, rather than copied blindly into public delivery.

22.4 Reuse capable loaders, with the right requests

Surface should configure a proven platform loader rather than replace all image fetching and caching. For Compose, Coil's AsyncImage resolves loading size from constraints, while rememberAsyncImagePainter requires a suitable size resolver to avoid original-size loading by default. 42

The architectural contribution is the request policy. It supplies intended display size, density, priority, privacy scope and cancellation. The loader supplies its specialized decoding and cache mechanisms. A custom resource system should not discard that leverage without a demonstrated need.

Theme changes should only affect dependent resources. Tinting an existing icon need not redownload its bytes. Changing a typography family does require a new font resource and remeasurement. A different decode size belongs in the relevant cache key.

22.5 Lazy loading is not one switch

Code splitting defers feature code. Data pagination defers records. Virtualization defers view instances. Asset lazy loading defers media requests. Deferred initialization postpones an expensive subsystem. Prefetch deliberately performs likely-next work before it is requested.

Figure 42. Pagination limits retrieved data, while virtualization limits mounted view work. A small overscan region can prepare nearby rows without creating active UI for the entire dataset. See the illustrated PDF for the diagram.

These controls should be independent. A timeline may retain several pages of records while mounting only the visible rows and a small surrounding region. A heavy editor can load when opened without making the surrounding page wait. Prefetched assets can be cancelled when navigation changes.

Priorities distinguish critical, visible, nearby and speculative work. A likely web Largest Contentful Paint image should be discoverable early rather than hidden behind a blanket lazy-loading rule. High priority is selective; assigning it to every resource removes its usefulness. 43

22.6 Preserve geometry while resources arrive

An image placeholder should reserve its known aspect ratio. A skeleton should approximate the eventual layout rather than begin as a small spinner that later becomes a large panel. Fonts need deliberate fallback and loading behavior.

Figure 43. Known media geometry is reserved before the image arrives. The resulting content can fill the region without moving the message the person is reading. See the illustrated PDF for the diagram.

A font change can still cause legitimate reflow. The goal is to reduce avoidable shifts and preserve a meaningful anchor. Web font guidance discusses format, subsetting and loading choices; those choices must be combined with the application's script coverage and layout requirements. 44

Private resources have an additional lifecycle. Logout, account switching and permission revocation must affect their use and cache policy. A content hash identifies bytes; it does not grant every account permission to view them.

23. Measuring web, native and custom interfaces

Assets have a separate bounded delivery path

HLD — Arrows follow asset demand, lease and target realization. Large image payloads stay outside control/event transport. Open the diagram for full size.

23.1 Start with the user-visible question

“Is this interface fast?” is too broad for one measurement. A conversation needs quick contact feedback, responsive editing and stable scrolling. A commerce page needs essential content to appear promptly. A graph editor needs selection and drag feedback to remain responsive while a large scene changes.

Each question defines a scenario and an observation boundary. A component function completing does not automatically mean the person has seen the result. A frame callback is not a direct measurement of photons reaching the display. The metric must state what it actually observes.

Figure 44. Different measurements cover different portions of the path from input to visible result. Diagnostic render timing is useful, but it does not replace end-to-end interaction measurement. See the illustrated PDF for the diagram.

23.2 Preserve standardized metric definitions

Core Web Vitals use Largest Contentful Paint, Interaction to Next Paint and Cumulative Layout Shift. Their good thresholds are 2.5 seconds, 200 milliseconds and 0.1 respectively at the 75th percentile, with appropriate segmentation. Custom Surface metrics do not reuse those names for different events. 45

Field measurements and laboratory scenarios complement each other. Field data describes supported users and conditions. Laboratory tests help reproduce a regression. Neither a single load score nor a component gallery can establish every interaction's performance.

Layout Shift also has a specific definition. It is not a complete measure of all movement a person may find disruptive. An application should separately test scroll anchors and active controls during content insertion. 46

23.3 Native collectors have different coverage

Android vitals and Apple MetricKit provide platform-specific quality and diagnostic signals. They differ in what they collect, where they collect it and how results are delivered. Surface preserves those distinctions rather than collapsing them into one “app vitals” number. 4748

A custom-rendered canvas needs particular care. A platform metric about ordinary scrolling may not cover its actual implementation. A browser's normal content measurement may not describe when the graph drawn inside a canvas became useful.

The framework therefore defines additional scenario metrics where needed: navigation-to-usable-content, selection-to-inspector-ready, action-to-visible-feedback, decode duration, bridge backlog and retained-resource size. Each declares its start event, end event, clock, sampling and supported targets.

23.4 Correlate measurements without overwhelming the graph

The graph provides useful context: owning feature, route kind, action contract and active implementation. Surface observations can use that context in traces and diagnostics.

High-rate samples should remain in bounded local buffers or sampled traces. A span for every animation tick would add overhead and unnecessary volume. Metric labels remain bounded; individual message text or arbitrary component-instance IDs do not become global metric dimensions.

The observer is a boundary for measurements, not permission to export private state. Inspection and telemetry apply redaction, access and retention policy. The inspector itself has an overhead budget so observing the interface does not become the dominant source of missed deadlines.

23.5 Explain the cause, not just the number

A useful finding identifies what changed and which work followed. It can report that a font revision invalidated text measurement, that a broad subscription rebuilt several regions, or that an image was decoded far above its displayed size.

React's Profiler supplies render timing, but layout, paint and end-to-end interaction still need the relevant collectors. 49 Compose likewise benefits from tracing the stages that actually consumed time rather than counting every recomposition as equally expensive.

Qualification uses named release-like workloads. Android Macrobenchmark provides a suitable mechanism for scenarios such as startup and scrolling; equivalent target-specific procedures are needed elsewhere. 50

No budget should be described as a measured result before the workload is run. The architecture defines where evidence comes from and how regressions are attributed. The product's supported profiles determine the actual thresholds it must meet.