Ijul's Journal

Mengenal Debounce Function

October 23, 2019

Debounce function adalah higher-order function yang digunakan untuk menunda eksekusi kode dengan waktu yang ditentukan. Penggunaan fungsi debounce ini memberikan kontrol agar proses sebelumnya berjalan terlebih dahulu, lalu mengeksekusi perintah dalam function yang didebounce.

Pada saat mengembangkan aplikasi web dengan menggunakan react atau library/framework javascript lain akan tiba saatnya menghadapi kasus harus menunda pengeksekusian suatu kode agar lebih efisien dan tidak mengganggu performance.

Contoh kasus penggunaan fungsi debounce ini biasanya pada fitur pencarian.

Contoh gambar pencarian

Dengan kode seperti di bawah

import React from 'react'
import axios from 'axios'

class App extends React.Component {
  state = {
    data: [],
  }

  handleChange = async e => {    try {      const animes = await axios.get('https://api.jikan.moe/v3/search/anime', {        params: {          limit: 5,          q: e.target.value        }      })      this.setState({        data: animes.data.results      })    } catch (error) {      console.log(error)    }  }
  render() {
    return (
      <>
        <h3>Cari anime</h3>
        <input type="text" onChange={this.handleChange} placeholder="masukkan judul anime" style={{ width: '20%' }} />        <div>
          hasil yang dicari:
          <ul>
            {this.state.data.map((anime, i) => (
              <li key={i}>{anime.title} ({anime.episodes} eps.) </li>
            ))}
          </ul>
        </div>
      </>
    )
  }
}

export default App

Setiap kali element input menerima masukkan akan memanggil method handleChange melalui event handler onChange. Sedangkan setiap event yang diterima di method tersebut akan langsung melakukan http request.

Ini berarti akan memberatkan performance karena terlalu banyak request setiap ada event. Jika kita mau memasukkan keyword naruto, maka akan ada 6 request.

pencarian keyword naruto

Setiap huruf yang diketikkan akan langsung dilakukan request dan ini tidak perlu dilakukan, malah akan membebani browser dan menghabiskan internet kuota user.

Oleh karenanya kita hanya ingin melakukan request pada saat user selesai mengetikkan keywordnya. Hal itu bisa kita lakukan dan siasati dengan debounce.

fungsi debounce bisa kita import dari library underscorejs atau bisa kita buat file sendiri.

// debounce.js
module.exports = (func, wait, immediate) => {

  var timeout;

  return function executedFunction() {
    var context = this;
    var args = arguments;

    var later = function () {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    var callNow = immediate && !timeout;

    clearTimeout(timeout);

    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };
};

Setelah diimport, lalu bungkus method handleChange dengan debounce dan beri waktu tunda untuk menunggu sampai menjalankan method tersebut.

import React from 'react'
import axios from 'axios'
import debounce from './debounce'

class App extends React.Component {
  state = {
    data: [],
  }

  handleChange = debounce(async keyword => {    try {      const animes = await axios.get('https://api.jikan.moe/v3/search/anime', {        params: {          limit: 5,          q: keyword,        },      })      this.setState({        data: animes.data.results      })    } catch (error) {      console.log(error)    }  }, 1000)
  render() {
    return (
      <>
        <h3>Cari anime</h3>
        <input type="text" onChange={e => this.handleChange(e.target.value)} placeholder="masukkan judul anime" style={{ width: '20%' }} />        <div>
          hasil yang dicari:
          <ul>
            {this.state.data.map((anime, i) => (
              <li key={i}>{anime.title} ({anime.episodes} eps.) </li>
            ))}
          </ul>
        </div>
      </>
    )
  }
}

export default App

Di baris 10-24 kita bungkus perintah method handleChange menjadi argumen pertama dari fungsi debounce, argumen kedua kita beri 1000 yang berarti waktu menunggu 1000ms.

Kemudian di baris 30, di event handler onChange kita hanya mengirim ke method handleChange isi keywordnya dari event element input saat menerima masukan.

Sehingga hasil pada saat menggunakan fungsi debounce akan seperti ini, hanya melakukan request satu kali.

Contoh gambar pencarian dengan debounce


Afrijal Dzuhri

Written by Afrijal Dzuhri who lives and works in Yogyakarta.