前端性能優化的利器 ——— 淺談JavaScript中的防抖和節流

来源:https://www.cnblogs.com/fx67ll/archive/2023/08/03/js-debounce-throttle.html
-Advertisement-
Play Games

防抖函數和節流函數是工作中兩種常用的前端性能優化函數,今天我就來總結一下什麼是防抖和節流,並詳細說明一下如何在工作中應用防抖函數和節流函數 ...


防抖和節流函數是工作中兩種常用的前端性能優化函數,今天我就來總結一下什麼是防抖和節流,並詳細說明一下如何在工作中應用防抖和節流函數

什麼是防抖和節流?

在 JavaScript 中,防抖(debounce)和節流(throttle)是用來限制函數執行頻率的兩種常見技術。

防抖(debounce) 是指在某個時間段內,只執行最後一次觸發的函數調用。如果在這個時間段內再次觸發該函數,會重新計時,直到等待時間結束才會執行函數。
這個技術通常用於處理頻繁觸發的事件,比如視窗大小調整、搜索框輸入等。防抖可以避免函數執行過多次,以減少網路開銷和性能負擔。

節流(throttle) 是指在一段時間內限制函數的執行頻率,保證一定時間內只執行一次函數調用。無論觸發頻率多高,都會在指定時間間隔內執行一次函數。
這個技術通常用於處理連續觸發的事件,比如滾動事件、滑鼠移動事件等。節流可以控制函數的執行頻率,以減少資源消耗和提高性能。

手寫一個防抖的工具函數

function debounce(func, delay) {
  let timeoutId;
  
  return function() {
    const context = this;
    const args = arguments;
    
    clearTimeout(timeoutId);
    
    timeoutId = setTimeout(function() {
      func.apply(context, args);
    }, delay);
  };
}

函數說明

  1. 這個防抖函數接受兩個參數:func表示需要進行防抖的函數,delay表示延遲的時間間隔(以毫秒為單位)
  2. 函數內部使用了一個timeoutId變數來保存定時器的標識。當調用防抖函數返回的新函數時,會清除之前的定時器,並設置一個新的定時器。只有在延遲時間內沒有再次調用該新函數時,才會觸發最終的函數執行

使用示例

該示例表示在全局滾動事件中使用防抖函數,每200毫秒內如果觸發滾動事件,那麼不會執行handleScroll()函數。
然後重新計時200毫秒,再次判斷,直到最後一個200毫秒內沒有觸發滾動事件,才會執行handleScroll()函數

function handleScroll() {
  console.log('Scrolled');
}
const debouncedScroll = debounce(handleScroll, 200);
window.addEventListener('scroll', debouncedScroll);

手寫一個節流的工具函數

function throttle(func, delay) {
  let timeoutId;
  let lastExecTime = 0;

  return function(...args) {
    const currentTime = Date.now();
    const remainingTime = delay - (currentTime - lastExecTime);

    clearTimeout(timeoutId);

    if (remainingTime <= 0) {
      func.apply(this, args);
      lastExecTime = currentTime;
    } else {
      timeoutId = setTimeout(() => {
        func.apply(this, args);
        lastExecTime = Date.now();
      }, remainingTime);
    }
  };
}

函數說明

  1. 這個節流函數接受兩個參數:func是要執行的函數,delay是延遲時間(以毫秒為單位)
  2. 它返回一個新的函數,該函數在調用時會根據指定的延遲時間來限制原始函數的執行頻率

使用示例

在全局滾動事件中使用節流函數,無論在滾動事件的監聽過程中,觸發了幾次handleScroll()函數,都只會在每200毫秒內執行一次handleScroll()函數。

function handleScroll() {
  console.log('Scrolled');
}
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);

如何在工作中應用防抖和節流

防抖和節流主要應用於:搜索框輸入事件監聽、視窗大小調整事件監聽、按鈕點擊事件監聽、滾動事件監聽、滑鼠移動事件監聽等等場景。

工作中哪些場景可以使用防抖函數?

  1. 用戶輸入: 當用戶在表單輸入框中頻繁輸入時,可以使用防抖函數來延遲處理用戶輸入,避免頻繁的請求或操作,提高性能和用戶體驗。
  2. 搜索框: 在搜索框中,當用戶連續輸入關鍵字時,可以使用防抖函數來延遲發送搜索請求,以避免請求過多。
  3. 視窗調整: 當視窗大小調整時,會觸發resize事件,可以使用防抖函數來限制resize事件的觸發次數,避免頻繁執行調整相關的代碼。
  4. 按鈕頻繁點擊: 當按鈕被頻繁點擊時,可以使用防抖函數來限制按鈕點擊的觸發次數。

