Skip to main content

Throttling คืออะไร แตกต่างกับ Debouncing อย่างไร (ตอนจบ)

· 3 min read
Kongvut Sangkla

Intro

สวัสดีครับ จากบทความครั้งก่อนได้พูดถึง เทคนิค Debouncing โดยบทความนี้จะพูดถึงเทคนิค Throttling ที่มีความคล้ายคลึงกัน ซึ่งเป็นเทคนิคที่มีประโยชน์ช่วยเพิ่มประสิทธิภาพ Performance ได้ทั้ง Frontend App และ Backend App ที่ช่วยแก้ปัญหาการเกิด callback จำนวนมากจาก Event listeners มีรายละเอียดดังนี้

Throttling

Throttling คือการหน่วงเวลา (Delay) ในระยะหนึ่งก่อนที่จะให้ทำงานใด ๆ โดยมีเงื่อนไขดังนี้

  • จะทำงานเมื่อหมดเวลาของ Delay และยังมีการกระทำกับ Input
  • ค่าของ Delay จะเริ่มต้นใหม่ไปเรื่อย ๆ เมื่อหมดเวลาของ Timeout

จากตัวอย่างด้านล่างเป็นการใช้ Timeout เพื่อกำหนด Delay 1000 ms และมีตัวแปร isWaiting เพื่อตรวจสอบการรอคอย

จากนั้นเมื่อเกิด Events ใด ๆ ก็จะถูก Ignore และหน่วงการทำงาน (ไม่ให้ทำงานทันที)

เมื่อสิ้นสุด Delay 1000 ms และ isWaiting เป็น false โปรแกรมก็จะทำงานตาม Callback ที่กำหนดไว้

แนวคิดของ Throttling
// เพิ่มกำหนดตัวแปร Timeout ขึ้นมาตัวนึง
const timeout = 1000
let isWaiting = false

inputField.addEventListener('input', () => {
if (!isWaiting) {
isWaiting = true
callback()
setTimeout(() => (isWaiting = false), timeout)
}
})

การนำ Throttling ไปใช้

  1. ใช้ Throttling เพื่อหน่วงการทำงานหลังการ Click เพื่อป้องกันไม่ให้เกิด Spam click
  2. ใช้ Throttling เพื่อหน่วงเวลาเมื่อเรียก API
  3. ใช้ Throttling กับ event handler mousemove/touchmove
  4. ใช้ Throttling กับการสร้างเกมส์ เช่น เงื่อนไขการยิง เงื่อนไขการชก ที่ใช้หน่วงเวลาป้องกันการกดปุ่มรัว ๆ
  5. ใช้ Throttling เพื่อป้องกันการเกิด Requests จำนวนมากในการ Load ข้อมูลใหม่เมื่อ Scroll event หน้าเว็บเพจ

ตัวอย่างการใช้งาน Throttling

แบบไม่ได้ใช้เทคนิค Throttling

เมื่อใช้เทคนิค Throttling

ความแตกต่างระหว่าง Throttling Vs. Debouncing

Throttling และ Debouncing มีหลักการทำงานคล้ายคลึงกันโดยอาศัย Delay แต่มีความแตกต่างกันดังนี้

อธิภายการทำงานจากรูปภาพ

  • Regular คือวิธีแบบปกติที่ไม่ใช้เทคนิค Debouncing โดยทุก ๆ Events จะเกิด Execute
  • Debounce คือวิธีแบบที่ใช้เทคนิค Debouncing โดยทุก ๆ Events จะไม่ทำงานทันทีจนกว่าจะเลิกทำกระทำกับ Input แล้วครบ Delay จึงจะ Execute
  • Throttle คือวิธีแบบที่ใช้เทคนิค Throttling โดยทุก ๆ Events จะไม่ทำงานทันทีจนว่าจะครบ Delay และยังมีการกระทำกับ Input จึงจะ Execute

Throttling with Lodash

ในภาษา JS เราไม่จำเป็นต้อง Implement Throttling เองให้เสียเวลา โดยเราสามารถใช้ Library ของ Lodash ช่วยดังนี้

import _ from "lodash"

const logHi = () => console.log('Hi')

const throttleLogHi = _.throttle(logHi, 100)

throttleLogHi()

// output: Hi

Throttling with React

Basically

ตัวอย่างการใช้ Throttling กับ React โดยพื้นฐาน (แบบไม่ใช้ Libs)

Live Editor
Result
Loading...

by Lodash

นี่คือตัวอย่างการใช้ Throttling ใน React และใช้ Library จาก Lodash

แต่จะมีการใช้ useMemo และ useCallback เข้ามาช่วยป้องกันปัญหาเรื่อง Re-renders ที่ส่งผลต่อประสิทธิภาพ

อ่านเนื้อหาเพิ่มเติมเกี่ยวกับการใช้งาน useMemo และ useCallback อย่างละเอียดได้ที่นี่ "การใช้งานและความแตกต่างระหว่าง useMemo และ useCallback ของ React Hooks"

import _ from "lodash"

const { throttle } = _

() => {
// Request statement
function httpRequest(input) {
// Call API ...
}

// ใช้แบบนี้ก็ได้ แต่จะมีปัญหาเรื่อง Re-renders
//const throttleInputHandler = throttle(inputHandler, 500)

// แนะนำให้ใช้ useCallback เข้ามาช่วยลดปัญหา Re-renders และให้ประสิทธิภาพที่ดีกว่า
const throttleInputHandler = useCallback(
throttle(inputHandler, 500), []
)

// หรือจะใช้ useMemo ก็ได้เช่นกัน
/*const throttleInputHandler = useMemo(() => {
return throttle(changeHandler, 500);
}, []);*/

const inputHandler = (event) => {
const input = event.target.value
httpRequest(input)
}

return (
<>
<input type="text" onInput={throttleInputHandler}></input>
</>
)
}

สรุป

Throttling เป็นเทคนิคที่เรียบง่ายและเข้าใจง่าย และยังช่วยปรับปรุงประสิทธิภาพอย่างมาก หวังว่าผู้อ่านจะสามารถปฏิบัติและนำแนวคิดนี้ไปใช้ได้อย่างมีประสิทธิภาพ ขอบคุณที่อ่านจนจบ 😊

References

Loading...