throttleでスクロールイベントを間引く
throttle、debounceについて
- throttle … 実行してから一定間隔内に発生した処理を無視
- debounce … 連続したイベントの最後だけ一定間隔で実行
どちらも、大量に連続でイベントが発生し、無駄に処理を発生させたくない時に用いる。
今回のタスク
今回のGrowiのタスク external_linkでは「一定量スクロールしたら、subnavigationのコンパクト版をページの上部に固定する」ということを行った。throttle
とdebounce
どちらも似ている処理だが、「スクロールする→処理→スクロールする→0.3秒後処理→スクロールする→0.3秒後処理→...」という流れにしたいので、ここでは連続的に発生するスクロールイベントにおいては、連続したイベントの最後だけ実行するdebounce
ではなく一定間隔で間引くthrottle
の方を使用。
今回はnpmのthrottle-debounce external_linkを使用。
そして今回、該当箇所は以下のようなコードとなった
PageContainer.jsximport { throttle } from 'throttle-debounce'; ... const scrollAmountForFixed = 122; ... export default class PageContainer extends Container { constructor(appContainer) { ... isCompactMode: false, }; ... window.addEventListener('scroll', throttle(300, () => { this.setState({ isCompactMode: window.pageYOffset > scrollAmountForFixed }); })); ...
scrollイベントが発生し、一定量スクロールした時にページの上部に固定表示するかどうか(true/false)を0.3秒毎にstateを更新するようにしている。なお、固定表示する処理は子コンポーネントのGrowiSubNavigation.jsx
で行っている。