Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Your skeleton screen is lying to your users

2026年10月27日に「Dev.to」が公開したITニュース「Your skeleton screen is lying to your users」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

読み込み中に表示される「スケルトンスクリーン」は、実際の画面が更新されると表示がずれる問題があった。`react-loadly` 3.1の`Skeletonize`は、実際の画面部品をそのまま仮表示として使うことで、レイアウトのずれを防ぐ。これにより、常に正しい表示を維持でき、開発の手間も省ける。

出典: Your skeleton screen is lying to your users | Dev.to公開日:

ITニュース解説

Webアプリケーションを開発する際、ユーザーが快適にサービスを利用できるよう、読み込み中の画面表示は重要な要素だ。その一つに「スケルトンスクリーン」という技術がある。これは、インターネットからデータが読み込まれるまでの間、真っ白な画面を表示する代わりに、コンテンツの骨格だけを先に表示しておく手法だ。例えば、SNSのタイムラインであれば、投稿の枠だけが先に表示され、後からプロフィール画像やテキスト、写真が埋まっていくようなイメージである。これにより、ユーザーは画面が固まっていると感じることなく、スムーズに次の情報へと目を移すことができるというメリットがある。

しかし、このスケルトンスクリーンには長年の課題があった。それは、一度作成したスケルトンスクリーンが、実際のUI(ユーザーインターフェース、つまり画面上の見た目)の変更に追従できないという問題だ。例えば、最初はプロフィールカードに名前と役割だけが表示されていたのが、後からバッジや二行の追加情報、より大きなアバターがデザイン変更によって加わったとする。このとき、もしスケルトンスクリーンが手動で設計されていれば、変更前の古いレイアウトのままで表示され続けてしまう。その結果、データが読み込み終わって実際のコンテンツが表示された瞬間に、画面のレイアウトが大きくずれてガタつく、いわゆる「レイアウトシフト」が発生してしまうのだ。これはユーザーにとって非常に不快な体験であり、スケルトンスクリーンが「嘘をついている」状態とも言える。本来はユーザーを助けるための機能が、かえってストレスを与えてしまうという皮肉な事態を引き起こす。

この問題に対処するための従来の解決策は、開発者にとって大きな負担となっていた。それは、常に実際のUIと同じレイアウトを持つスケルトンスクリーンを別途作成し、そして実際のUIが更新されるたびに、そのスケルトンスクリーンも手作業で更新して同期を取り続けるというものだ。これは「永遠に続く追加作業」であり、アプリケーションの規模が大きくなればなるほど、その保守コストは膨大なものとなる。開発チームが新しい機能の追加や改善に集中すべき時間を、このような「同期作業」に割かなければならないのは、決して効率的とは言えない。

このような背景の中、JavaScriptのフロントエンドライブラリであるReact向けに「react-loadly」というパッケージがバージョン3.1で大きく進化を遂げた。「Skeletonize(スケルトナイズ)」という新しいコンポーネントを導入することで、前述のレイアウトシフト問題と開発者の負担を根本から解決するアプローチを提案しているのだ。

「Skeletonize」の最も革新的な点は、「あなたのリアルコンポーネントが、そのまま自身のスケルトンになる」という発想にある。これまでのスケルトンスクリーンが、リアルなUIとは別の独立した存在だったのに対し、「Skeletonize」はリアルなUIコンポーネントそのものを利用して、その場でスケルトン表示を生成する。

具体的な使い方を見てみよう。例えば、画面にユーザーのプロフィールを表示するUserCardというコンポーネントがあるとする。このUserCardは、通常、バックエンドから取得したユーザーデータを受け取って表示するものだ。Skeletonizeを使う場合、このUserCardを<Skeletonize>コンポーネントで囲むように配置する。そして、Skeletonizeには現在データが読み込み中であるかを示すloadingというプロパティに、読み込み状態を渡す。さらに、UserCardには、データがまだ取得できていない場合の「プレースホルダーデータ」も渡しておく。このプレースホルダーデータは、例えばユーザー名に「Loading name」、役割に「Loading role」といった仮の文字列、アバターに空の値を設定しておくような形だ。

このように設定すると、loadingプロパティがtrue(つまり、データ読み込み中)の間は、Skeletonizeが自動的に動作する。UserCard内部にあるテキスト、画像、アイコン、入力フォームなどの各要素が、実際のコンテンツの「サイズ」と「位置」を正確に保ったまま、スケルトンブロック(灰色のアニメーションする四角)へと変換されるのだ。一方で、UserCardの外枠や背景色、ボーダー(枠線)、パディング(内側の余白)といった「コンテナ」としてのスタイルはそのまま維持される。もし、デフォルトではスケルトンブロックに変換されないが、開発者が特定の要素もスケルトン化したい場合は、その要素にdata-skeletonという属性を追加するだけで簡単に対応できる。

