# throttleでスクロールイベントを間引く
##  throttle、debounceについて
- throttle … 実行してから一定間隔内に発生した処理を無視
- debounce … 連続したイベントの最後だけ一定間隔で実行  

どちらも、大量に連続でイベントが発生し、無駄に処理を発生させたくない時に用いる。

## 今回のタスク
今回のGrowiの[タスク](https://github.com/weseek/growi/pull/1839)では「一定量スクロールしたら、subnavigationのコンパクト版をページの上部に固定する」ということを行った。`throttle`と`debounce`どちらも似ている処理だが、「スクロールする→処理→スクロールする→0.3秒後処理→スクロールする→0.3秒後処理→...」という流れにしたいので、ここでは連続的に発生するスクロールイベントにおいては、連続したイベントの最後だけ実行する`debounce`ではなく**一定間隔で間引く**`throttle`の方を使用。  

今回はnpmの[throttle-debounce](https://www.npmjs.com/package/throttle-debounce)を使用。

そして今回、該当箇所は以下のようなコードとなった
```javascript:PageContainer.jsx
import { 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`で行っている。


## 関連記事
- https://tips.weseek.co.jp/%E7%94%A8%E8%AA%9E%E9%9B%86/Javascript/throttle-debouce%E3%81%AEthrottle%E3%81%A8debouce%E3%81%AE%E9%81%95%E3%81%84
- [throttleとdebounce](https://aloerina01.github.io/blog/2017-08-03-1)  
- [jsイベント間引き(throttle+debounce) - Qiita](https://qiita.com/akuden/items/5a24b0bd4b02b6756730)  
- [throttle-debounce - npm](https://www.npmjs.com/package/throttle-debounce)

---

## Page Navigation

- Canonical URL: https://tips.weseek.co.jp/開発日記/throttleでスクロールイベントを間引く
- Permalink: https://tips.weseek.co.jp/5e8de43931511b0048ecf612
- Parent: [開発日記](/5e3d294bcff797004b16abba.md)
- Children: 0 total
- Total descendants: 0
- Siblings: 20 total
  - [GROWIのAPIを使用したアプリケーション](/5e5bd0e3e7f8db0048df3a08.md)
  - [GitとGitHubの違い](/5e417dcadecd0a0049953ad7.md)
  - [LDAP攻略への道](/5e48b2561ec5e4004811d4e9.md)
  - [Migrationsファイルを作成する](/5e9d1dc7b682620049e55a64.md)
  - [QiitaでGROWIが設計書システムとして紹介されました](/5e535a04eb17ce0048b9fb13.md)
  - [UserManagement](/65069da24603e7ff39a6b3d2.md)
  - [aタグ以外での画面遷移](/5e9cfd51b682620049e55a5d.md)
  - [jestを使ったテストを初実装しました](/5ef1ed225eea4b004a1912b2.md)
  - [npm とyarn の違いを簡単に説明](/5e3e6822591d7f0048b3cc5e.md)
  - [react-card-flipを使って回転するカードレイアウトを作る](/5ebaa05ad3055000488bd526.md)
  - [vuepressのテンプレート内で二重波括弧をエスケープ](/5f16ecf4c2f6150048b2955b.md)
  - [なぜsetStateをComponentDidMountで使用してはいけないのか](/5eb7728458c8ea00480d0825.md)
  - [アジャイルとウォーターフォール](/5e4137d343c1c400499b6bac.md)
  - [セルフレビューはどこまで確認しようか](/5e3d2adfcff797004b16abbe.md)
  - [ソート機能の実装](/5e8aadc15245e70048c22c7c.md)
  - [タスクを円滑にこなすために必要な垂れ流しとは](/5e47a18a927c020048448a18.md)
  - [ページ内リンクの実装](/5e93c9d511007300489677ff.md)
  - [レビュー依頼する際に確認すること](/5e3ae41225751e00499297f6.md)
  - [動作確認用にページをたくさん作りたい](/5f80326633588b0048eaf865.md)
  - [間違えてマージしてさらにプッシュしちゃった](/5e9d176db682620049e55a60.md)
- Last updated: 2020-04-08T14:50:54.500Z by deleted_at_1672138060255
- Full page listing (all children regardless of count): https://tips.weseek.co.jp/_api/v3/page-listing/children?id=5e8de43931511b0048ecf612
