絞り込み欄に文字を打つたび、画面がガクッと重くなった。“待ってから動く”を覚えた話

スケジュール表の絞り込み入力欄に文字を打つたび、画面が一瞬固まる感覚があった。
真面目に働きすぎていた処理を、デバウンスという“待ち”の仕組みで直した話。

管理画面のスケジュール表で、絞り込み欄に日付を打っていたときのことだ。
一文字打つたびに、画面がガクッと一瞬固まる。
別に壊れているわけじゃない。むしろ、ちゃんと仕事をしすぎていた。

入力するたびに、その場で全部の予定を洗い直して、絞り込み直していたんだ。
1文字打つ。全件見直す。もう1文字打つ。また全件見直す。
真面目すぎる働き方が、そのまま画面のカクつきになって出ていた。

キー入力は、想像より多く発火している

フォームの入力欄には、文字が変わるたびに「変わったよ」と知らせるイベントが仕込める。
便利な仕組みだけど、これが思っていたより忙しい。
「キャンプ場」と打つだけで、5回そのイベントが飛ぶ。

その5回それぞれで重たい絞り込み処理を律儀に動かしていたら、そりゃ画面も渋くなる。
僕がやりたかったのは「入力のたびに動く」ことではなく「入力が終わったら動く」ことだった。
同じ入力欄でも、求めていた動きは全然違ったんだ。

“待ってから動く”という発想

そこで使ったのが、デバウンスという考え方だった。
日本語にするなら「間を置く」あたりが近い。
直前の入力から一定の時間、何も打たれなかったら、そこで初めて処理を動かす、というだけの仕組みだ。

やっていることは単純で、キーが押されるたびに「ちょっと待ってから実行する」予約を入れる。
次のキーが来たら、その予約をいったんキャンセルして、また新しく予約を入れ直す。
だから連打している間は何も起きず、指が止まった瞬間にようやく1回だけ動く。

予約とキャンセルを繰り返しているだけ

中身はタイマーの仕掛けそのものだ。
「これくらい経ったら実行して」と時間を指定して予約を入れる関数と、その予約を取り消す関数の組み合わせでできている。
キーが押されるたびに、前の予約を取り消してから、新しい予約を入れ直す。それだけだ。

だから最後の1文字が打たれてから、指定した時間が過ぎるまで誰も邪魔をしなければ、そこで晴れて処理が実行される。
途中で次の文字が来たら、また振り出しに戻ってやり直し。
気の長い門番が、入力が落ち着くのをずっと見張っているようなイメージだ。

似ているようで別物の「間引き」

この手の話でよく一緒に出てくるのが、スロットルという別の仕組みだ。
デバウンスが「最後の1回だけ実行する」のに対して、スロットルは「一定間隔でしか実行させない」という間引き方をする。
スクロールみたいに、動いている間もそれなりに反応がほしい場面はスロットル向き、入力が落ち着いてから1回でいい場面はデバウンス向き、というのが僕の中の使い分けだ。

数字は、思ったより小さくていい

実際に入れた待ち時間は、200ミリ秒ほどだった。
体感でいうと、5分の1秒に満たない。
それだけなのに、画面のカクつきはうそのように消えた。

長く待たせすぎると、今度は「反応が遅い」と感じさせてしまう。
短すぎると、連打の途中でも処理が動いてしまって意味がない。
ちょうどいい間、というのは思ったより狭いところにあるらしい。

使う場所は選ぶ

便利だからといって、なんでもデバウンスすればいいわけではない。
たとえば「送信する」ボタンのクリックにまでこの間を挟むと、押した実感と結果がずれてしまって、逆に使いにくくなる。
待たせていいのは、あくまで「連打されがちな入力」に対してだけだと思っている。

絞り込みや検索窓のように、打っている途中はまだ答えを求めていない場面。
そこにだけそっと間を置いてあげると、忙しく働きすぎていた画面が、急に涼しい顔で仕事をするようになる。
たった200ミリ秒の間が、体感の重さをこんなに変えるとは思っていなかった。

技術ブログ一覧へ戻る