基礎から学ぶJavaScript入門 90日コース | 非同期処理とAPI - Day 62:ローディング処理

JavaScript 90日で身につけるJavaScript
スポンサーリンク
スポンサーリンク

Day 62:ローディング処理

Day 62では、第5フェーズ「非同期処理とAPI」の実践として、ローディング処理を学びます。今回の学習内容は、ローディング表示と、データ取得完了後にそれを非表示にすることです。Day 59からDay 61にかけて、fetch() を使ったAPI通信、公開APIからのデータ取得、取得したデータのHTML表示までを学んできました。ここまでで、外部データを取得して画面へ表示する基本的な流れはつかめてきました。しかし、実際のアプリとして考えると、まだ大事な要素が1つ足りません。それが「今、読み込み中であることをユーザーに伝える仕組み」です。

API通信は、必ずしも一瞬で終わるとは限りません。ネットワークの状況、取得するデータ量、サーバーの状態などによって、少し待ち時間が発生することがあります。そのとき、画面に何も変化がないと、使う人は「ボタンが反応していないのかな」「壊れているのかな」と不安になってしまいます。そこで必要になるのがローディング表示です。ローディング表示は、単なる飾りではありません。「今、処理中です」「少し待ってください」という情報を伝える、とても大切なユーザー案内です。

初心者の方は、ローディング処理を「見た目の演出」だと思いがちですが、実際には使いやすさを大きく左右する機能です。そして、非同期処理を学ぶ上でも非常に良い練習になります。なぜなら、ローディング表示は「処理が始まる前に表示し、終わったら消す」という、非同期処理の前後関係をはっきり考える必要があるからです。つまり、Day 62はUI改善の一部であると同時に、「非同期処理の流れを正しくつかむ練習」でもあります。今回も、初心者向けに、なぜ必要なのか、どのタイミングで表示・非表示を切り替えるのか、何に注意するのかを、ステップバイステップで丁寧に解説していきます。

まず最初に結論をつかむ

最初に今回の内容を一言でまとめると、ローディング処理とは「データ取得が始まったら読み込み中の表示を出し、取得が終わったらその表示を消す処理」です。

流れをとてもシンプルにすると、次のようになります。

  • ボタンを押す
  • ローディング表示を出す
  • APIからデータを取得する
  • データを画面に表示する
  • ローディング表示を消す

初心者の方は、まずこの順番をしっかり頭に入れることが大切です。特に重要なのは、「取得する前に出す」「終わったら消す」という前後関係です。

なぜローディング表示が必要なのか

ここはDay 62の中心です。なぜローディング表示が必要なのかというと、ユーザーに「今何が起きているか」を伝えるためです。アプリの内部ではAPI通信が進んでいても、画面上に何も変化がなければ、使っている人にはそれが見えません。すると、何も起きていないように感じてしまいます。

たとえば、ボタンを押してから2秒待たないとデータが表示されないとします。その2秒間、何の表示も変化しなければ、次のような誤解が起きやすいです。

  • ボタンが押せていないと思う
  • アプリが止まったと思う
  • もう一度何度もボタンを押してしまう

ローディング表示があれば、「ちゃんと動いています」「今読み込んでいます」と伝えられます。初心者の方は、ローディング表示を「親切な案内表示」と考えると理解しやすいです。

ローディング処理は非同期処理の流れ理解にも役立つ

ローディング表示はUIのためだけではありません。学習上もとても価値があります。なぜなら、ローディング処理を正しく書くには、非同期処理の始まりと終わりを意識する必要があるからです。

つまり、次のことを順番に考える練習になります。

  • 処理開始前に何をするか
  • 処理中に何を見せるか
  • 処理完了後に何を戻すか
  • 失敗した場合にどうするか

初心者の方は、ローディング処理を通して「非同期処理は結果だけでなく途中状態も扱う」という感覚を身につけることができます。

まずはローディング表示の場所を用意する

最初のステップとして、HTMLにローディング表示用の要素を用意します。たとえば、次のようにします。

<p id="loading" style="display: none;">読み込み中です...</p>

ここで display: none; にしているのは、最初は見えない状態にしておくためです。つまり、ページを開いた直後はローディング表示は出ていません。必要になったときだけ表示します。

初心者の方は、「ローディング表示は最初からずっと出すものではなく、処理中だけ一時的に出すもの」と理解すると整理しやすいです。

ステップ1:まず表示だけ切り替えてみる

いきなりAPIと組み合わせる前に、まずはローディング表示のON/OFFだけを練習するとわかりやすいです。

const loading = document.getElementById("loading");

// ローディング表示を出す
loading.style.display = "block";

// ローディング表示を消す
loading.style.display = "none";
JavaScript

これだけで、ローディング要素を表示したり隠したりできます。初心者の方は、ここで「見せるときは block、隠すときは none」という基本を押さえておくとよいです。

ステップ2:疑似的な待ち時間で練習する

次に、API通信の代わりに setTimeout() を使って、ローディング表示の流れを練習してみます。

const loading = document.getElementById("loading");

