Firefox 新的稳定版本在 7 月底发布,带来了共享内存的回归!Firefox 79 还提供了一个新的 Promise 方法,更安全的 target=_blank
链接,逻辑赋值运算符,以及其他对 Web 开发人员感兴趣的更新。
这篇博文只提供了一些亮点;有关所有详细信息,请查看以下内容
开发者工具中的新增功能
首先,我们来看看 79 版本中 Firefox 开发者工具的添加内容。
JavaScript 日志记录和调试功能
随处可见的异步堆栈跟踪
现代 JavaScript 依赖于 Promise、async/await、事件和超时来协调代码、库和浏览器之间的复杂调度。然而,调试异步代码以了解控制流和数据流可能很困难。操作在时间上被分解。异步堆栈跟踪通过将堆栈的实时同步部分与捕获的异步部分组合起来,解决了这个问题。
现在,您可以在 Firefox JavaScript 调试器的调用堆栈、控制台错误和网络发起者中享受详细的异步执行链。
为了使此功能正常工作,JavaScript 引擎在分配 Promise 或某些异步操作开始时会捕获堆栈。然后,捕获的堆栈将被附加到捕获的任何新堆栈。
针对错误网络响应的更佳调试
服务器请求失败会导致一系列错误。以前,您必须在控制台和网络面板之间切换以进行调试,或者在控制台中启用“XHR/Requests”过滤器。在 Firefox 79 中,控制台默认显示 4xx/5xx 错误状态代码的网络请求。此外,可以展开请求/响应详细信息以检查完整详细信息。这些详细信息也存在于网络检查器中。
提示:要进一步调试、重试或验证服务器端更改,请使用“重新发送请求”上下文菜单选项。它在控制台和网络面板中都有效。您可以使用相同的参数和标题发送新请求。“编辑并重新发送”选项仅在网络面板中可用。它会打开一个编辑器,您可以在发送请求之前调整请求。
调试器突出显示代码中的错误
许多调试会话都是从记录的 JavaScript 错误跳转到调试器开始的。为了简化此流程,现在会在调试器中突出显示错误,并显示其在相应源代码中的位置。此外,相关详细信息将在悬停时显示,在代码上下文中以及暂停的变量状态中显示。
我们要感谢核心贡献者 Stepan Stava,他已经开始构建此功能,进一步模糊了日志记录和调试之间的界限。
在调用堆栈中重新启动帧
当您从调试器中重新启动帧时,调用堆栈会将执行指针移至函数的顶部。需要注意的是,变量状态不会重置,这允许在当前调用堆栈内进行时间旅行。
“重新启动帧”现在在调试器的调用堆栈中作为上下文菜单选项可用。同样,我们要感谢 Stepan Stava 的贡献,调试器用户会从 Chrome 和 VS Code 中认识到这一功能。
更快的 JavaScript 调试
此版本的性能改进加快了调试速度,尤其是对于包含大型文件的项目。我们还修复了一个影响评估密集型代码模式的瓶颈,现在可以正常工作了。
检查器更新
针对 SCSS 和 CSS-in-JS 的更好的源地图引用
我们改进了所有面板中的源地图处理,因此,从检查器侧面板打开 SCSS 和 CSS-in-JS 源文件现在更加可靠。您可以快速从检查器侧面板中的规则定义跳转到 样式编辑器 中的原始文件。
新的检查辅助功能属性上下文菜单
辅助功能检查器 现在始终在浏览器上下文菜单中可用。您可以直接在辅助功能面板中打开元素,以检查 ARIA 属性并运行审核。
更多工具更新
- 网络面板中的“禁用缓存”选项现在还禁用了 CORS 预检请求 缓存。这使得迭代 Web 安全 设置更加容易。
- 贡献者 KC 统一了控制台中显示的被阻止请求的样式,使其与网络面板中的显示一致。
- Richard Sherman 扩展了工具提示的范围,现在它们会描述在控制台和调试器中预览的对象值的类型和值。
- 为了合并侧边栏选项卡,Farooq AR 将网络的 WebSocket“消息”选项卡移至“响应”选项卡。
- 调试器对“黑盒”的引用已重命名为“忽略”,以与其他工具的措辞保持一致,并使其更具包容性。还要感谢 Richard Sherman 对此更新的贡献!
Web 平台更新
target=_blank
链接的隐式 rel=noopener
为了防止 DOM 属性 window.opener
被不可信的第三方网站滥用,Firefox 79 现在会自动为所有包含 target=_blank
的链接设置 rel=noopener
。以前,您必须手动设置 rel=noopener
,才能为每个使用 target=_blank
的链接使 window.opener = null
。如果您需要 window.opener
,请使用 rel=opener
显式启用它。
SharedArrayBuffer 回归
在 2018 年初,考虑到 Spectre,共享内存 和高分辨率计时器实际上被 禁用。在 2020 年,一种新的、更安全的方法已标准化,以重新启用共享内存。作为基本要求,您的文档需要位于安全上下文中。对于顶级文档,您必须设置两个标头才能隔离文档的跨域
Cross-Origin-Opener-Policy
设置为same-origin
。Cross-Origin-Embedder-Policy
设置为require-corp
。
要检查跨域隔离是否成功,您可以针对 crossOriginIsolated
属性进行测试,该属性可用于窗口和工作程序上下文
if (crossOriginIsolated) {
// use postMessage and SharedArrayBuffer
} else {
// Do something else
}
在文章 安全地恢复共享内存 中了解更多信息。
Promise.any 支持
新的 Promise.any()
方法接受一个可迭代的 Promise
对象,一旦可迭代对象中的某个 Promise 完成,它就会返回一个单独的 Promise,解析为该 Promise 的值。本质上,此方法与 Promise.all()
相反。此外,Promise.any()
与 Promise.race()
不同。重要的是 Promise 完成的顺序,而不是哪个 Promise 首先结算。
如果提供的 Promise 全部被拒绝,则会返回一个名为 AggregateError
的新错误类。此外,它还会指示拒绝的原因。
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3];
Promise.any(promises).then((value) => console.log(value));
// quick wins
逻辑赋值运算符
JavaScript 已经支持各种 赋值运算符。 逻辑赋值运算符提案 指定了三个新的逻辑运算符,现在这些运算符在 Firefox 中默认启用
这些新的逻辑赋值运算符具有与现有的 逻辑运算 相同的短路行为。仅当逻辑运算会计算右侧时才会执行赋值。
例如,如果“lyrics”元素为空,则将 innerHTML
设置为默认值
document.getElementById('lyrics').innerHTML ||= '<i>No lyrics.</i>'
这里,短路特别有用,因为元素不会被无意义地更新。此外,它不会造成额外的解析或渲染工作或失去焦点之类的意外副作用。
弱引用
在 JavaScript 中,对象之间的引用通常是一对一的:如果你有一个指向某个对象的引用,使其无法被垃圾回收,那么它所引用的所有对象都无法被回收。在 ES2015 中添加了 WeakMap
和 WeakSet
之后,这种情况发生了改变,你现在需要同时拥有指向 WeakMap
的引用和一个键才能阻止对应的值被回收。
从那时起,JavaScript 就没有提供更高级的 API 来创建弱引用,直到现在。 弱引用提案 添加了此功能。现在 Firefox 支持 WeakRef
和 FinalizationRegistry
对象。
转到 MDN 文档查看 WeakRef
的示例用法。垃圾收集器很复杂,因此在使用 WeakRefs 之前,请务必阅读 此注意事项。
WebAssembly
Firefox 79 包含新的 WebAssembly 功能
- 首先,为 批量内存操作 提供了七个新的内置操作。例如,复制和初始化允许 WebAssembly 以更有效、更高效的方式模拟
memcpy
和memmove
等本机函数。 - 现在支持 引用类型提案。它提供了一种新的类型
externref
,可以保存任何 JavaScript 值,例如字符串、DOM 引用或对象。wasm-bindgen
文档包含从 Rust 中利用externref
的指南。 - 随着 SharedArrayBuffer 对象的回归,我们现在还能够支持 WebAssembly 线程。因此,现在可以跨运行在不同 Web Worker 中的多个 WebAssembly 实例共享 WebAssembly 内存对象。结果如何?Worker 之间非常快速的通信,以及 Web 应用程序的性能大幅提升。
WebExtensions 更新
从 Firefox 79 开始,选项卡管理扩展的开发人员可以改善用户切换选项卡时的感知性能。新的 tabs.warmup()
函数将准备显示选项卡。开发人员可以在他们预期选项卡切换时使用此函数,例如,当将鼠标悬停在按钮或链接上时。
如果您是扩展开发人员,并且您的扩展在多个设备之间同步项目,请注意,我们已将 storage.sync
区域 移植到基于 Rust 的实现。在已安装的扩展第一次尝试在 Firefox 79 中访问 storage.sync
数据时,将自动迁移已存储在现有配置文件中的扩展数据。需要注意的是,新实现强制执行客户端配额限制。您应该估算您的扩展在本地存储了多少数据,并测试您的扩展在数据限制超出后如何运行。查看 此文章,了解测试说明以及有关此更改的更多信息。
查看 附加组件博客,了解 Firefox 79 中对 WebExtensions API 的更多更新!
总结
与往常一样,请随时在评论中分享建设性反馈并提出问题。感谢您将 Firefox 保持最新!
关于 Florian Scholz
Florian 是 MDN Web Docs 的内容主管,撰写有关 Web 平台技术的文章并研究浏览器兼容性数据。他住在德国不来梅。
关于 Chris Mills
Chris Mills 是 Mozilla 的高级技术作家,他撰写有关开放 Web 应用程序、HTML/CSS/JavaScript、A11y、WebAssembly 等方面的文档和演示。他喜欢玩弄 Web 技术,并偶尔在会议和大学发表技术演讲。他曾为 Opera 和 W3C 工作,喜欢演奏重金属鼓和喝好酒。他和他的妻子以及三个美丽的女儿住在英国曼彻斯特附近。
关于 Harald Kirschner (digitarald)
Harald “digitarald” Kirschner 是 Firefox 开发人员体验和工具的产品经理,致力于赋能创作者编写、设计和维护一个对所有人开放且可访问的网络。在他在 Mozilla 的 8 年时间里,他在性能、Web API、移动、可安装 Web 应用程序、数据可视化和开发人员推广项目中积累了技能。
一条评论