ShadowRealms在全局对象隔离上,其运行开销与收益的权衡,究竟如何体现?
- 内容介绍
- 相关推荐
本文共计781个文字,预计阅读时间需要4分钟。
markdownShadowRealm 在全局对象隔离上没有实际运行开销,因为其根本不可用。截至 2026 年 4 月,所有主流浏览器(Chrome、Firefox、Safari)均已移除其实验性支持,Node.js 也从未将其纳入稳定 API。你无法在生产环境测量其开销,就像无法测量一台尚未出厂的发动机的油耗一样。
ShadowRealm 的“隔离”只存在于规范草案中
- 它承诺每个实例拥有独立的
globalThis、Array、Promise等内建对象,不共享原型链 - 但这种隔离是静态声明式的:不支持
import、无法调用fetch或setTimeout、不能访问 DOM —— 所有这些都被 TC39 明确认定为“与现有平台模型不兼容” - 即使你在旧版 Chrome Canary 中用
--enable-features=ShadowRealms强行启用,也会遇到:-
ReferenceError: ShadowRealm is not defined(多数版本) -
sr.evaluate('import("x")')报语法错误或静默失败 - 返回的函数在主 Realm 调用时丢失
this绑定或报TypeError: Illegal invocation
-
真正可测的隔离方案只有两个,开销特征截然不同
-
Node.js 的
vm模块- 每次
vm.Script+runInContext都触发一次完整 JS 解析 + 编译,无缓存复用 - 开销集中在首次执行:10KB 代码约增加 3–8ms CPU 时间(V8 12.x 测试)
- 优势是可控:你能显式传入
console、JSON,但必须手动过滤process、require
- 每次
-
浏览器中的
<iframe sandbox="allow-scripts">- 启动延迟高(DOM 构建 + 渲染进程通信),内存占用是
vm的 5–10 倍 - 但后续
postMessage通信成本极低(结构化克隆快于 JSON 序列化) - 关键限制:
sandbox必须不含allow-same-origin,否则隔离失效;DOM 操作只能由父页代理
- 启动延迟高(DOM 构建 + 渲染进程通信),内存占用是
最容易被忽略的一点
隔离从来不是靠“新 API”实现的,而是靠放弃便利性换来的:
- 你不能在子环境里直接
console.log,得封装成postMessage回调 - 你不能让子环境自由
import,得预加载白名单模块并显式importValue(如果它还存在) - 你甚至不能依赖
globalThis.constructor是Function,因为ShadowRealm规范里连Function构造器都计划禁用
现在所有声称“已适配 ShadowRealm”的沙箱库,实际运行时 fallback 的都是 vm 或 iframe —— 它们只是把一个已死亡的占位符当接口暴露出来。
本文共计781个文字,预计阅读时间需要4分钟。
markdownShadowRealm 在全局对象隔离上没有实际运行开销,因为其根本不可用。截至 2026 年 4 月,所有主流浏览器(Chrome、Firefox、Safari)均已移除其实验性支持,Node.js 也从未将其纳入稳定 API。你无法在生产环境测量其开销,就像无法测量一台尚未出厂的发动机的油耗一样。
ShadowRealm 的“隔离”只存在于规范草案中
- 它承诺每个实例拥有独立的
globalThis、Array、Promise等内建对象,不共享原型链 - 但这种隔离是静态声明式的:不支持
import、无法调用fetch或setTimeout、不能访问 DOM —— 所有这些都被 TC39 明确认定为“与现有平台模型不兼容” - 即使你在旧版 Chrome Canary 中用
--enable-features=ShadowRealms强行启用,也会遇到:-
ReferenceError: ShadowRealm is not defined(多数版本) -
sr.evaluate('import("x")')报语法错误或静默失败 - 返回的函数在主 Realm 调用时丢失
this绑定或报TypeError: Illegal invocation
-
真正可测的隔离方案只有两个,开销特征截然不同
-
Node.js 的
vm模块- 每次
vm.Script+runInContext都触发一次完整 JS 解析 + 编译,无缓存复用 - 开销集中在首次执行:10KB 代码约增加 3–8ms CPU 时间(V8 12.x 测试)
- 优势是可控:你能显式传入
console、JSON,但必须手动过滤process、require
- 每次
-
浏览器中的
<iframe sandbox="allow-scripts">- 启动延迟高(DOM 构建 + 渲染进程通信),内存占用是
vm的 5–10 倍 - 但后续
postMessage通信成本极低(结构化克隆快于 JSON 序列化) - 关键限制:
sandbox必须不含allow-same-origin,否则隔离失效;DOM 操作只能由父页代理
- 启动延迟高(DOM 构建 + 渲染进程通信),内存占用是
最容易被忽略的一点
隔离从来不是靠“新 API”实现的,而是靠放弃便利性换来的:
- 你不能在子环境里直接
console.log,得封装成postMessage回调 - 你不能让子环境自由
import,得预加载白名单模块并显式importValue(如果它还存在) - 你甚至不能依赖
globalThis.constructor是Function,因为ShadowRealm规范里连Function构造器都计划禁用
现在所有声称“已适配 ShadowRealm”的沙箱库,实际运行时 fallback 的都是 vm 或 iframe —— 它们只是把一个已死亡的占位符当接口暴露出来。