工作中哪些場景可以使用節流函數?

  1. 用戶輸入: 當用戶在文本框中輸入時,觸發搜索功能。使用節流函數可以限制搜索請求的頻率,以避免頻繁的網路請求。例如,可以設置一個定時器,在用戶輸入後的一小段時間內不觸發搜索請求,只在定時器結束後才進行搜索。
  2. 無限載入: 當用戶滾動頁面時,觸發載入更多數據的操作。使用節流函數可以限制載入操作的頻率,以提高頁面的響應性能。例如,可以設置一個定時器,在用戶滾動過程中只觸發載入操作的最後一次滾動事件。
  3. 按鈕頻繁點擊: 當用戶頻繁點擊某個按鈕時,觸發某個操作。使用節流函數可以限制點擊操作的頻率,以避免重覆操作或者混亂的界面狀態。例如,可以設置一個定時器,在用戶點擊後的一小段時間內不觸發重覆操作。

如何使用loadsh.js工具庫中的防抖和節流函數

實際開發過程中,我們的項目中可能會直接使用loadsh.js工具庫,來避免重覆造輪子,所以這裡也特地說明一下如何使用loadsh.js工具庫中的防抖和節流函數

  1. 安裝loadsh.js工具庫
npm install lodash  
  1. 在項目中引入loadsh.js工具庫,不同前端項目引入方式不同,請自行鑒別
import { debounce, throttle } from 'loadsh';
  1. 使用防抖函數,該示例中,submitData()函數被限製為每1秒只會執行最後一次,如果在等待時間內多次調用該函數,則會重置1秒的等待時間
// 定義要延遲執行的函數
function submitData(data) {
  console.log('保存數據:', data);
}

// 使用debounce函數創建一個延遲執行的函數
const debouncedFn = _.debounce(submitData, 1000);

// 模擬連續觸發保存數據的操作
// 等待1秒後,只會執行最後一次保存數據的操作
debouncedFn('數據1'); // 不會輸出
debouncedFn('數據2'); // 不會輸出
debouncedFn('數據3'); //  輸出 —— 保存數據:數據3

  1. 使用節流函數,該示例中,throttledFn()函數被限製為每秒只能執行一次,如果在等待時間內多次調用該函數,則不會執行
// 定義要減少調用次數的函數
function fetchData(data) {
	console.log('拉取數據:', data);
}

// 使用throttle函數創建一個定時執行的函數
const throttledFn = _.throttle(fetchData, 2000);

// 調用throttledFn函數
throttledFn('數據1'); // 輸出 —— 拉取數據: 數據1

// 在1秒內多次調用throttledFn函數
throttledFn('數據2'); // 不會輸出

// 2秒後再次調用throttledFn函數
setTimeout(() => {
  throttledFn('數據3'); // 輸出 —— 拉取數據: 數據3
}, 1000);

我是 fx67ll.com,如果您發現本文有什麼錯誤,歡迎在評論區討論指正,感謝您的閱讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ### Linux簡介 ```bash # Linux是什麼? 與大家熟知的 Windows 操作系統軟體一樣,Linux 也是一個操作系統軟體。但是與Windows 不同的是,Linux 是一套開放源代碼程式的、並且可以自由傳播的類 Unix操作系統軟體。其在設計之初,就是基於 Intel x86 ...
  • ## 許可權機制和性能指標 前面我們學完了`操作文件`和`用戶`相關知識,本篇學習`許可權`和`性能`相關知識。 ### 文件的屬性看起 看 linux 的許可權,先從文件的屬性看起 ls -l 加 `-d` 是只看這個文件夾: ```javascript pjl@pjl-pc:~$ sudo ls -l ...
  • module_init是linux內核提供的一個巨集, 可以用來在編寫內核模塊時註冊一個初始化函數, 當模塊被載入的時候, 內核負責執行這個初始化函數. 在編寫設備驅動程式時, 使用這個巨集看起來理所應當, 沒什麼特別的, 但畢竟我還是一個有點追求的程式員嘛:P, 這篇文章是我學習module_init... ...
  • ![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230803122150238-1461011617.png) # 1. 問題4 ## 1.1. 最多選修兩門課程的學生,沒有選修任何課程的學生應該被排除在外 ## 1.2.  ...
  • ![file](https://img2023.cnblogs.com/other/2685289/202308/2685289-20230803180034435-79319118.png) ## 導讀 國內某頭部券商是國內排名前三的全國性大型綜合證券公司。作為證券行業領頭羊之一,該券商一直高度重 ...
  • # 項目實戰-前後端分離博客系統 ## 1.項目介紹 * 純後端講解 * 完整的前臺後臺代碼編寫 * 主流技術棧(SpringBoot,MybatisPlus,SpringSecurity,EasyExcel,Swagger2,Redis,Echarts,Vue,ElementUI....) * 完 ...
  • 我們基於 canvas 實現了一款簡單的塗鴉面板,用於在網頁上進行繪圖和創作。此篇文章用於記錄柏成從零開發一個canvas塗鴉面板的歷程。 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 完整效果 對基本的表單樣式進行設置 這裡設置了基本的表單樣式,外層用了div進行包裹,重點是運用了兩個i元素在後期通過css樣式勾畫出一條線沒在聚焦文本框的時候線會過度成一個對話框,掩蓋掉原本的對話框的形式,很好的一個創意 <body> ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...