在Angular项目中,仅在Chrome浏览器上出现zone.js违规警告

27

我有一个使用 @angular/cli 创建的 Angular 4 项目,当以开发模式运行应用程序时,控制台会显示这些警告:

zone.js:1489 [Violation] 'setTimeout' handler took 209ms
2[Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive.
zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
2zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive.
zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive.
zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.
2zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive.
zone.js:1157 [Violation] Added non-passive event listener to a scroll-blocking 'mousewheel' event. Consider marking event handler as 'passive' to make the page more responsive.

奇怪的是这些警告仅出现在Chrome浏览器中。(我的Chrome版本为:58.0.3029.110

  1. 这些(violation)警告代表什么意思?
  2. 这会对应用程序性能有害吗?
  3. 如何关闭/覆盖或配置zone.js以消除这些警告?

2
使用material.angularjs时遇到同样的问题。只需添加此库,问题即可解决。https://github.com/zzarcon/default-passive-events。将其包含在您的项目中即可解决这些问题。 - Narendra Singh Rathore
1个回答

32

什么是被动事件?

被动事件监听器是DOM规范中的新功能,它使开发人员可以选择更好的滚动性能,消除了滚动时阻塞触摸和滚轮事件监听器的需要。开发人员可以使用{ passive:true }注释触摸和滚轮监听器,以表示它们永远不会调用preventDefault。此功能于Chrome 51、Firefox 49中发布并登陆WebKit. 参考资料

Chrome会抛出警告...

[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive.

当您绑定鼠标滚动事件时,基本上会发出警告,您可能已经通过调用preventDefault()禁止了滚动性能或禁用了默认事件。

在被动事件中,当您尝试并仍然调用preventDefault()时,Chrome也会抛出错误。

Unable to preventDefault inside passive event listener invocation.

Firefox也有类似的错误,但似乎不像Chrome一样会抛出警告:

Ignoring ‘preventDefault()’ call on event of type ‘wheel’ from a listener registered as ‘passive’.

警告展示

运行以下代码片段并在详细模式下查看Chrome控制台。

// WILL throw violation
document.addEventListener("wheel", function(e) {
  e.preventDefault(); // prevents default browser functionality
});

// will NOT throw violation
document.addEventListener("wheel", function(e) {
  e.preventDefault(); // does nothing since the listener is passive
}, {
  passive: true
});


解决问题

关于这个问题在JavaScript中的影响,有一个类似的SO post

通过将触摸或滚轮监听器标记为被动的,开发人员承诺处理程序不会调用preventDefault()来禁用滚动。这使得浏览器可以立即响应滚动而无需等待JavaScript,从而确保用户获得可靠的平滑滚动体验。

Angular尚未实现通用/易于使用的解决方案,可以在此处进行跟进。

然而,由于TypeScript编译为JavaScript,在TypeScript中实现上述片段仍应该消除违规行为


性能影响

违规本身对应用程序的性能没有任何伤害,但是您事件函数的内容可能会有影响,因此Chrome会抛出这个警告。请注意,此警告仅在详细控制台模式下显示,并不会显示给一般用户。

据我所知,目前没有办法禁用此类警告,因为它们是由Chrome在运行时对代码的解释生成的。


抑制警告的一种方法(如果使用 preventDefault())是声明 { passive: false }。在这种情况下,错误消息似乎令人困惑,因为它要求声明处理程序为“passive”。 - akauppi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接