v149 · Clipboard · Async Clipboard API

Selective Clipboard Format Read

Chrome 149 makes navigator.clipboard.read() lazy: instead of fetching all clipboard formats from the OS immediately, it returns ClipboardItem objects with only the MIME type list. Actual data is read only when getType() is called — reducing CPU work, power consumption, and startup latency for clipboard-reading operations.

concepts

  1. Lazy Read Demo

    Copy content to the clipboard, call read(), then request only the formats your app needs via getType(). The demo shows which formats are available without reading any data upfront, then fetches specific formats on demand.

  2. Eager vs. Lazy Comparison

    Side-by-side comparison of the old eager-read behaviour (all format data fetched on read()) versus the new lazy-read behaviour (only the type list is fetched on read(); data arrives only on getType()). Shows the performance implications.

  3. Format Priority Chain

    Step through a priority-ordered format list — HTML → plain text → PNG → JSON — checking availability for free and triggering exactly one OS clipboard read for the best match found. Shows how lazy reads make format negotiation virtually free.

  4. Type Inspector

    Step through a clipboard read call-by-call, with a cost badge on each step. After read() returns you see all available MIME types instantly (zero OS reads). Then tick which formats you want and click Fetch — only those formats trigger an OS read. Counter tracks checks, fetches, and fetches avoided.

  5. Paste Router

    Four typed drop targets — plain-text, HTML, image, and smart any-format — each calling getType() only for the MIME types they accept. Press Ctrl+V (or the Paste button) and watch the routing log show which formats were checked for free, which were fetched, and which were completely skipped for each target.

  6. Format Cost Meter

    Configure a realistic clipboard payload from four presets — Office paste (RTF+HTML+text), web page copy, screenshot, or code snippet — then check which formats your app actually reads. The cost meter shows the estimated decode time for each format and computes the total for eager (all formats) vs lazy (only your formats). A green savings banner shows the percentage reduction from Chrome 149's lazy-read path.

    Interactive Performance MIME types

why it shipped

The old navigator.clipboard.read() API eagerly fetched data for all available clipboard formats as soon as it was called. If the clipboard contained a large image plus HTML plus plain text, all three were deserialised and decoded before the API resolved — even if the app only needed plain text. On complex clipboards (large Office documents, high-resolution images), this produced noticeable latency spikes and unnecessary CPU and memory usage. Chrome 149 changes the contract: read() resolves with ClipboardItem objects that know which MIME types are available but have not yet read their data. Only when clipboardItem.getType('text/plain') is called does Chrome go to the OS clipboard for that specific format's bytes. Sites that only care about one format now pay only for that format.

the new contract

// Chrome 149+: read() does NOT read any data yet
const items = await navigator.clipboard.read();

for (const item of items) {
  // item.types is available immediately — no OS clipboard access needed
  console.log(item.types); // e.g. ['text/plain', 'text/html', 'image/png']

  // Only this call triggers an OS clipboard read:
  const blob = await item.getType('text/plain'); // Only text/plain data read
  const text = await blob.text();
}

// Old behaviour (Chrome <149): read() fetched all format data eagerly

references

implementation reference

Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