Will Liu

Chromium Blog: Chrome 66 Beta: CSS Typed Object Model, Async Clipboard API, AudioWorklet

原文链接: blog.chromium.org

Chrome 66 Beta: CSS Typed Object Model, Async Clipboard API, AudioWorklet

除非额外注明,以下描述的更新皆适用于 Android, Chrome OS,Linux,macOS 和 Windows 平台 Chrome Beta 渠道的最新发布。Chrome 66 的全部功能列表在 ChromeStatus 上可以查看到。

ImageBitMap Rendering Context <canvas>

以前把一张图片渲染到 canvas 上要包含两个部分,首先创建一个<img> 标签,然后把其内容渲染到 canvas 上。这就导致内存中存在图片的多份拷贝。一种新的 rendering context 通过避免内存复制简化了 ImageBitMap 对象的显示步骤,提高了渲染效率。本例展示了如何使用 ImageBitmapRenderingContext. 本质上它只是转移图片像素的所有权。该例子把图片像素从一个 blob 转移到一个 <canvas>,其实像素也能在 <canvas> 元素之间转移。值得注意的是这个 blob 是被压缩过的所以它在内存中并不是一份全量的拷贝。

const image = await createImageBitmap(imageBlob);
const canvas = document.createElement('canvas');
const context = canvas.getContext('bitmaprenderer');
context.transferFromImageBitmap(image);
canvas.toBlob((outputJPEGBlob) =>
{ // Do something with outputJPEGBlob. }, 'image/jpeg');

如果这里不使用 createImageBitmap()imageBlob 将会延迟解码,这将导致卡顿。另一方面,createImageBitmap() 是异步的,使用之前已经完全解码了,避免了卡顿。例如一个 WebGL 游戏可以使用这个功能在游戏进行中一边在后台加载新的贴图。

CSS Typed Object Model

以前开发者想要操作 CSS 属性不得不操作浏览器返回的字符串,然后浏览器再把字符串转化回类型化表示。让事情更糟的是,当开发者尝试用 JavaScript 读取 CSS 属性值时,这个类型化的值被转成了一个字符串。在 66 版中,Chrome 实现CSS Typed Object Model ( OM ) Level 1Houdini 的一部分,CSS properties 的子集。Typed OM 通过把 CSS 值暴露为类型化 JavaScript 对象而非字符串,减少了开发者和浏览器的负担。Typed OM 在允许高性能操作 CSS 属性值的同时,也使得开发者能写出维护性更高的更易于理解的代码。这个简短的例子阐释了这一点。之前如果我想设置一个元素的不透明度我会这样做:

el.style.opacity = 0.3;
el.style.opacity === "0.3"

有了 CSSOM:

el.attributeStyleMap.set("opacity", CSS.number("0.3"));
el.attributeStyleMap.get("opacity").value === 0.3 

上面返回的值类型是 CSSUnitValue, 它比字符串更容易操作。

Asynchronous Clipboard API

新的异步剪贴板 API 提供了一种基于 promise 的方式来读写剪贴板。它比在 Chrome 43 中发布的老的 execCommand('copy') API 更加容易,同时还集成了 Permissions API。在未来的 Chrome 发布中,富类型数据,包括图片,也将得到支持。让我们做一些简单的文本读写操作来品一品这个 API。

try { 
    await navigator.clipboard.writeText("Hello, clipboard.");
} catch { 
    console.error("Unable to write to clipboard.");
} 

相似地,读取文本:

const data = await navigator.clipboard.readText();
console.log("From the clipboard:", data);

要获取更多信息,包括如何使用 API 的安全性和授权,阅读 Unblocking Clipboard Access ,查看我们的样例.

AudioWorklet

老的 ScriptProcessorNode 是异步的,并且需要线程切换,这会导致音频输出不稳定。AudioWorklet 对象提供了一种新的同步 Javascript 执行上下文,允许开发者以编程方式无延迟地控制音频,使音频输出有更高的稳定性。在 Google Chrome Labs 你可以看到代码示例。除 AudioWorklet 之外,还提供了其他的 worklet API。 Chrome 65/Opera 52 发布了 PaintWorkletAnimationWorklet 也在计划中。在 AudioWorklet 发布后的某个时候,ScriptProcessorNode 将被废除。

Other Features in this Release

Blink > Animation

addaccumulate 组合操作旨在构建模块化动画。addaccumulate 关键字即将在 Chrome 中得到支持。那时它们不再会抛出错误。这是为了与 Firefox 和其他实现保持兼容性。

Blink > CSS

CSS 有两个新特性。

  • 根据 CSS Values and Units Module Level 4标准,数学表达式 calc(), min(), 和 max() 现在在媒体查询中得到了支持。这个更新使函数表达式与其他类型的规则一致,在允许数字的地方,也允许使用这些函数。

  • rgb()rgba() 函数现在支持浮点数值。

Blink > Feature Policy

默认地,deviceorientation, deviceorientationabsolute, 和 devicemotion 事件现在限制在顶级文档或者同源的子 frame 中触发,效果和在 feature policy 中把这些特性设置为 'self' 一样。要修改这个行为表现,需要显式地启用或禁用相关的特性

Blink > File API

如果尝试从无效的或者不存在的 blob URL 读取内容,File API 现在会得到网络错误而非404 错误。

Blink > Forms

HTML forms 有两个特性。

  • 根据规范要求 <textarea> 元素和 <select> 元素现在支持 autocomplete 属性。
  • 根据 HTML 规范要求), 可更改的 checkbox 现在会触发3次事件,一次 click 事件, 接着一次 input 事件,然后触发一次 change 事件。之前只会触发 clickchange 事件。

Blink > Fullscreen

如果全屏模式下的页面打开了一个弹窗并调用 window.focus() 获得焦点,页面将退出全屏模式。如果弹窗通过其他方式获得焦点则页面不会退出全屏。

Blink > GetUserMedia

MediaStreamTrack 接口上新增了名为 getCapabilities() 的方法,它会返回 MediaTrackCapabilities 对象,指明了每个可约束属性的值或者值的范围。结果因设备而异。

Blink > JavaScript

Javascript 有数个改变。

  • Function.prototype.toString() 函数现在能精确地返回源码中的内容。它包含空格和其他可能未被使用的文本。例如,如果 function 关键字和函数名字之间有注释,注释同时也会被返回。

  • JSON 现在是 ECMAScript 的语法子集,字符串中允许出现行分隔符 (U+2028)和段落分隔符 (U+2029)。

  • try 语句的 catch 从句现在支持无参数形式了。

  • 除已经实现的 String.prototype.trim() 外,现在 String.prototype.trimStart() and String.prototype.trimLeft() 可以使用了,是修剪字符串前后空白的标准方法。为保持后向兼容,非标准的 trimLeft()trimRight() 作为别名保留了下来。

  • Array.prototype.values() 返回一个新的包含数组中的索引值的迭代对象。

Blink > Layout

Layout 有两个新特性。

  • CSS gutter 属性移除了 grid 前缀:
    • grid-gap 变成 gap
    • grid-row-gap 变成 row-gap
    • grid-column-gap 变成 column-gap

这三个属性的默认值都是 normal,带前缀的属性变成新属性的别名。值得注意的是,column-gap 是一个已经存在的属性,在 css-multicol 中就已经使用了。

  • display 属性是 table-row, table-row-group, table-header-group, table-footer-group, table-cell, 和 table-caption 并且拥有 transform 属性的元素现在是固定定位元素的包含块了。Blink 目前还没有使<tr>, <tbody>, <tfoot>, and <thead> 成为固定定位元素的包含块。

Blink > Media

Media 有两个新特性。

  • 正如早先声明的,autoplay 目前只有在 视频不会播放声音,在用户点击或者触摸之后,或者(对于桌面系统)当用户之前在此站点表露了播放媒体的兴趣的情况下有效。这将减少首次打开一个网页时意料之外地播放带声音的视频的情况。
  • 媒体性能和解码信息 API 允许网站获取更多的关于客户端解码能力的信息。这使得网站可以给用户提供更有信息感知能力的媒体流,避免一些糟糕场景的发生,例如网站只根据带宽和屏幕尺寸而错误地选择了客户端无法流畅地高效能解码的分辨率。

Blink > Network

Fetch API 有两个新特性。

  • Request 对象目前支持 keepalive 属性,允许在 tab 关闭后继续 fetch 请求。通过传递布尔值给构造器初始化对象,可以启用这个特性。其值可以通过 request 对象本身读取。该属性还可以和sendBeacon() 一起使用。
  • 新的 AbortSignalAbortController 接口允许取消 fetch 请求。要实现这个功能,你需要创建一个 AbortController 对象,把它的 signal 属性以 option 形式传递给 fetch ,通过调用 abortController.abort() 即可取消 fetch。在我们的这篇文章可中止的 fetch 可以得到更多的信息。下方是一个小代码示例:
const controller = new AbortController();
const signal = controller.signal;
const requestPromise = fetch(url, { signal });
// Abort the fetch: controller.abort();

Blink > ServiceWorker

Service workers 有两个变化.

  • 如果 request 是 same-origin 模式,response 是 CORS 类型,Service worker 不再允许对这种请求进行响应。这是最近 Fetch 规范添加的安全措施。
  • FetchEvent.clientId 未设值,现在将返回空字符串而非 null. 例如浏览器导航请求,就会发生这种情况。

Blink > WebRTC

依照规范,Chrome 现在支持 RTCRtpSender.dtmf 属性,用来替代 还未废除的 CreateDTMFSender()

废弃和互用性提升

Blink > CSS

object-positionperspective-origin 属性不再接受类似 top right 20% 的这种三参数值。这种改变同样适用于基础形状和渐变。有效的位置值必须是1个、2个或者4个参数的值。

Blink > HTML

应规范改变,ImageCapture 被移除。

Blink > Input

应规范改变,document.createTouch()document.createTouchList() 被移除。

Blink > Web Audio

应规范改变,AudioParam.prototype.value 更改的自动解压缩从 Chrome 中被移除。如果你想对 AudioParam 的更改平滑处理,使用 AudioParam.prorotype.setTargetAtTime()