ShadowRealms在全局对象隔离上,其运行开销与收益的权衡,究竟如何体现?

2026-04-27 18:311阅读0评论SEO问题
  • 内容介绍
  • 相关推荐

本文共计781个文字,预计阅读时间需要4分钟。

ShadowRealms在全局对象隔离上,其运行开销与收益的权衡,究竟如何体现?

markdownShadowRealm 在全局对象隔离上没有实际运行开销,因为其根本不可用。截至 2026 年 4 月,所有主流浏览器(Chrome、Firefox、Safari)均已移除其实验性支持,Node.js 也从未将其纳入稳定 API。你无法在生产环境测量其开销,就像无法测量一台尚未出厂的发动机的油耗一样。


ShadowRealm 的“隔离”只存在于规范草案中

  • 它承诺每个实例拥有独立的 globalThisArrayPromise 等内建对象,不共享原型链
  • 但这种隔离是静态声明式的:不支持 import、无法调用 fetchsetTimeout、不能访问 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 测试)
    • 优势是可控:你能显式传入 consoleJSON,但必须手动过滤 processrequire
  • 浏览器中的 <iframe sandbox="allow-scripts">

    • 启动延迟高(DOM 构建 + 渲染进程通信),内存占用是 vm 的 5–10 倍
    • 但后续 postMessage 通信成本极低(结构化克隆快于 JSON 序列化)
    • 关键限制:sandbox 必须不含 allow-same-origin,否则隔离失效;DOM 操作只能由父页代理

最容易被忽略的一点

隔离从来不是靠“新 API”实现的,而是靠放弃便利性换来的:

  • 你不能在子环境里直接 console.log,得封装成 postMessage 回调
  • 你不能让子环境自由 import,得预加载白名单模块并显式 importValue(如果它还存在)
  • 你甚至不能依赖 globalThis.constructorFunction,因为 ShadowRealm 规范里连 Function 构造器都计划禁用

现在所有声称“已适配 ShadowRealm”的沙箱库,实际运行时 fallback 的都是 vmiframe —— 它们只是把一个已死亡的占位符当接口暴露出来。

本文共计781个文字,预计阅读时间需要4分钟。

ShadowRealms在全局对象隔离上,其运行开销与收益的权衡,究竟如何体现?

markdownShadowRealm 在全局对象隔离上没有实际运行开销,因为其根本不可用。截至 2026 年 4 月,所有主流浏览器(Chrome、Firefox、Safari)均已移除其实验性支持,Node.js 也从未将其纳入稳定 API。你无法在生产环境测量其开销,就像无法测量一台尚未出厂的发动机的油耗一样。


ShadowRealm 的“隔离”只存在于规范草案中

  • 它承诺每个实例拥有独立的 globalThisArrayPromise 等内建对象,不共享原型链
  • 但这种隔离是静态声明式的:不支持 import、无法调用 fetchsetTimeout、不能访问 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 测试)
    • 优势是可控:你能显式传入 consoleJSON,但必须手动过滤 processrequire
  • 浏览器中的 <iframe sandbox="allow-scripts">

    • 启动延迟高(DOM 构建 + 渲染进程通信),内存占用是 vm 的 5–10 倍
    • 但后续 postMessage 通信成本极低(结构化克隆快于 JSON 序列化)
    • 关键限制:sandbox 必须不含 allow-same-origin,否则隔离失效;DOM 操作只能由父页代理

最容易被忽略的一点

隔离从来不是靠“新 API”实现的,而是靠放弃便利性换来的:

  • 你不能在子环境里直接 console.log,得封装成 postMessage 回调
  • 你不能让子环境自由 import,得预加载白名单模块并显式 importValue(如果它还存在)
  • 你甚至不能依赖 globalThis.constructorFunction,因为 ShadowRealm 规范里连 Function 构造器都计划禁用

现在所有声称“已适配 ShadowRealm”的沙箱库,实际运行时 fallback 的都是 vmiframe —— 它们只是把一个已死亡的占位符当接口暴露出来。