창 크기를 조정하거나 페이지를 아래로 스크롤하는 등 일부 브라우저 이벤트는 짧은 시간 내에 여러 번 빠르게 트리거될 수 있습니다. 예를 들어, 페이지 창 스크롤 이벤트를 수신하고 사용자가 계속해서 페이지를 빠르게 아래로 스크롤하는 경우 스크롤 이벤트가 3초 안에 수천 번 실행될 수 있으며 이로 인해 심각한 성능 문제가 발생할 수 있습니다.
인터뷰 중에 애플리케이션 구축에 대해 논의하고 스크롤링, 창 크기 조정 또는 키 누름과 같은 이벤트가 발생하는 경우 페이지 속도와 성능을 향상시키기 위한 디바운싱 및 기능 제한을 언급하세요. 이 두 형제의 본질은 폐쇄의 형태로 존재한다. 이벤트에 해당하는 콜백 함수를 래핑하고, 시간 정보를 자유 변수 형태로 캐싱하고, 마지막으로 setTimeout을 사용하여 이벤트의 트리거 빈도를 제어합니다.
Throttle: 첫 번째 사람이 최종 결정권을 가집니다
Throttle의 중심 아이디어는 일정 시간 내에 아무리 많은 콜백을 실행하더라도 첫 번째 콜백만 인식하고 타이머가 끝나면 응답.
먼저 작은 이야기를 들려드리겠습니다. 한 승객이 막 비행기에서 내려 차가 필요해서 공항에서 유일한 공항 버스를 불러 그를 데리러 갔습니다. 운전사는 자신이 이미 왔다고 생각하고 공항으로 차를 몰고 갔습니다. 그래서 여행이 가치가 있을 수 있도록 함께 갈 사람을 몇 명 더 태워야 합니다. 10분 정도 기다려 보겠습니다. 그래서 운전기사는 타이머를 켜고 뒤에 있는 손님들에게 차례로 버스에 타라고 인사했습니다. 이 10분 동안 비행기 뒤에서 내린 승객만 이 버스를 탈 수 있습니다. 10분이 지나면 비행기 뒤의 승객이 버스에 아무리 붐비지 않아도 이 버스를 떠나야 합니다.
이 이야기에서 "운전자"는 출발 시간을 제어하는 스로틀이며, "승객"은 잦은 운영 이벤트로 인해 계속해서 쏟아지는 콜백 작업이며, "운전자"와 "타이머"는 위에서 언급한 것처럼 자유 변수의 형태로 존재하는 시간 정보이며, 이는 "운전자"가 최종적으로 자동차의 출발을 결정하는 기준이 됩니다. 콜백 함수의 실행에 해당합니다.
요약하자면, 소위 "제한"은 일정 기간 동안 후속 콜백 요청을 무시함으로써 달성됩니다. 손님이 차량 서비스를 요청하는 한, 운전자는 일정 시간 내에 차량 서비스를 요청하는 모든 후속 손님이 이 서비스를 이용하기 위해 줄을 서야 하며, 누구도 호출할 수 없습니다. 더 많은 놀이기구.
실제 상호 작용에도 동일하게 해당합니다. 사용자가 스크롤 이벤트를 트리거할 때마다 이 트리거 작업에 대한 타이머가 시작됩니다. 일정 기간 동안 모든 후속 스크롤 이벤트는 "자동차에 탄 승객"으로 처리됩니다. 즉, 새로운 스크롤 콜백을 실행할 수 없습니다. "일정 기간"에 도달할 때까지 처음으로 트리거된 스크롤 이벤트에 해당하는 콜백이 실행되고 "일정 기간 내에" 트리거된 후속 스크롤 콜백은 스로틀 밸브에 의해 무시됩니다.
이제 함께 스로틀을 구현하세요.
// fn是我们需要包装的事件回调, interval是时间间隔的阈值 function throttle(fn, interval) { // last为上一次触发回调的时间 let last = 0 // 将throttle处理结果当作函数返回 return function () { // 保留调用时的this上下文 let context = this // 保留调用时传入的参数 let args = arguments // 记录本次触发回调的时间 let now = +new Date() // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值 if (now - last >= interval) { // 如果时间间隔大于我们设定的时间间隔阈值,则执行回调 last = now; fn.apply(context, args); } } } // 用throttle来包装scroll的回调 const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
디바운스: 마지막 사람이 최종 결정권을 가집니다.
흔들림 방지의 핵심 아이디어는 다음과 같습니다. 끝까지 기다리겠습니다. 일정 시간 내에 아무리 많은 콜백을 실행하더라도 마지막 콜백만 인식합니다.
운전하는 운전자의 이야기를 계속해서 들려주세요. 이번에는 운전자가 더 인내심을 보였습니다. 첫 번째 승객이 버스에 탑승한 후 운전기사가 시간 측정을 시작합니다(예: 10분). 10분 이내에 다른 승객이 오면 운전자는 타이머를 지우고 10분 더 기다리기 시작합니다(지연 대기). 그런 승객이 있고 버스에 탑승한 후 10분 동안 새로운 승객이 버스에 타지 않을 때까지 운전자는 아무도 이 버스를 탈 필요가 없다고 생각하고 차를 몰고 갈 것입니다.
디바운스를 이해하기 위해 스로틀을 비교해 보겠습니다. 스로틀의 논리에서는 "첫 번째 사람이 최종 결정권을 가집니다"라고 하며 첫 번째 승객에게만 시간을 할당하고 시간이 다 되면 콜백을 실행합니다. Debounce는 "마지막 사람이 최종 발언권을 갖는다"고 믿으며 Debounce는 새로운 승객마다 새로운 타이머를 설정합니다.
이제 디바운스를 함께 구현하세요.
// fn是我们需要包装的事件回调, delay是每次推迟执行的等待时间 function debounce(fn, delay) { // 定时器 let timer = null // 将debounce处理结果当作函数返回 return function () { // 保留调用时的this上下文 let context = this // 保留调用时传入的参数 let args = arguments // 每次事件被触发时,都去清除之前的旧定时器 if(timer) { clearTimeout(timer) } // 设立新定时器 timer = setTimeout(function () { fn.apply(context, args) }, delay) } } // 用debounce来包装scroll的回调 const better_scroll = debounce(() => console.log('触发了滚动事件'), 1000)
스로틀을 사용하여 디바운스 최적화
디바운스의 문제점은 "너무 인내심이 많다"는 것입니다. 사용자가 매우 자주 작업하는 경우 다음 작업을 수행하기 전에 디바운스로 설정된 지연 시간이 끝날 때까지 기다리지 않으므로 각 디바운스가 사용자에 대한 타이머를 재생성하고 콜백 기능이 셀 수 없이 지연됩니다. 빈번한 지연으로 인해 사용자는 응답을 받지 못하며 사용자는 "이 페이지가 멈췄습니다."라는 인상을 받게 됩니다.
자멸을 방지하려면 스로틀 개념을 빌려 "최종선" 디바운스를 생성해야 합니다. 기다릴 수 있지만 원칙은 있습니다. 지연 시간 내에 타이머를 재생성할 수 있습니다. 하지만 지연 시간이 지나면 사용자에게 응답을 주어야 합니다. 스로틀과 디바운스의 이 "조합" 아이디어는 많은 성숙한 프런트엔드 라이브러리에서 향상된 스로틀 기능 구현에 적용되었습니다.
// fn是我们需要包装的事件回调, delay是时间间隔的阈值 function throttle(fn, delay) { // last为上一次触发回调的时间, timer是定时器 let last = 0, timer = null // 将throttle处理结果当作函数返回 return function () { // 保留调用时的this上下文 let context = this // 保留调用时传入的参数 let args = arguments // 记录本次触发回调的时间 let now = +new Date() // 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值 if (now - last < delay) { // 如果时间间隔小于我们设定的时间间隔阈值,则为本次触发操作设立一个新的定时器 clearTimeout(timer) timer = setTimeout(function () { last = now fn.apply(context, args) }, delay) } else { // 如果时间间隔超出了我们设定的时间间隔阈值,那就不等了,无论如何要反馈给用户一次响应 last = now fn.apply(context, args) } } } // 用新的throttle包装scroll的回调 const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000) document.addEventListener('scroll', better_scroll)
Vue의 lodash에서 디바운싱 및 스로틀링 사용
事件节流和防抖是提高性能或降低网络开销的好方法。虽然 Vue 1曾经支持对事件的节流和防抖,但是在Vue 2中为了保持核心的简单性,删除对事件的节流和防抖的支持。因此,在Vue 2对对事件进行防抖和节流我们可以使用 lodash
来做。
安装
可以通过 yarn 或 npm 安装 lodash。
# Yarn $ yarn add lodash # NPM $ npm install lodash --save
注意:如果我们不想导入lodash
的所有内容,而只导入所需的部分,则可以通过一些Webpack构建自定义来解决问题。 还可以使用lodash.throttle
和lodash.debounce
等软件包分别安装和导入lodash
的各个部分。
throttling 方法
要对事件进行节流处理方法非常简单,只需将要调用的函数包装在lodash的_.throttle
函数中即可。
<template> <button @click="throttledMethod()">Click me as fast as you can!</button> </template> <script> import _ from 'lodash' export default { methods: { throttledMethod: _.throttle(() => { console.log('I get fired every two seconds!') }, 2000) } } </script>
debouncing 方法
尽管节流在某些情况下很有用,但一般情况我们经常使用的是防抖。 防抖实质上将我们的事件分组在一起,并防止它们被频繁触发。 要在Vue组件中使用节流,只需将要调用的函数包装在lodash的_.debounce
函数中。
<template> <button @click="throttledMethod()">Click me as fast as you can!</button> </template> <script> import _ from 'lodash' export default { methods: { throttledMethod: _.debounce(() => { console.log('I only get fired once every two seconds, max!') }, 2000) } } </script>
参考:
相关推荐:
更多编程相关知识,请访问:编程入门!!
위 내용은 Vue에서 이벤트를 방지하고 조절하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!