// ローディングを表示する
loading.style.display = "block";

// 2秒後にローディングを消す
setTimeout(function () {
  loading.style.display = "none";
}, 2000);
JavaScript

このコードでは、ローディングが表示されてから2秒後に消えます。初心者の方は、ここで「待っている間だけ表示する」という感覚をつかむことが大切です。

なぜいきなり fetch と組み合わせないのか

この順番にも意味があります。初心者の方はいきなり全部つなげたくなるかもしれませんが、ローディング表示そのものの仕組みと、API通信の仕組みを分けて練習したほうが理解しやすいです。

  • まず表示・非表示だけを理解する
  • 次に待ち時間と組み合わせる
  • 最後に実際のAPI通信へつなげる

このように段階を分けると、「何が難しいのか」が見えやすくなります。初心者向けの学習では、この分解がとても大切です。

ステップ3:fetch() とローディング表示を組み合わせる

では、いよいよAPI通信とローディング表示を組み合わせます。基本形は次の通りです。

async function loadData() {
  // ローディングを表示する
  loading.style.display = "block";

  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  const data = await response.json();

  console.log(data);

  // ローディングを消す
  loading.style.display = "none";
}
JavaScript

このコードでは、データ取得を始める前にローディングを表示し、データ取得が終わったあとにローディングを消しています。これがDay 62の基本形です。

初心者の方は、この順番を何度も確認するとよいです。

  • 先に表示する
  • そのあと取得する
  • 最後に消す

ただしこのままではエラー時に問題がある

ここは非常に重要なので深掘りします。先ほどのコードは成功時にはうまく動きますが、もし fetch() に失敗したらどうなるでしょうか。途中でエラーが起きると、最後の loading.style.display = "none"; までたどり着かず、ローディング表示が出たままになる可能性があります。

これは初心者の方がよくつまずく点です。つまり、ローディング処理では「成功したときだけ消す」のでは不十分です。「失敗したときも必ず消す」必要があります。

ステップ4:try…catch でエラー対応する

そのため、try...catch を使ってエラー処理も考えます。

async function loadData() {
  try {
    // ローディングを表示する
    loading.style.display = "block";

    const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const data = await response.json();

    console.log(data);
  } catch (error) {
    console.log("データ取得に失敗しました。", error);
  }

  // 成功でも失敗でもローディングを消す
  loading.style.display = "none";
}
JavaScript

このようにすれば、成功でも失敗でも最後にローディングを消せます。初心者の方は、「ローディングは終わったら必ず消す必要がある」と意識すると大切さが見えてきます。

ステップ5:画面表示まで含めて完成させる

Day 61で学んだ画面表示と組み合わせると、次のような形になります。

async function loadTodo() {
  try {
    // ローディング表示を出す
    loading.style.display = "block";

    const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const data = await response.json();

    // データを画面に表示する
    result.textContent = data.title;
  } catch (error) {
    // エラー時の表示
    result.textContent = "データの取得に失敗しました。";
  }

  // データ取得完了後にローディングを消す
  loading.style.display = "none";
}
JavaScript

この流れで、ローディング表示とデータ表示がきれいにつながります。初心者の方は、「読み込み中の見た目」と「結果の見た目」を分けて考えると理解しやすいです。

複数件のデータ表示にも応用する

1件のデータだけでなく、複数件の一覧表示でもローディング処理は同じ考え方で使えます。

async function loadTodos() {
  try {
    loading.style.display = "block";
    todoList.innerHTML = "";

    const response = await fetch("https://jsonplaceholder.typicode.com/todos?_limit=5");
    const data = await response.json();

    data.forEach(function (todo) {
      const li = document.createElement("li");
      li.textContent = todo.title;
      todoList.appendChild(li);
    });
  } catch (error) {
    console.log(error);
  }

  loading.style.display = "none";
}
JavaScript

初心者の方は、1件表示でも一覧表示でも、ローディング処理の考え方は同じだと理解すると整理しやすいです。

ローディング表示中に何を隠すかも考える

ここは少し発展的ですが、とても実践的です。ローディング表示を出すとき、前回のデータが残ったままだと「古いデータを見ているのか、新しいデータを読み込み中なのか」がわかりにくいことがあります。そのため、読み込み開始時に表示内容を空にするのもよくある工夫です。

// 前回の表示内容を空にする
todoList.innerHTML = "";
JavaScript

または、メッセージを切り替える方法もあります。

message.textContent = "データを取得中です...";
JavaScript

初心者の方は、「ローディングを出す」だけでなく、「今の状態が誤解されない画面にする」ことも考えられると、かなり実践的です。

そのまま使える完成テンプレート

ここでは、Day 62の内容をまとめた完成テンプレートを紹介します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Day 62 ローディング処理</title>
  <style>
    /* ローディング表示の見た目 */
    #loading {
      color: blue;
      font-weight: bold;
      display: none;
    }
  </style>
