【パフォーマンス】Reactで優先度低めでごにょごにょするHooks
こんにちは。ぬこすけです。
コンポーネントの画面描画には優先度があるでしょう。
ECサイトを想像してみてください。
例えばユーザーの目に止まる商品の画像はできるだけ早く描画させて、ちょっとしたアイコンは遅く描画でも良いでしょう。
この記事では React で「他のコンポーネントの画面描画を優先させて、このコンポーネントは優先度を低く画面を表示したい」というようなケースが出てきたときに使える Hooks を紹介 します。
実装例
いきなりですが先に実装例を挙げます。
import { useEffect, useState } from 'react';
// ページのリソースが完全に読み込まれたことを通知する Hooks
const useDocumentLoadCompleted = (): boolean => {
const [isLoaded, setIsLoaded] = useState(false);
const loaded = () => setIsLoaded(true);
useEffect(() => {
if (document.readyState === 'complete') {
loaded();
return;
}
// またページが完全に読み込まれていないので、読み込みが完了したら処理させる
window.addEventListener('load', loaded);
return () => {
window.removeEventListener('load', loaded);
};
}, []);
return isLoaded;
};
export default useDocumentLoadCompleted;
この useDocumentLoadCompleted
Hooks は例えば次のように使います。
export const LowPrioriryImage: FC = () => {
const isLoaded = useDocumentLoadCompleted();
return isLoaded ? <Image /> : null;
}
解説
まずは Hooks の方を見てみましょう。
useEffect(() => {
if (document.readyState === 'complete') {
loaded();
return;
}
// またページが完全に読み込まれていないので、読み込みが完了したら処理させる
window.addEventListener('load', loaded);
return () => {
window.removeEventListener('load', loaded);
};
}, []);
肝となる実装はこの useEffect
のところでしょう。
こちらの記事にも書いてありますが、 document.readyState
と window.addEventListener('load', callback)
を組み合わせることで、 CSS や画像などのサブリソースを含めて完全にページの読み込みが完了してから処理を開始させることができます 。
export const LowPrioriryImage: FC = () => {
const isLoaded = useDocumentLoadCompleted();
return isLoaded ? <Image /> : null;
}
Hooks の利用側のコンポーネントは、「 CSS や画像など含めて完全にページが読み込まれた後に Image
コンポーネントを画面に描画する 」というような実装になっています。
これは簡単な例ですが、例えば React.lazy
と React.Suspense
を組み合わせるとより効力を発揮 するでしょう。
import { lazy, Suspense } from 'react';
const Image = lazy(() => import('./Image'));
export const LowPrioriryImage: FC = () => {
const isLoaded = useDocumentLoadCompleted();
return (
<Suspense>
{isLoaded && <Image />}
</Suspense>
)
}
Image
コンポーネントは初回に配信されるスクリプトからは除外されるために 初回の読み込みは早くなる でしょう。
CSS や画像など含めて完全にページが読み込まれて初めて Image
のスクリプトを読み込み、画面にコンポーネントを描画します。
まとめ
サクッとではありますが、 CSS や画像など含めてページが完全に読み込まれたことを通知する Hooks を作成し、コンポーネント描画の優先度を下げる 実装例を紹介しました。
他にもパフォーマンスチューニングに興味がある方は次の記事でアホみたいな量をご紹介しているので、ぜひ覗いてみてください!
ここまでご覧いただきありがとうございました! By ぬこすけ
Discussion