最近chrome v107的stable版本更新了,更新内容包括HEVC硬解、Align Timers、User-Agent Reduction、PerformanceAPI以及一些其它的小变化。
Align Timers:定时器对齐
概要
状态:Behind a flag
按照官方的说法,这主要是一个为了节省cpu使用率的特性(reduce overall CPU wake ups),具体来说就是将嵌套定时器的执行时间对齐到8ms(125Hz,目前的最小间隔是4ms),例如使用setTimeout的最短执行时间变成了8ms。
例子
这个特性现在需要用flag来手动开启:在chrome://flags 里打开Align delayed wake ups at 125 Hz
let last = performance.now();
function onTimer() {
setTimeout(onTimer, 5);
let now = performance.now();
console.log(`Elapsed: ${Math.round(now - last)} ms`);
last = now;
}
onTimer();
根据上面这个例子,flag关闭时定时器的执行间隔一般在5ms左右,开启后执行间隔变成约8ms。
相关内容
关于js里的定时器执行频率其实早有限制,具体可以参考developer.chrome.com/blog/timer-…
从chrome 88开始,对计时器有个更严格的频率限制,主要限制有:
- 如果一个页面被隐藏超过5分钟(例如切换到其它tab)
- 且 定时器调用链长度超过100(指setTimeout回调里又调用setTimeout的情况)
- 且 没有打开的WebRTC连接
- 且 页面30s内没有在播放媒体(静音的不算)
那么定时器的执行频率会降到约每分钟1次
在此之前,当页面被隐藏时,定时器执行频率会降低到约每秒1次
需要注意的是,非嵌套定时器(或5层以内)的执行时间是没有规定最小间隔的,例如:
let count = 0;
let last = performance.now();
function onTimer() {
if (count++ > 10) return;
setTimeout(onTimer, 0);
let now = performance.now();
console.log(`chain count ${count} Elapsed: ${Math.round(now - last)} ms`);
last = now;
}
onTimer();
上面这个例子中,前5次定时器的执行间隔都可以为0ms。关于这点,可以参考setTimeout的规范
HEVC/H.265 解码支持
概要
状态:Enabled by default
Chrome终于增加了对h265视频的默认硬件解码支持,虽然这个特性safari已经支持了一段时间,但是由于各种原因Chromium系浏览器一直没有默认支持,经过长时间的等待,现在大家终于得到这个开箱即用的特性了。
需要注意的是,h265硬件解码需要硬件和操作系统同时满足条件,一些旧的GPU可能没法使用。
具体的软硬件要求可以参考这里:github.com/StaZhu/enab…
css grid-template属性支持插值
概要
状态:Enabled by default
在grid布局里面,grid-template-columns和grid-template-rows可以用来控制网格的组成形状,从chrome107开始这些属性支持插值,也就是说transition和animation等css动画也可以应用在grid布局中了。
例子
具体效果可以参考这个demo
getDisplayMedia 增加 selfBrowserSurface、surfaceSwitching和displaySurface参数
概要
状态:Enabled by default
js可以通过getDisplayMedia来获取用户屏幕内容,可以选择录屏的范围,例如整个屏幕/某个tab/某个窗口,selfBrowserSurface可以将当前tab排除在外,避免用户意外录制当前tab的内容。
surfaceSwitching用于在共享tab的时候在页面上方显示一个按钮,显式地提示用户当前所共享的tab。
displaySurface用于控制默认选择共享的是窗口/tab还是整个屏幕,但用户依旧可以在这三者中进行选择。
例子
可以参考这个demo
<video id="video"></video>
<script>
(async () => {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
selfBrowserSurface: "exclude",
surfaceSwitching: "include"
});
const video = document.querySelector('#video');
video.srcObject = stream;
video.play();
})();
</script>
相关内容
关于录屏的一些相关参数,可以参考这篇文章:developer.chrome.com/docs/web-pl…
PerformanceAPI增加renderBlockingStatus
概要
状态:Enabled by default
在performance.getEntriesByType("resource")返回的ResourceTiming[]指标中,增加renderBlockingStatus用来表示当前资源是否会阻塞页面渲染
例子
const resourceTimingList = performance.getEntriesByType("resource")
const resourceTiming = resourceTimingList[0];
// PerformanceResourceTiming {initiatorType: 'img', nextHopProtocol: '', workerStart: 0, redirectStart: 0, redirectEnd: 0, …}
resourceTiming.renderBlockingStatus // "blocking" | "non-blocking"
User-Agent Reduction Phase 5
概要
Chrome的User-Agent Reduction计划的第五步,旨在对user-agent字段进行规范化。
User-Agent Reduction主要有两个目的,一是目前的UA包含了许多无用信息,这些信息会附带在每个请求上,而且随着版本升级变得越来越长,二是这些信息经常被作为浏览器指纹来收集用户数据(这一点我认为不是主要原因,毕竟修改后依旧有办法获取原来的具体信息)。
User-Agent Reduction分为6个步骤,目前进行到第5步,具体每一步修改的内容可以参考:www.chromium.org/updates/ua-…
例子
这里复制上面链接中的例子
| Desktop (user on Windows 8.1, for example) | |
|---|---|
| Old UA | Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.1234.56 Safari/537.36 |
| Final Reduced UA | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Safari/537.36 |
| Mobile (user on Samsung Galaxy, for example) | |
|---|---|
| Old UA | Mozilla/5.0 (Linux; Android 9; SM-A205U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.1234.56 Mobile Safari/537.36 |
| Final Reduced UA | Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36 |
| Tablet (user on Samsung Galaxy, for example) | |
|---|---|
| Old UA | Mozilla/5.0 (Linux; Android 9; SM-T810) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.1234.56 Safari/537.36 |
| Final Reduced UA | Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Safari/537.36 |
主要的变化有两个,一是固定了操作系统和硬件平台信息(需要注意这些值未来即使更新了系统也不会再变了),二是不再显示浏览器的小版本号(全部改成0)。
现在chrome将使用以Sec-CH-UA开头的一系列http headers代替原来user-agent的功能。
在默认情况下,浏览器会带上这些header:
-
sec-ch-ua: "Google Chrome";v="107", "Chromium";v="107", "Not=A?Brand";v="24"
-
sec-ch-ua-mobile: ?0
-
sec-ch-ua-platform: "macOS"
如果服务端需要客户端在子请求中附带更具体的信息,需要在响应headers中带上Accept-CH,例如:
Accept-CH: Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Model, Sec-CH-UA-Platform-Version
具体每个header的含义可以参考:www.chromium.org/updates/ua-…
同样地,现在通过navigator.userAgent也无法获取到准确的设备信息了,因此如果需要在js中获取更具体的ua信息,可以使用navigator.userAgentData对象上的接口:
await navigator.userAgentData.getHighEntropyValues([
'architecture',
'model',
'uaFullVersion',
'bitness',
'fullVersionList',
'platformVersion',
]);
URLPattern增加ignoreCase参数
概要
状态:Enabled by default
URLPattern是一个内置的路由匹配对象,默认情况下,依照规范除了url的域名部分,其它如path等部分的匹配规则都是大小写敏感的,但由于许多框架内置的路由匹配是大小写不敏感的,因此增加了ignoreCase参数,控制url中除域名以外部分的大小写匹配逻辑。
例子
const pattern1 = new URLPattern('/run/:action', 'http://localhost', { ignoreCase: true });
const pattern2 = new URLPattern('/run/:action', 'http://localhost', { ignoreCase: false });
pattern1.test('http://localhost/RUN/task1'); // true
pattern2.test('http://localhost/RUN/task1'); // false