[073] 플러터 (Flutter) 배우기 - Throttle 적용하여 리스트뷰(ListView) 페이지네이션 API 중복 호출 방지하기

2024. 5. 26. 19:31모바일어플개발/Flutter

반응형

안녕하세요 totally 개발자입니다.

 

이 포스팅에서는 플러터 패키지 중 debounce_throttle을 사용하여 Throttle 개념을 적용해보도록 하겠습니다.

 

우선 Throttle의 사용 목적에 대해서 알아야 합니다. 이 포스팅 이후에 Debounce에 대해서도 다룰 것이지만 Throttle과 Debounce는 비슷해보이나 서로 다른 목적을 가지고 있습니다. Throttle은 일정한 주기 동안 특정 함수가 여러 번 호출된 경우 함수를 한 번만 바로 실행하고 연속적으로 함수를 호출하는 것은 방지할 수 있습니다. 반대로 Denounce는 정해진 시간 동안 특정 함수가 여러 번 호출된 경우 마지막으로 실행된 함수를 호출합니다.

 

Throttle 특정 시간 동안 여러 번의 함수 호출이 있을 경우 함수를 한 번만 실행
Debounce 특정 시간 동안 여러 번의 함수 호출이 있을 경우 마지막 함수 호출만 실행

 

Throttle과 Denounce가 사용되는 예시는 아래와 같습니다.

Throttle 리스트뷰(List View), 그리드뷰(Grid View) 페이지네이션 등
Debounce 숫자를 증감시키는 경우, 텍스트를 입력할 때 변경될 때마다 호출하는 경우 등

 

이 포스팅에서는 Throttle을 사용하여 ListView의 스크롤하여 페이지네이션을 진행할 때 중복 API 호출을 방지해보도록 하겠습니다. 저희가 사용할 패키지는 아래에 있는 debounce_throttle입니다. 자세한 예제는 아래를 참고해주시면 됩니다.

https://pub.dev/packages/debounce_throttle

 

debounce_throttle | Dart package

A debouncer and throttle that works with Futures, Streams, and callbacks.

pub.dev

 

 

먼저 예전 포스팅에서 다뤘던 ListView Pagination 부분 코드를 대부분 가져와서 예제 실습을 해보도록 하겠습니다.

https://totally-developer.tistory.com/119

 

[046] 플러터 (Flutter) 배우기 - ListView.builder + 스크롤 Pagination 적용

안녕하세요~ totally 개발자입니다. ListView.builder + Pagination 이번에는 ListView.builder를 사용하여 스크롤을 내렸을 때 다음 페이지, 추가 내용을 가져와서 보여주는 스크롤 페이지네이션(Pagination) 구현

totally-developer.tistory.com

 

Step 1: 먼저 pubspec.yaml 파일에 http 패키지말고 dio 패키지로 대체하고, debounce_throttle 패키지도 추가하여 줍니다.

 

Step 2: 아래 패키지들을 import 합니다. 모든 소스 코드는 맨 아래에 있습니다.

 

 

Step 3: 아래 _HomePageState 부분처럼 변수들을 선언하여 줍니다. 그 중에서도 37-40번째 부분이 새롭게 추가된 부분으로 Throttle 변수 2개와 _count 변수도 만들어줍니다. _throttledNextLoad는 리스트뷰 페이지네이션 스크롤을 위해, _throttledButtonClick은 버튼 클릭시 숫자를 증감시킬 목적으로 선언한 변수입니다.

 

 

Step 4: 아래처럼 initState 부분을 구성해줍니다. 보통 Throttle에는 Duration(기간) 설정, initialValue(초기값) 설정, checkEquality(함수 실행할 때 전달된 값이 같은지 여부 판단) 설정 등 데이터를 초기화하도록 되어 있고 ..values.listen을 붙여서 어떤 함수를 대상으로 Throttle를 설정할 것인지 정하면 됩니다. 첫 번째 Throttle에는 _nextLoad 즉 리스트뷰에서 그 다음 리스트를 받아오는 부분이고, 56-60번째 라인은 사용자가 스크롤을 내렸을 때, 그 다음 Throttle의 _nextLoad를 호출하도록 만들어줍니다. 물론 저는 예전 예시부터 setState로 자체적으로 page 변수 등을 업데이트하였기 때문에 별도의 초기값과 setValue 파라미터를 설정해줄 필요 없이 null 값으로 진행하였으나 Provider 등 다른 상태 패키지를 사용하는 경우에는 인스턴스 형태나 다른 값이 들어가게 됩니다. Duration(milliseconds: 1000)은 1초를 의미합니다. 즉 1초 동안 아무리 많이 함수를 호출했다 하더라도 함수를 한 번만 실행하게 됩니다. 이 부분은 추후 숫자를 증가시킬 때 확실하게 보실 수 있습니다.

 

 

Step 5: _nextLoad 함수 부분인데 이 부분은 기존 포스팅에 있는 내용과 같습니다.

 

 

Step 6: dispose 메소드 부분으로 해제할 부분들 해제하시면 됩니다.

 

 

Step 7: 다른 Throttle 부분인 _increaseCount 부분입니다.

 

 

Step 8: Widget build 부분으로 맨 아래에 floatingActionButton만 추가하였습니다. 모든 소스 코드는 맨 아래에 있습니다.

 

 

Step 9: 실행해본 모습입니다. 아래와 같이 표시됩니다.

 

 

Step 10: 숫자 증가시키는 부분도 1초에 몇 번을 클릭하든지, 함수가 한 번만 실행되어 업데이트됩니다. 물론 이 숫자 관련된 업데이트는 Debounce가 상황에 따라 더 적절할 수도 있는 것이 이 Throttle은 일정한 기간 내 함수 한 번만 실행되어 어차피 마지막에 업데이트된 값을 추가로 업데이트시켜야 하는데 비해, Debounce를 사용하면 특정 시간 내에 같은 함수가 여러 번 호출되었을 때 마지막의 값을 전달하는 함수만 업데이트 되므로 효율적으로 데이터를 처리할 수 있습니다. 이 Debounce 관련해서는 다음 포스팅에서 진행해보도록 하겠습니다.

 

[전체 소스 코드]

 

 

[유튜브 강좌 영상]

 

https://youtu.be/NhW7JprHZ7w

 

 

반응형