検索ボックスを実装したら画面が重たくなった…
という経験はないでしょうか。
考えられる原因はいくつかあると思いますが、基本的にonChangeが悪さをしていることが多いです。
原因:テキストが入力されるたびにonChangeで重たい処理が実行されてしまっている
処理が重くなりがちな例
example.js
const filteringName = (inputValue) => {
// 高負荷な処理
someHeavyProcessing();
if (inputValue) {
const filteredNames = nameListData.filter((name) =>
name.toLowerCase().includes(inputValue.toLowerCase())
);
setNameList(filteredNames);
} else {
setNameList(nameListData);
}
};
...
<TextField
margin="normal"
fullWidth
onChange={(e) => filteringName(e.currentTarget.value)}
/>
文字が入力されたり消されたりするたびに直接処理を呼び出しているため、処理の重さやユーザーのタイピング速度によってパフォーマンスに影響がでやすい。
解決策
テキスト入力が終わってから処理が実行されるようにカスタムフックを作ります。
useDebounce.js
import { useState, useEffect } from "react";
export function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
}
このカスタムフックでは第一引数に更新するstate,第二引数に何秒間の猶予を持たせるかを設定して発火のタイミングを調整します。
例のコードに当てはめてみる
example.js
import { useDebounce } from "../customHooks/useDebounce";
...
const [nameList, setNameList] = useState(nameListData);
// ↓onChange用
const [inputText, setInputText] = useState("");
// ↓今回はonChangeで更新されたテキストを0.5秒後にdebouncedInputTextとして返す設定にする
const debouncedInputText = useDebounce(inputText, 500);
const filteringName = (inputValue) => {
// 高負荷な処理
someHeavyProcessing();
if (inputValue) {
const filteredNames = nameListData.filter((name) =>
name.toLowerCase().includes(inputValue.toLowerCase())
);
setNameList(filteredNames);
} else {
setNameList(nameListData);
}
};
// ↓useEffectを使ってdebouncedInputTextの値が更新されたタイミングで処理を走らせる
useEffect(() => {
filteringName(debouncedInputText);
}, [debouncedInputText]);
...
<TextField
margin="normal"
fullWidth
onChange={(e) => setInputText(e.currentTarget.value)}
/>
流れを整理すると
① テキストフィールドにテキストが入力される
② 0.5秒間テキストが入力されなくなったらuseDebounceが値を返す
③ useDebounceの値更新をuseEffectで検知して本命の処理を実行させる
このようにすることで高負荷な処理があったとしても、文字が入力されるたびに実行されるのを防ぐことができます。
参考にさせていただいた記事
関連記事