</head>
<body>
  <h2>ローディング処理の確認</h2>

  <button id="loadButton">ToDoを取得する</button>

  <p id="loading">読み込み中です...</p>
  <p id="message">ボタンを押すとデータを取得します。</p>
  <ul id="todoList"></ul>

  <script>
    // 必要な要素を取得する
    const loadButton = document.getElementById("loadButton");
    const loading = document.getElementById("loading");
    const message = document.getElementById("message");
    const todoList = document.getElementById("todoList");

    // APIデータを取得して画面に表示する関数
    async function loadTodos() {
      try {
        // ローディング表示を出す
        loading.style.display = "block";

        // 説明メッセージを更新する
        message.textContent = "データを取得中です...";

        // 前回の一覧を空にする
        todoList.innerHTML = "";

        // APIへリクエストを送る
        const response = await fetch("https://jsonplaceholder.typicode.com/todos?_limit=5");

        // Response を JSON として読み取る
        const data = await response.json();

        // 取得したデータを一覧表示する
        data.forEach(function (todo) {
          const li = document.createElement("li");

          // タイトルと完了状態を表示する
          li.textContent = `${todo.title} / 状態: ${todo.completed ? "完了済み" : "未完了"}`;

          todoList.appendChild(li);
        });

        // 成功メッセージを表示する
        message.textContent = "データの取得に成功しました。";
      } catch (error) {
        // エラー時のメッセージ
        message.textContent = "データの取得に失敗しました。";
        console.log("エラー:", error);
      }

      // 成功でも失敗でもローディング表示を消す
      loading.style.display = "none";
    }

    // ボタンが押されたらデータ取得を実行する
    loadButton.addEventListener("click", function () {
      loadTodos();
    });
  </script>
</body>
</html>

このテンプレートには、Day 62で学ぶべき基本がしっかり入っています。

  • 取得開始時にローディング表示を出す
  • データ取得中のメッセージを出す
  • 取得完了後にデータを表示する
  • 成功でも失敗でも最後にローディングを消す

よくあるつまずきポイント

Day 62で初心者の方がつまずきやすいポイントを整理しておきます。

  • ローディング表示を出すタイミングが遅い
  • データ取得成功時にしかローディングを消していない
  • エラー時にローディングが出たままになる
  • 前回の表示内容が残っていて画面がわかりにくい
  • 表示・非表示の切り替え対象の要素IDが間違っている

特に重要なのは、「非表示に戻す処理を忘れないこと」です。ローディング表示は出すよりも、正しく消すことのほうが実は大切です。

情報セキュリティの観点での注意

ローディング処理そのものは見た目の制御ですが、外部APIとの通信と組み合わせる以上、失敗時の扱いはとても重要です。たとえば、通信が失敗しているのに読み込み中の表示だけが出続けると、ユーザーは正しい状態を把握できません。これは使いやすさの問題であると同時に、信頼性の問題でもあります。初心者の方は、「外部通信は成功するとは限らない」「失敗時の見せ方も安全な設計の一部」と意識すると、堅実なアプリづくりにつながります。

初心者が特に注意したいポイント

Day 62では、次の点を特に意識すると理解が深まりやすいです。

  • ローディング表示は処理の前に出します。
  • データ取得完了後には必ず非表示に戻します。
  • 成功時だけでなく失敗時もローディングを消す必要があります。
  • 読み込み中の状態をユーザーに伝えることが大切です。
  • ローディング処理は非同期処理の流れ理解にも役立ちます。

特に重要なのは、「ローディングは見せることより、正しいタイミングで消すことまで含めて完成」だという点です。

Day 62のゴールを整理する

Day 62では、次のことができるようになっていれば十分です。

  • ローディング表示の役割を説明できる
  • データ取得前にローディング表示を出せる
  • データ取得完了後にローディング表示を消せる
  • エラー時にもローディング表示を消せる
  • APIデータ表示とローディング処理を組み合わせられる

ここまでできれば、Day 62としてはとても順調です。API通信をただ動かすだけでなく、使いやすい見せ方まで含めて設計できるようになっています。

まとめ

Day 62では、第5フェーズ「非同期処理とAPI」の実践として、ローディング処理を学びました。ローディング表示は、API通信のように少し時間のかかる処理において、「今読み込み中です」とユーザーへ伝えるための大切な仕組みです。処理が始まる前にローディングを表示し、データ取得が完了したらそれを非表示にする、という流れが基本になります。そして、成功時だけでなく失敗時にも必ずローディングを消す必要があります。ここを忘れると、読み込み中の表示が残り続けてしまい、使いにくい画面になります。

特に大切なのは、ローディング処理がただの見た目の演出ではなく、非同期処理の流れそのものを正しく扱う練習にもなっていることです。処理開始前、処理中、処理完了後、そして失敗時という状態の変化を意識することで、アプリの使いやすさと設計の正確さの両方が高まります。

次に進む前に、今回のテンプレートを実際に動かし、ローディング表示が「いつ出て、いつ消えるか」を自分の言葉で説明できるようにしておくのがおすすめです。そして、成功パターンだけでなく、失敗したらどう見えるべきかまで考えられるようになると、Day 62の理解がかなり深まっています。

タイトルとURLをコピーしました