フロントエンド性能最適化---振れ防止&スロットル
17758 ワード
今日の目標は手書きでブレ止め&スロットル関数を作ることです
ブレ止め
コンセプト:イベントがトリガーされた後、n秒以内に関数は1回しか実行できません.n秒以内にイベントがトリガーされた場合、関数実行時間を再計算します.
私たちはいつジッタ防止関数を最適化する必要がありますか?高周波トリガのイベント、例えば私たちはボタンを狂わせたり、移動したりします.
まず簡単な手ぶれ防止関数を実現して処理します
簡単版のブレ止め関数は実現しましたが、初めて上がったときはすぐに実行されず、アップグレードをしました.
自分でブレ止め関数を設計する時も自分でここの変数nowに取って代わる追加のパラメータを設定することができます
しぼり
コンセプト:連続的にトリガーされたイベントを一定時間内にトリガーします.このboxを例に挙げます.
ここではtimerをnullに設定するだけですが、タイマーをクリアしていません.影響がないように見えます.もっと細かく解決して最適化する必要があります(タイムスタンプを使用してtimerを置き換え、settimoutを使用しません).
ブレ止め
コンセプト:イベントがトリガーされた後、n秒以内に関数は1回しか実行できません.n秒以内にイベントがトリガーされた場合、関数実行時間を再計算します.
私たちはいつジッタ防止関数を最適化する必要がありますか?高周波トリガのイベント、例えば私たちはボタンを狂わせたり、移動したりします.
//
let box = document.querySelector('.box')
box.onmousemove = function(e){
box.innerHTML = e.clientX
}
まず簡単な手ぶれ防止関数を実現して処理します
//
//
let box = document.querySelector('.box')
let boxDebounce = debounce(move,1000)
box.onmousemove = boxDebounce
function move(e){
box.innerHTML = e.clientX
}
function debounce(fn,wait){
let timer = null
return function(){
let args = arguments
timer && clearTimeout(timer)
timer = setTimeout(()=>{
fn.apply(this,args)
},wait)
}
}
簡単版のブレ止め関数は実現しましたが、初めて上がったときはすぐに実行されず、アップグレードをしました.
//
let box = document.querySelector('.box')
let boxDebounce = debounce(move,1000)
box.onmousemove = boxDebounce
function move(e){
box.innerHTML = e.clientX
}
function debounce(fn,wait){
let timer = null
return function(){
let args = arguments
let now = !timer;
timer && clearTimeout(timer)
timer = setTimeout(()=>{
timer = null
},wait)
// if(now){
// fn.apply(this,args)
// }
now ? fn.apply(this,args)
: ''
}
}
自分でブレ止め関数を設計する時も自分でここの変数nowに取って代わる追加のパラメータを設定することができます
しぼり
コンセプト:連続的にトリガーされたイベントを一定時間内にトリガーします.このboxを例に挙げます.
let box = document.querySelector('.box')
let boxReduce = reduce(move,400)
box.onmousemove = boxReduce
function move(e){
box.innerHTML = e.clientX
}
function reduce(fn,wait){
let timer = null
return function(){
let args = arguments
if(!timer){
timer = setTimeout(()=>{
timer = null
fn.apply(this,args)
},wait)
}
}
}
ここではtimerをnullに設定するだけですが、タイマーをクリアしていません.影響がないように見えます.もっと細かく解決して最適化する必要があります(タイムスタンプを使用してtimerを置き換え、settimoutを使用しません).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
background: #00acec;
height: 500px;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
let box = document.querySelector('.box')
let boxReduce = reduce(move,400)
box.onmousemove = boxReduce
function move(e){
box.innerHTML = e.clientX
}
// function reduce(fn,wait){
// let timer = null
// return function(){
// let args = arguments
// if(!timer){
// timer = setTimeout(()=>{
// timer = null
// fn.apply(this,args)
// },wait)
// }
// }
// }
function reduce(fn,wait){
let last = 0
return function(){
let args = arguments
let now = Date.now()
if(now - last > wait){
fn.apply(this,args)
last = now
}
}
}
</script>
</body>
</html>