본문 바로가기
웹 프론트엔드/Javascript

웹 성능 향상을 위한 Throttle과 Debounce 개념부터 활용까지

by canoe726 2020. 9. 7.
728x90

저는 Javascript 웹 페이지 제작을 하면서 성능 향상을 위해 쓰로틀(Throttle)과 디바운스(Debounce) 기능이라는 것을 알게 되었습니다.

 

그에 대한 이해를 더욱 깊이있게 하고 배운 것을 공유하기 위해 포스팅 하게되었습니다.

 

 

두 가지 기능에 대한 개념부터 활용까지 한 번 알아보겠습니다.

 

 

1. 둘의 개념과 사용법은?

 

1) Throttle 이란?

 

- 개념 : 여러 호출이 발생할 때 일정 시간이 지나기 전에는 기능이 호출 되지 않도록 하는 기능

 

- 사용예 : 무한 스크롤을 사용한 LazyLoading 기능을 구현할 때 사용, 스크롤로 인한 성능 저하 방지

 

 

왼쪽 : Throttle 미적용, 오른쪽 : Throttle 적용

 

 

Throttle을 적용하지 않으면 스크롤이 조금 움직일 때 마다 기능을 계속 호출하게 된다. 스크롤 이동시 많은 기능이 로드되어야 한다면 부하가 발생할 수 있다.

 

 

 

2) Debounce 란?

 

- 개념 : 일정 시간 동안 발생하는 여러 호출 중에 마지막 기능만 호출 되도록 하는 기능

 

- 사용예 : 키워드 검색과 같이 입력을 통한 API 호출을 사용할 때 사용

 

왼쪽 : Debounce 미적용, 오른쪽 : Debounce 적용

 

Debounce를 적용하지 않으면 입력이 발생할 때 마다 API 호출을 요청하여 많은 비용이 발생할 수 있다.

 

 

2. 코드는 어떻게 작성해야 하는가?

 

1) Throttle 기본 코드

 

스크롤 할 경우 console.log() 기능을 일정 시간 간격(200ms)마다 호출 하는 예제

 

var throttler;

window.onscroll = () => {
    // throttle
    if(!throttler) {
        throttler = setTimeout(() => {
            throttler = null;
            console.log('throttle');
        }, 200);
    }
}

 

 

2) Debounce 기본 코드

 

input에 입력을 할 경우 입력이 끝난 시점으로 부터 500ms 이후 console.log() 기능을 호출 하는 예제

 

var debouncer;

document.querySelector('.search').addEventListener('input', e => {
	// debounce
    if(debouncer) {
        clearTimeout(debouncer);
    }
    debouncer = setTimeout(() => {
        console.log('debounce');
    }, 500);
});

 

 

3. 활용 코드 예제

 

스크롤 기능과 API 호출 기능을 넣어서 간단한 예제를 작성해 보았습니다.

 

 

1) Throttle 예제 코드

 

스크롤 가장 하단에서 스크롤 할 경우 이미지를 표시하는 기능을 호출 하는 예제

 

 

- html 코드

 

<!DOCTYPE html>
<meta charset="utf-8">
<html>
    <head>
        <style>
            .long-area {
                height: 1200px;
            }
        </style>
    </head>
    <body>
        <div class="long-area">
            <img class="cat-image">
        </div>
        
        <script src="index.js"></script>
    </body>
</html>

 

 

- javascript 코드

 

var throttler;

var catImage = document.querySelector('.cat-image');
catImage.dataset.src = 'image/cat.jpg';

function getScrollTop() {
    return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body).scrollTop;
}

function getDocumentHeight() {
    const body = document.body;
    return Math.max(body.scrollHeight, body.offsetHeight);
}

window.onscroll = () => {
    // throttle
    if(!throttler) {
        throttler = setTimeout(() => {
            throttler = null;
            if (getScrollTop() < getDocumentHeight() - window.innerHeight) return;
            catImage.src = catImage.dataset.src;
            console.log('show Image');
        }, 200);
    }
}

 

 

2) Debounce 예제 코드

 

input 에 입력을 할 경우 입력이 끝난 시점으로 부터 500ms 이후 fetch() 기능을 호출 하는 예제

 

 

- html 코드

 

<!DOCTYPE html>
<meta charset="utf-8">
<html>
    <body>
        <input class="search">
        
        <script src="index.js"></script>
    </body>
</html>

 

 

- javascritp 코드

 

var debouncer;

const URL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';

const request = async () => {
    const response = await fetch(URL);
    if(response.ok) return response.json();
};  

// debounce
document.querySelector('.search').addEventListener('input', e => {
    if(debouncer) {
        clearTimeout(debouncer);
    }
    debouncer = setTimeout(async () => {
        const data = await request();
        console.log('검색어 : ', data.homeTown);
    }, 500);
});

 

 

- 참고한 사이트

 

1. zerocho

 

 

https://www.zerocho.com/category/JavaScript/post/59a8e9cb15ac0000182794fa

 

www.zerocho.com

 

 

728x90

댓글