Passive Event Listener

article/2025/10/26 5:52:13

起源

最近打开项目随便点点,控制台就开始报警:在这里插入图片描述

Added non-passive event listener to a scroll-blocking ‘mousewheel’ event. Consider marking event handler as ‘passive’ to make the page more responsive

可以看到警告信息是element-uiecharts两个库发出来的, 原因是使用了mousewheelwheel两个事件,但是却没有传递passive参数。

什么是passive参数?

passive adj.消极的,被动的

打开MDN,搜索addEventListener可以看到,addEventListener传递的第三个参数option中有passive选项,它设置为true时表示不会调用preventDefault()方法。

那么问题来了:一个事件是否调用preventDefault()对浏览器有什么影响嘛?

preventDefault与浏览器

对于一个滚动事件mousewheel(非标准)/touch(移动端事件)/wheel(标准)来说,浏览器需要先去调用他的回调函数,然后再去执行默认行为(在这里是滚动)。然而执行回调函数是需要时间的,如果回调函数中放了一个耗时的循环,它就会等待这个循环执行完再去滚动,那么页面表现就是滑动滚轮后的一段时间页面才会滚动,会有很明显的延迟感。

除此之外,由于执行回调函数需要浏览器的主线程,因此当主线程忙着执行其他任务时就会来不及执行回调函数,页面同样会出现延迟感。

一个小实验——耗时的回调函数

我们让一个页面的滚动事件里执行一段耗时的程序,可以很明显的看出效果

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><li>123</li><!-- 省略100个li,vscode输入li{123}*100即可快速生成 --><script>function fib(n) {if (n == 1 || n == 2) return n;return fib(n - 2) + fib(n - 1);}window.addEventListener("wheel",async (e) => {console.log(fib(40));},{ passive: false });</script></body>
</html>

当页面滚动时,求斐波那契数列,经过我的多次测试,我的电脑将n设置为40效果比较好,n太低了算的太快效果看不出来,太高了页面直接卡死崩溃了。

滑动滚轮后,页面无反应,等过了约1s后页面才开始滚动,并且控制台出现如下信息:

Handling of 'wheel' input event was delayed for 1450 ms due to main thread being busy. Consider marking event handler as 'passive' to make the page more responsive.
由于主线程繁忙,'wheel'输入事件的处理延迟了1450毫秒。 考虑将事件处理程序标记为“passive”,以使页面响应更快。  

在这里插入图片描述

可以看到浏览器发现了这个wheel事件的回调函数时间太长了,推荐开发者设置passive属性,那么我们将passive设置为true试一下

将passive设置为true后,虽然控制台依然会有很明显的延迟输出,但是滑动滚轮时页面很流畅,并不卡顿

一个小实验——繁忙的主线程

这次我们给页面添加一个计算按钮,给按钮注册一个点击后计算斐波那契数据列的事件,当点击按钮后立刻滑动滚轮查看页面表现

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><button>calc</button><li>123</li><!-- 省略100个li,vscode输入li{123}*100即可快速生成 --><script>const btn = document.querySelector('button')btn.onclick = function(){fib(41)}function fib(n) {if (n == 1 || n == 2) return n;return fib(n - 2) + fib(n - 1);}window.addEventListener("wheel",async (e) => {console.log('wheel');},{ passive: false });</script></body>
</html>

结果发现点击后立马滑动滚轮,页面无反应,约2s后才有滚动效果,此时控制台也会打印出警告:

Handling of 'wheel' input event was delayed for 1279 ms due to main thread being busy. Consider marking event handler as 'passive' to make the page more responsive.
由于主线程繁忙,'wheel'输入事件的处理延迟了1279毫秒。 考虑将事件处理程序标记为“passive”,以使页面响应更快。  

后面的就不细说了,将passive设置为true后,再执行上述操作,页面滚动就很流畅了

为什么设置为passive就不卡了呢?

在没有passive的时候,浏览器会等待回调函数的执行,然后再去执行滚动操作

设置passive后,滑动滚轮时浏览器会直接对内容快照(相当于给当前页面拍了一张照片)进行滑动处理,因此滑动会很流畅

解决passive警告

先别急着装!!

本项目是vue项目,我使用了default-passive-events这个包来解决passive警告,这个包的原理是给每一个事件监听器都添加一个passive:true

  1. npm i default-passive-events -S 安装
  2. main.js中添加import 'default-passive-events'

