🎈Debouncing

Debouncing เป็นเทคนิคที่มีประโยชน์ในการเพิ่มประสิทธิภาพ Performance ของ Client-side applications โดยเป็นหนึ่งเทคนิคในหลายสิ่งที่สำคัญในการพัฒนา Web App และ Software

# แนวคิด Debouncing

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

  • จะทำงานเมื่อหมดเวลาของ Delay และ User ไม่มีการกระทำใด ๆ กับ Input interface และเกิด Event

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

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

เพราะว่าอาจจะเกิด Events อื่น ๆ ก่อนที่จะให้ทำงานจริง ๆ (เช่น การพิมพ์ตัวอักษรหลาย ๆ ตัวที่พิมพ์ยังไม่เสร็จ ทำให้การ httpRequest() จะยังไม่ทำงานทันที) ลองดูตัวอย่าง code ด้านล่าง

// เพิ่มกำหนดตัวแปร Timeout ขึ้นมาตัวนึง
let timeout;

inputField.addEventListener('input', () => {
  // เมื่อเกิด Events ของ Input ให้ Reset ค่าใน Timeout
  clearTimeout(timeout)
  // เมื่อสิ้นสุด Delay 500 ms จะทำงานตาม Callback ที่กำหนดไว้คือ httpRequest()
  timeout = setTimeout(httpRequest, 500)
})
อธิบายการทำงานระหว่าง Regular และ Debounce
  • Regular คือวิธีแบบปกติที่ไม่ใช้เทคนิค Debouncing โดยทุก ๆ Events จะเกิด Execute

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

# ตัวอย่างการทำ Debounce ด้วย React by Lodash

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

import _ from "lodash"

const { debounce } = _

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

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

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

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

  const inputHandler = (event) => {
    const input = event.target.value
    httpRequest(input)
  }
  
  return (
    <>
      <input type="text" onInput={debouncedInputHandler}></input>
    </>
  )
}

Ref : https://blog.2my.xyz/2022/04/24/what-is-debouncing/

Last updated