After some of the replies, I gave this a bit more thought, and I came up with an entirely-different design that (IMHO) has a much better security model — and which I personally like a lot better. It eschews webpage-supplied Arbitrary Code Execution altogether, while still letting the user style the perf-visualization charts to match the "theme" of the embedding page. (Also, as a bonus, this version of the design leans more heavily on existing sandboxing features, rather than having to hypothesize new ones!)

1. Rather than having the page-perf API be a Web API "only available on specific origins" or "only available to weirdly-sandboxed Service Workers", just make it a WebExtension API. One with its own WebExtension manifest capability required to enable it; where each browser vendor would only accept WebExtensions requesting that particular capability into their Extension Stores after very thorough vetting.

(Or in fact, maybe browser vendors would never accept third-party WebExtensions with this capability into their Extension Stores; and for each browser, the capability would only be used in a single extension, developed by the browser vendor themselves. This would then be analogous to the existing situation, where the Web API is only available on a first-party domain controlled by the browser vendor; but as this would rely on the existing WebExtensions capabilities model, there would be no need for a separate one-off "WebAPI but locked to an origin" security-model. Also, unlike with a "WebAPI but locked to an origin" capability, you could play with this capability locally in an unpacked extension!)

2. Browsers that want to offer this "visualize the performance of the current page" ability as a "thing the browser can do", would just bundle their first-party WebExtension that holds this capability [and the "access current tab" capability] as a pre-installed + force-enabled component of the browser, hidden from the extensions management view. (I believe that this is already a thing browsers do — e.g. I believe Chrome implements its PDF viewer this way.)

3. This WebExtension would consist, at its core, of an extension page (https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...), that could be embedded into webpages as an iframe. This extension page would contain a script, which would use the WebExtension version of the page-perf API to continuously probe/monitor "the tab this instance of the extension-page document lives within." On receiving a perf sample, this script would then render the sample as a datapoint, in a chart that lives in some sense in the extension page's own DOM. There'd be no Service Worker necessary.

(Though, for efficiency reasons, the developer of this WebExtension might still want to split the perf-API polling out into a Service Worker, as a sort of "weak-reference perf provider" that the extension page subscribes to messages from + sends infrequent keepalive polls to. This would ensure that the Service Worker would unload — and so stop polling the page-perf API — both whenever the extension page's tab goes inactive, and whenever the browser unloads extension Service Workers generally [e.g. whenever the lid of a laptop is closed.] The page-perf API could itself be made to work this way... but it's easier to take advantage of the existing semantics of Service Worker lifetimes, no?)

4. But is there an existing API that allows a web-origin page to access/embed an extension page, without knowing the extension's (browser-specific) extension ID? Yes! Just like native apps can register "app intents", WebExtensions can register URI protocol handlers! (https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...) The performance-visualization WebExtension would register a protocol_handler for e.g. ext+pageperf:// , and then a page that wants to render its own perf would just create an <iframe allowTransparency="true" src="ext+pageperf://..." /> and shove it into the DOM. The privileged-origin-separation restrictions for iframes, would then stop the (web-origin, lower-privilege-level) page from introspecting the DOM inside the (extension-origin, higher-privilege-level) iframe — accomplishing the same thing that the "make the Canvas into an opaque handle" concept did in the previous design, but relying 100% on already-standardized security semantics of existing browser features.

---

But how would the webpage style the extension page to match itself? Well, that depends on what the extension page is doing to render the metrics.

An elegant assumption would be that the page-perf extension page is creating + incrementally updating an SVG DOM that lives embedded in the page's DOM — on each frame, appending new vector elements (e.g. bezier control-points) to that SVG's DOM to represent new datapoints in the time-series. (I believe e.g. Grafana's charting logic works this way.)

If this is the case, then all the parent page needs, is a way to pass a regular old CSS stylesheet to the extension page; which the extension page could then embed directly into its own <head>. Just have the parent page construct a <style> Element, and then call:

perfIframe.postMessage('applyStyles', {transfer: constructedStyleElement})

(And the beauty of doing that, is that once you embed the transferred <style> from the webpage into the extension page, the very same privileged-origin-separation logic will kick in again, preventing the extension pages from loading insecure web-origin content from an origin not in the extension's manifest's whitelisted origins. Which in turn means that, despite the webpage author being able to write e.g. `background: uri(...)` in their stylesheet, and despite the extension page doing nothing to explicitly filter things like that out of the stylesheet before loading it, the extension page would get to the "making a network request" part of applying that style, hit a security violation, and fail the load. Thereby neutering the ability of the page developer to use web-origin URL-references within a stylesheet as a side-channel for communicating anything about the metrics back to them!)

---

And all of this would be easily made cross-browser. You'd need a little standalone "Browser Support for Embedded Performance Visualizations" spec, that specifies two things:

1. a well-known URI scheme, for each browser's built-in page-perf extension to register a protocol_handler for. (Since it's standardized, they can drop the "ext+" part — it can just be `pageperf://`.)

2. a fixed structure for the page-perf extension page's metrics-visualization DOM — i.e. a known hierarchy of elements with specific `id` and `class` attributes (think CSS Zen Garden) — so that the same webpage-author-supplied stylesheets will work to style every browser's own metrics-chart implementation. (This would seem constraining, but remember that WebComponents exist. Standardize a WebComponent for the metrics chart, and how styles affect it. Browser vendors are then free to implement that WebComponent however they like in their own impl of the extension. Very similar to how browser vendors are free to implement the internals of a new HTML element, actually — in fact, in theory, for maximum efficiency, browsers could even implement this WebComponent's shadow-DOM in their renderers in terms of a custom "internal" HTML element!)