javascript的防抖和節(jié)流你了解嗎
一:為什么需要防抖與節(jié)流
防抖和節(jié)流都是為了解決短時(shí)間內(nèi)大量觸發(fā)某函數(shù)或者事件而導(dǎo)致的性能問題,比如在
1.用戶體驗(yàn)上,觸發(fā)頻率過高導(dǎo)致的響應(yīng)速度跟不上觸發(fā)頻率,出現(xiàn)延遲,假死,卡頓的現(xiàn)象
2.服務(wù)器上:加重服務(wù)器壓力
二:防抖
防抖是當(dāng)事件或函數(shù)被觸發(fā)后,延遲n秒后在執(zhí)行回調(diào),如果在這n秒內(nèi)事件或函數(shù)又被觸發(fā),則重新計(jì)時(shí),直到n秒內(nèi)沒有觸發(fā)事件或函數(shù),則執(zhí)行回調(diào)函數(shù)
圖文解釋:
(回城的時(shí)間就相當(dāng)于延遲時(shí)間,如果在回城的時(shí)間內(nèi)再次觸發(fā)回城則重新倒計(jì)時(shí)回城時(shí)間)
案例:表單輸入框事件
<!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> <input type="text" class="serach"> <script> let serach = document.getElementsByClassName('serach')[0] // console.log(serach); serach.addEventListener('input', function() { console.log('向后端發(fā)起了請(qǐng)求!'); }) </script> </body> </html>
運(yùn)行:
可以看出當(dāng)我每次輸入一個(gè)數(shù)字的時(shí)候都發(fā)起了請(qǐng)求,這是不符合項(xiàng)目要求和這非常消耗服務(wù)器的性能,我們應(yīng)該在用戶在輸入內(nèi)容后的一段時(shí)間內(nèi)如果用戶不再輸入內(nèi)容再發(fā)起請(qǐng)求,用戶如果在這一段時(shí)間內(nèi)再次輸入,則繼續(xù)等待用戶在一段時(shí)間內(nèi)不再輸入內(nèi)容后再發(fā)起請(qǐng)求。
使用防抖優(yōu)化:
<!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> <input type="text" class="serach"> <script> let serach = document.getElementsByClassName('serach')[0] // console.log(serach); let timer = null; //聲明一個(gè)用于防抖的定時(shí)器變量timer serach.addEventListener('input', function() { clearTimeout(timer) //如果在定時(shí)器的時(shí)間間隔內(nèi)再次觸發(fā)事件則清除定時(shí)器,重新執(zhí)行新的定時(shí)器函數(shù) // 定時(shí)器函數(shù) timer = setTimeout(function() { console.log('向后端發(fā)起了請(qǐng)求!'); }, 500) }) </script> </body> </html>
運(yùn)行:
如果在500毫秒內(nèi)調(diào)用多次,只會(huì)執(zhí)行最后一次
可以看出在輸入完內(nèi)容后的500毫秒后才發(fā)起請(qǐng)求
防抖的應(yīng)用場(chǎng)景:
1.用戶在輸入框連續(xù)輸入一串字符時(shí),可以通過放抖策略,只在輸入完后,才執(zhí)行查詢的請(qǐng) 求,這樣可以有效減少請(qǐng)求次數(shù),節(jié)約請(qǐng)求資源。(也可以用節(jié)流)
2.登錄、發(fā)短信等按鈕避免用戶點(diǎn)擊太快,以致于發(fā)送了多次請(qǐng)求,需要防抖
3.調(diào)整瀏覽器窗口大小時(shí),resize 次數(shù)過于頻繁,造成計(jì)算過多,此時(shí)需要一次到位,就用到了防抖
4.文本編輯器實(shí)時(shí)保存,當(dāng)無任何更改操作一秒后進(jìn)行保存
三、節(jié)流
控制事件發(fā)生的頻率從而達(dá)到減少一段時(shí)間內(nèi)事件的觸發(fā)頻率,如控制為1s發(fā)生一次,甚至1分鐘發(fā)生一次。
圖文解釋:
(當(dāng)玩射擊游戲時(shí),無論你手點(diǎn)的有多快射出的彈還是有規(guī)律的發(fā)出(比如0.5發(fā)出一個(gè)彈))
案例:獲取鼠標(biāo)的最終坐標(biāo)
<!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> <style> .app { width: 800px; height: 800px; background-color: pink; } </style> </head> <body> <div class="app"> </div> <script> let app = document.getElementsByClassName('app')[0] app.addEventListener('mousemove', function(e) { console.log(`x坐標(biāo)${e.pageX},y坐標(biāo)${e.pageY}`); }) </script> </body> </html>
運(yùn)行:
可以看出每次鼠標(biāo)移動(dòng)都執(zhí)行函數(shù),大大消耗性能,我們可以利用節(jié)流策略,一秒內(nèi)只執(zhí)行一次來節(jié)流
節(jié)流優(yōu)化:
<!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> <style> .app { width: 800px; height: 800px; background-color: pink; } </style> </head> <body> <div class="app"> </div> <script> let app = document.getElementsByClassName('app')[0] let timer = true; //定義一個(gè)節(jié)流閥變量來控制節(jié)流閥為關(guān)閉還是開啟狀態(tài),默認(rèn)為開啟 app.addEventListener('mousemove', function(e) { if (!timer) { return //判斷節(jié)流閥是否關(guān)閉,如果節(jié)流閥還是false(關(guān)閉狀態(tài)),則證明上次的函數(shù)未執(zhí)行完,直接退出函數(shù) } timer = false; //設(shè)置節(jié)流閥為false,如果定時(shí)器函數(shù)沒有設(shè)置為true,則定時(shí)器函數(shù)沒執(zhí)行,節(jié)流閥一直為關(guān)(false) setTimeout(function() { console.log(`x坐標(biāo)${e.pageX},y坐標(biāo)${e.pageY}`) timer = true //定時(shí)器函數(shù)已經(jīng)執(zhí)行,設(shè)置節(jié)流閥為true }, 500) }) </script> </body> </html>
運(yùn)行效果:
使用節(jié)流后,坐標(biāo)打印次數(shù)明顯變少,節(jié)流效果達(dá)成
四.防抖和節(jié)流的區(qū)別:
防抖:如果事件被頻繁觸發(fā),防抖能保證只有最后一次觸發(fā)生效!前面N多次的觸發(fā)都會(huì)被忽略!
節(jié)流:如果事件被頻繁觸發(fā),節(jié)流能夠減少事件觸發(fā)的頻率,因此,節(jié)流是有選擇性地執(zhí)行一部分事件,單位時(shí)間內(nèi)事件只能觸發(fā)一次
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- JavaScript函數(shù)防抖動(dòng)debounce
- 通過實(shí)例講解JS如何防抖動(dòng)
- JavaScript運(yùn)動(dòng)框架 解決防抖動(dòng)問題、懸浮對(duì)聯(lián)(二)
- JavaScript中防抖和節(jié)流的區(qū)別及適用場(chǎng)景
- JavaScript中防抖和節(jié)流的實(shí)戰(zhàn)應(yīng)用記錄
- JavaScript深入理解節(jié)流與防抖
- JavaScript防抖與節(jié)流的實(shí)現(xiàn)與注意事項(xiàng)
- JavaScript的防抖和節(jié)流一起來了解下
- JavaScript中函數(shù)的防抖與節(jié)流詳解
- 淺談JavaScript節(jié)流與防抖
- 關(guān)于JavaScript防抖與節(jié)流的區(qū)別與實(shí)現(xiàn)
- JavaScript防抖與節(jié)流詳解
- JavaScript 防抖和節(jié)流詳解
- JavaScript防抖動(dòng)與節(jié)流處理
相關(guān)文章
javascript中的location用法簡(jiǎn)單介紹
javascript中的location用法簡(jiǎn)單介紹...2007-03-03設(shè)計(jì)模式中的facade外觀模式在JavaScript開發(fā)中的運(yùn)用
外觀模式通過引入一個(gè)外觀角色來簡(jiǎn)化客戶端與子系統(tǒng)之間的交互,為復(fù)雜的子系統(tǒng)調(diào)用提供一個(gè)統(tǒng)一的入口,降低子系統(tǒng)與客戶端的耦合,接下來就來看設(shè)計(jì)模式中的facade外觀模式在JavaScript開發(fā)中的運(yùn)用2016-05-05JavaScript中的操作符類型轉(zhuǎn)換示例總結(jié)
最近發(fā)現(xiàn)在前端的面試題目中經(jīng)常出現(xiàn)操作符類型轉(zhuǎn)換的題目,于是這里來進(jìn)行一個(gè)JavaScript中的操作符類型轉(zhuǎn)換示例總結(jié),需要的朋友可以參考下2016-05-05關(guān)于JavaScript 原型鏈的一點(diǎn)個(gè)人理解
本文給大家分享的是個(gè)人關(guān)于JavaScript原型鏈相關(guān)知識(shí)的一些理解,這里推薦給大家,希望大家能夠喜歡2016-07-07JavaScript簡(jiǎn)介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
JavaScript是一種基于對(duì)象(Object)和事件驅(qū)動(dòng)(EventDriven)并具有安全性能的腳本語言,javascript的出現(xiàn)使得網(wǎng)頁和用戶之間實(shí)現(xiàn)了一種實(shí)時(shí)性的,動(dòng)態(tài)性的,交互性的關(guān)系,使網(wǎng)頁包含更多活躍的元素和更加精彩的內(nèi)容2017-06-06Uglifyjs(JS代碼優(yōu)化工具)入門 安裝使用
Uglify JS 是一個(gè)服務(wù)端node.js的壓縮程序。需要的朋友可以測(cè)試下2012-03-03