ローディング

最終更新: 2022年02月11日

ローディングの種類

通常のWebサイトと違いNext.jsのようにクライアントサイドで画面をレンダリングする場合自分でページ読み込みを意味するローディングUIを実装する必要があります。

ローディングには2パターンあります。部分的ローディングと画面全体のローディングです。画面全体をローディングさせる場合サイト上部に動くアニメーションバーを表示させるのが一般的です。部分的ローディングの場合ローディングアイコンが該当箇所で回転するUIが一般的に用いられます。

実装

ローディングが必要であるということはそのページを開いた時点で何らかのデータがリクエストされ、値が返却されるのを待つ必要がある状態ということです。isLoading などのStateを用意し、必要なデータが揃った時点で isLoadingfalse にすることでUIを切り替えます。

全体ローディング

const ExamplePage = () => { const [isLoading, setIsLoading] = useState<boolean>(true); const [data, setData] = useState(); useEffect(() => { // DBにデータをリクエスト fetch('...').then((data) => { // 必要なデータをセットする setData(data); // ローディング状態を無効にする setIsLoading(false) }); }, []); // ローディング状態であればローディングUIを表示する if (isLoading) { return <p>ローディング中</p>; } // そうでなければ画面を表示する return ( <div> <h2>ユーザーデータ</h2> <p>ユーザーのデータを確認してください。</p> {/* データ */} </div> ); }

この例の場合ローディング状態であればローディングUIのみを表示しています。レイアウトが存在する場合コンテンツ部分のみがローディング状態になります。

部分的ローディング

前述の例で <p>ユーザーのデータを確認してください。</p> などの部分は無条件に表示させておき、あくまでデータ部分のみをローディング状態であると示したい場合部分に表示を切り分けます。

以下の切り分けを削除します。

if (isLoading) { return <p>ローディング中</p>; }

該当箇所にローディングの条件分岐を実装します。

return ( <div> <h2>ユーザーデータ</h2> <p>ユーザーのデータを確認してください。</p> {isLoading ? <div>ローディングアイコン</div> : {/* データを表示 */} </div> );

ちらつきをなくす

制限に達したモバイル回線でもない限り Firestore や Vercel との通信は一瞬で終わります。にもかかわらずロジック的にローディングUIは一瞬表示されてしまうので、ユーザーにとっては一瞬だけローディングUI的な何かが表示されてすぐ消える、という状態になりむしろ不快感を与えることがあります。

ちらつきをなくすコツはローディングUIの表示に0.5〜1秒のアニメーションを加えることです。ローディングUIの該当箇所を以下のように調整します。CSS単体では要素の存在自体が切り替わるタイミングにアニメーションをかけることはできないので Headless UI などのライブラリを使います。

npm install @headlessui/react

ローディングUIの箇所を以下のように書き換えます。

<Transition show={isLoading} enter="transition-opacity duration-75 delay-500" enterFrom="opacity-0" enterTo="opacity-100" leave="transition-opacity duration-150" leaveFrom="opacity-100" leaveTo="opacity-0" > ローディングバー、ローディングアイコン </Transition>

こうすることで表示までに若干タイムラグが生まれるようになるので、その間にローディングが終わった場合ローディングUIの表示を回避することができ、ちらつきがなくなります。