この「リアルコンポーネントが自身のスケルトンになる」という仕組みが、どのようなメリットをもたらすかというと、最も大きいのは「二重のレイアウトを維持する必要がなくなる」ことだ。開発者がUserCardにバッジを追加したり、レイアウトを変更したりしても、スケルトンはそのリアルコンポーネントの構造をそのまま利用しているため、自動的に新しいレイアウトに適応する。これにより、データが到着した際に画面がガタつく「レイアウトシフト」が完全に解消される。ユーザーは常に一貫した、滑らかな画面遷移を体験できるようになり、開発者はスケルトンを更新するという余計な作業から解放され、アプリケーションの機能開発に集中できる。

Skeletonizeコンポーネントは、見た目のカスタマイズ性も豊富に用意されている。スケルトンブロックの基本色やハイライト色、アニメーションの速度などを調整できる。アニメーションの種類も「shimmer(きらめき)」「wave(波打ち)」「pulse(脈打ち)」の中から選ぶことができ、アニメーションを完全にオフにすることも可能だ。これらの設定は、親コンポーネントであるSkeletonGroupLoaderからまとめて継承させることもできるため、アプリケーション全体で一貫したスケルトン表示を実現するのも容易だ。

また、アクセシビリティ(ユーザー補助)への配慮も行き届いている。データ読み込み中、Skeletonizeによって表示されるコンテンツは「inert(不活性)」かつ「aria-hidden(スクリーンリーダーから隠す)」という状態になる。これにより、視覚的に情報を得にくいユーザーがスクリーンリーダーを利用している場合でも、無関係なプレースホルダーテキストが次々と読み上げられて混乱することがない。代わりに、アプリケーションのステータスを伝えるための「role="status"」メッセージが一度だけ読み上げられ、ユーザーはアプリケーションの状況を正確に把握できる。さらに、アニメーション表示についても、ユーザーがオペレーティングシステムの設定で「prefers-reduced-motion(動きの少ない表示を好む)」を選択している場合には、それを尊重してアニメーションを抑制するようになっている。これは、一部のユーザーが画面の動きによって不快感を感じたり、集中力を失ったりするのを防ぐための重要な配慮だ。

Skeletonizeは、アプリケーションの他の部分ともスムーズに連携できるよう設計されている。データ読み込み状態が切り替わっても、子コンポーネントの内部状態(state)は保持されるため、ReactのHooksやContextといった機能が期待通りに動作する。また、CSSフレームワークのTailwind CSSや、サーバーサイドレンダリング(SSR)、そしてNext.jsのApp Routerといった最新の技術スタックにも対応しており、React 17、18、19といった様々なバージョン、Next.js 14、15、16といった幅広いバージョンで動作することが確認されている。これにより、多くの開発環境で安心して導入できる汎用性の高さを持っている。

react-loadlyパッケージには、Skeletonize以外にもいくつかの便利なローダーコンポーネントが用意されている。例えば、脈打つようなアニメーションを表示するPulseLoaderや、より基本的なスケルトン表示を提供するSkeletonLoader、複数のスケルトンをグループ化して管理するSkeletonGroupLoaderなどがある。中でもSkeletonSwitchLoaderは、データの読み込み中、エラー発生時、データが空の場合、そしてコンテンツが表示された通常の状態といった、様々なアプリケーションの状態に応じて適切なUIを切り替えて表示する機能を提供し、ローディング状態のハンドリングをより一層シンプルにする。

バージョン3.1では、機能追加だけでなく、技術的な改善も行われている。CommonJS形式のプロジェクトでrequire()が正しく動作しないという問題が修正され、またパッケージ全体のサイズも大幅に縮小された。これにより、アプリケーションのバンドルサイズ(最終的にユーザーにダウンロードされるファイルの大きさ)を小さく保ち、より高速な読み込みを実現することにも貢献している。

react-loadlyの「Skeletonize」は、ユーザー体験を向上させながら開発者の負担を軽減するという、Webアプリケーション開発における大きな一歩となるだろう。npm install react-loadlyというコマンド一つで簡単に導入できるため、ぜひ実際に試して、その効果を体験してみてほしい。

関連コンテンツ

関連IT用語

関連ITニュース