js性能優化之防抖與節流

防抖

函數防抖(debounce):當持續觸發事件時,必定時間段內沒有再觸發事件,事件處理函數纔會執行一次,若是設定的時間到來以前,又一次觸發了事件,就從新開始延時。javascript

節流

函數節流(throttle):當持續觸發事件時,保證必定時間段內只調用一次時間處理函數。css

節流的定義應該比較好理解,舉例來講就是,你在瘋狂點擊短視頻裏面的「點亮紅心」按鈕,好比你10s點擊了1000次,可是節流的作法就是在這1000次的事件觸發過程當中,我規定1s才能真正的觸發紅心亮起的邏輯。因此10s內再快的點擊頻率,也只會亮起10顆紅心。html

防抖的定義看起來比較繞,咱們也舉例說明。舉例某寶或者某東的聯想搜索框,正常狀況,若是你短期內不停的敲擊鍵盤那麼每一次輸入的內容都會發送請求給服務端作聯想算法,而後不停返回數據,那麼下拉框看起來就會不停閃動,體驗不好,而且實際上不須要那麼高頻率的去發送請求,應該是當你中止了一個字或者一個詞或者一句話的輸入後再發送請求。因此防抖的作法,就是不管你多快的輸入(觸發事件),我只在這個週期的開始或者結束觸發一次事件中的邏輯。如此反覆,視爲防抖。java

防抖的應用場景

  • search搜索聯想,用戶不短輸入,用防抖節約請求資源,優化用戶體驗
  • window觸發resize的時候,不斷調整瀏覽器窗口大小會觸發這個事件,利用防抖來讓其觸發一次
  • 防止短期內重複提交

節流的應用場景

  • 鼠標不短觸發mousedown或者mouseover事件的時候,能夠利用節流在單位事件內只觸發一次
  • 監聽滾動事件,好比是否滑到底部加載更多數據,用節流來判斷

防抖的實現

咱們設定一個場景,有一個擁有固定寬高的div,監聽這個div的mouseover事件,觸發一次就+1,並將值填充到div中。 算法

防抖的目的就是爲了讓鼠標移動的時候,按照規定的週期結束或者開始的時候才觸發這個+1的邏輯。

<html>
<head>
	<title></title>
	<style type="text/css">
	#container{
		width: 400px;
		height: 400px;
		background-color: #333333;
		color:#ffffff;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 34px;
		font-weight: 600;
	}
</style>
</head>
<body>
	<div id="container"></div>
	<script type="text/javascript">
		var count = 1;
		var container = document.getElementById('container');
		function getUserAction(){
			this.innerHTML = count++;
		}
		container.onmousemove = debounce(getUserAction,100,false);
		function debounce(fn,wait,flag){
			var timeout;
			return function(){
				var self = this;
				clearTimeout(timeout);

				if(flag){
					var callNow = !timeout;
					timeout = setTimeout(function(){
						timeout = null;
					}, wait);

					if(callNow){
						fn.apply(self);
					}
				}else{
					timeout = setTimeout(function(){
						fn.apply(self);
					}, wait);
				}
			}
		}
	</script>
</body>
</html>
複製代碼

節流的實現

繼續引用上述場景,節流的目的是爲了在鼠標移動不停觸發mouseover的時候,+1的邏輯只在規定的周內執行一次(例:鼠標瘋狂滑動,只在1s內+1,不會在1s中內觸發兩次函數)瀏覽器

<html>
<head>
	<title></title>
	<style type="text/css">
	#container{
		width: 400px;
		height: 400px;
		background-color: #333333;
		color:#ffffff;
		display: flex;
		justify-content: center;
		align-items: center;
		font-size: 34px;
		font-weight: 600;
	}
</style>
</head>
<body>
	<div id="container"></div>
	<script type="text/javascript">
		var count = 1;
		var container = document.getElementById('container');
		function getUserAction(){
			this.innerHTML = count++;
		}
		container.onmousemove = throttle(getUserAction,1000);
		//代理模式
		function throttle(fn,wait){
			var pre = 0;
			return function(){
				var self = this;
				var now =  +new Date();
				if(now-pre>wait){
					fn.apply(self);
					pre = now;
				}
			}
		}
	</script>
</body>
</html>
複製代碼
相關文章
相關標籤/搜索