前面说过,本项目中的这个警告是element-uiecharts两个库导致的,虽然在大部分场景下可以解决这个报警,但是当这两个库中确实有些事件调用了preventDefault时,你稍微滑动下就会疯狂报错,因此一定要慎用

使用default-passive-events导致的报错

如果项目中确实有方法需要调用preventDefault,而我们又引入了default-passive-events这个包,这个时候控制台就会疯狂报错

Unable to preventDefault inside passive event listener invocation.

因为我们明明告诉浏览器不会阻止默认行为了,可我们的代码还是阻止了。

目前的解决办法似乎只有不用这个包,继续忍受着passive警告,毕竟警告总比报错好一点

参考

MDN关于passive的介绍

让页面滑动流畅得飞起的新特性:Passive Event Listeners


http://chatgpt.dhexx.cn/article/DQlDMkdH.shtml

相关文章

passive的作用和原理

passived到底有什么用&#xff1f; passived主要用于优化浏览器页面滚动的性能&#xff0c;让页面滚动更顺滑~~BetterScroll&#xff1a;可能是目前最好用的移动端滚动插件 passived产生的历史时间线 addEventListener()&#xff1a;大家都是认识的&#xff0c;为dom添加触发…

Java并发编程—CompletableFuture的介绍和使用

在博主上一篇博客介绍中&#xff0c;Java并发编程—java异步Future的迭代过程_小魏快起床的博客-CSDN博客&#xff0c;这里面给大家分析了Future的使用过程和一些存在的问题&#xff0c;那么针对里面出现的阻塞问题&#xff0c;博主将在这一篇文章给大家介绍清楚 &#x1f34f…

Java8 CompletableFuture runAsync等使用学习总结 submit() execute()等

一般的 Executors 的 execute以及submit 并发包下 Executors 创建的线程存在 一个 execute()&#xff0c;以及三个 submit() 不同的是使用 execute() 执行的任务是没有返回值的&#xff0c;使用 submit() 则是存在返回值的&#xff0c;这与接下里要说的 CompletableFuture.run…

实现异步编程,这个工具类你得掌握!

前言 最近看公司代码&#xff0c;多线程编程用的比较多&#xff0c;其中有对CompletableFuture的使用&#xff0c;所以想写篇文章总结下 在日常的Java8项目开发中&#xff0c;CompletableFuture是很强大的并行开发工具&#xff0c;其语法贴近java8的语法风格&#xff0c;与st…

Java异步编程之CompletableFuture

异步任务 Future获取异步任务结果 利用 Java 并发包提供的 Future 可以很容易获得异步任务的执行结果&#xff0c;无论异步任务是通过线程池 ThreadPoolExecutor 执行的&#xff0c;还是通过手工创建子线程来执行的。利用多线程可以快速将一些串行的任务并行化&#xff0c;从而…

JUC异步编程

什么是JUC JUC的意思是java并发编程工具包&#xff0c;是java.util.concurrent包的简称。目的就是为了更好的支持高并发任务&#xff0c;让开发者利用这个包进行的多线程开发时&#xff0c;可以有效的减少竞争条件和死锁线程。 异步编程 模拟用户下单操作。。。 1、根据地址…

线程、多线程的使用、线程池、异步(CompletableFuture)-48

一&#xff1a;线程 1.初始化线程的四种方式 1&#xff09;、继承 Thread public class ThreadTest {public static void main(String[] args) {System.out.println("main...start...");Thread01 thread new Thread01();//启动线程thread.start();System.out.pri…

CompletableFuture 执行异步任务

CompletableFuture 执行异步任务 参考&#xff1a; (10条消息) Java 8 的异步编程利器 CompletableFuture 真香&#xff01;_不才陈某的博客-CSDN博客 提供几十种方法&#xff0c;帮助异步任务执行调用&#xff1b; 主要包括&#xff1a; 创建异步任务任务异步回调多个任务…

CompletableFuture实现异步编排全面分析和总结

一、&#x1f308;CompletableFuture简介 CompletableFuture结合了Future的优点&#xff0c;提供了非常强大的Future的扩展功能&#xff0c;可以帮助我们简化异步编程的复杂性&#xff0c;提供了函数式编程的能力&#xff0c;可以通过回调的方式处理计算结果&#xff0c;并且提…

【Java8新特性--->异步处理】CompletableFuture

一、引入 假设一个商品详情页需要以下操作&#xff1a; 查询展示商品的基本信息耗时&#xff1a;0.5s查询展示商品的销售信息耗时&#xff1a;0.7s查询展示商品的图片信息耗时&#xff1a;1s查询展示商品销售属性耗时&#xff1a;0.3s查询展示商品规格属性耗时&#xff1a;1.…

CompletableFuture API

目录 1. 为什么要用CompletableFuture1.1 API 2. CompletableFuture Demo1. 创建CompletableFuture2. 定义CompletableFuture完成时和异常时需要回调的实例3. CompletableFuture的优点 3. demo&#xff1a;多个CompletableFuture串行执行4. demo&#xff1a;多个CompletableFut…

CompletableFuture实战与分析

Future对于结果的获取不够好&#xff0c;只能通过阻塞或者轮询的方式得到任务的结果。在Java8中Doug Lea大师提供了一个CompletableFuture工具类&#xff0c;可以更优雅的对异步并行操作进行编排。 Future VS CompletableFuture CompletableFuture支持手动完成任务&#xff0…

Java8 CompletableFuture异步非阻塞做法

创建异步任务 Future.submit supplyAsync / runAsync 异步回调 thenApply / thenApplyAsync thenAccept / thenRun exceptionally whenComplete handle 组合处理 thenCombine / thenAcceptBoth / runAfterBoth applyToEither / acceptEither / runAfterEither thenCom…

2022.2.5 第十三次周报

文章目录 前言一、论文阅读《ROCKET: Exceptionally fast and accurate time series classification using random convolutional kernels》Abstract摘要Introduction介绍Method方法Kernels内核Transform转换Classifier分类器Complexity Analysis复杂性分析 Experiments实验Con…

并发编程(十五)-CompletableFuture中常用方法的使用与分析

文章目录 一、CompletableFuture API介绍1. 描述2. CompletionStage3. CompletableFuture 4个核心静态方法&#xff08;1&#xff09;runAsync(Runnable runnable)&#xff08;2&#xff09;runAsync(Runnable runnable, Executor executor)&#xff08;3&#xff09;supplyAsy…

Java 编程问题:十一、并发-深入探索

原文&#xff1a;Java Coding Problems 协议&#xff1a;CC BY-NC-SA 4.0 贡献者&#xff1a;飞龙 本文来自【ApacheCN Java 译文集】&#xff0c;自豪地采用谷歌翻译。 本章包括涉及 Java 并发的 13 个问题&#xff0c;涉及 Fork/Join 框架、CompletableFuture、ReentrantLock…

线程(十二)---CompletableFuture(三)

写在前面&#xff1a;各位看到此博客的小伙伴&#xff0c;如有不对的地方请及时通过私信我或者评论此博客的方式指出&#xff0c;以免误人子弟。多谢&#xff01; 示例五&#xff1a;异常处理 接着上一篇记录一下CompletableFuture的异常处理&#xff0c;异常处理通常使用…

dice loss

Dice Loss 最先是在VNet 这篇文章中被提出&#xff0c;后来被广泛的应用在了医学影像分割之中。 Dice 系数 Dice系数作为损失函数的原因和混淆矩阵有着很大的关系&#xff0c;下图给出的是一个混淆矩阵&#xff1a; 其中的一些关键指标如下&#xff1a; 精确率(precision)表…

Hinge loss

声明&#xff1a; 参考自维基百科后面可能会更新 Hinge Loss 在机器学习中&#xff0c;hinge loss作为一个损失函数(loss function)&#xff0c;通常被用于最大间隔算法(maximum-margin)&#xff0c;而最大间隔算法又是SVM(支持向量机support vector machines)用到的重要算法…

【深度学习】一文读懂机器学习常用损失函数(Loss Function)

【深度学习】一文读懂机器学习常用损失函数&#xff08;Loss Function&#xff09; 最近太忙已经好久没有写博客了&#xff0c;今天整理分享一篇关于损失函数的文章吧&#xff0c;以前对损失函数的理解不够深入&#xff0c;没有真正理解每个损失函数的特点以及应用范围&#x…