非同期通信をするなら絶対にやったほうがいいこと

# TL; DR

**ユーザーを待たせるとき、「どのように待たせるか」によって印象は結構変わります。**

**非同期処理などでユーザーを待たせるときは、適切なローディングを表示してUXを改善しましょう。**

違いを体感していただけるよう、いくつかの例を元に書いてみました。

# ボタン押下の例

送信ボタンを押してから、通信に1秒かかるお問い合わせフォームを作ってみました。

2つの例を比べてみて下さい。

実際には何も通信しないダミーのFORMなので、気軽に試して下さい。

## Bad

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="zYEOXZW" data-user="laineus" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/laineus/pen/zYEOXZW">
  ダミーFORM</a> by laineus (<a href="https://codepen.io/laineus">@laineus</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

## Good

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="LYzPaXd" data-user="laineus" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/laineus/pen/LYzPaXd">
  ダミーFORM</a> by laineus (<a href="https://codepen.io/laineus">@laineus</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

## 改善されたこと1

**ユーザーの操作に対し、画面が即時応答するようになりました。**

**結果:**

体感速度が向上しました。

どちらの例も、目的が達成されるのは1秒後であるにも関わらず、
**「押して即何かが起きる」というステップを踏むだけで、サクサク動いている印象を受けます。**

ローディングが無い場合は、ボタン押下してから通信が完了するまで、
画面に何も変化がないため、フリーズしているような、もっさりした印象を受けます。

例えば、頑張ってこの1秒かかる通信を0.8秒くらいに高速化するより、体感できる差は大きいと思われます。

## 改善されたこと2

**ユーザーは通信中であるということが分かるようになりました。**

**結果:**

1秒という待ち時間に対する印象が良くなりました。


|ローディング|印象|
|---|---|
|無し|「通信中か？」<br>「まだかな？」<br>「もしかしてちゃんと送信ボタン押せなかった？」<br>「もう一回押すか」|
|有り|「ああ、通信中ね。待とう。」|

やはり同じ秒数であっても、ユーザーが感じるストレスは大きく異なると思います。

（多重送信の防止もセットで見直しましょう）

![ローディング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151137/1b6d8367-640a-452d-cd19-cac31ade7bc1.png)

# SPAにおける画面遷移の例

もう1つ、画面遷移における例も用意したので、これも試しみていただきたいです。

一覧画面と詳細画面を持つブログのようなサイトです。
一覧と詳細を行ったり来たりして、どちらが快適かどうか比べてみて下さい。

今回はどちらの例でもローディングが表示されます。
違いは、遷移元の画面と遷移先の画面のどちらでローディングを表示するかです。

詳細画面の通信にかかる時間は、どちらも同じ1秒です。

## 元画面でローディング

<p class="codepen" data-height="700" data-default-tab="result" data-slug-hash="dyVbBwK" data-user="laineus" style="height: 700px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/laineus/pen/dyVbBwK">
  画面遷移</a> by laineus (<a href="https://codepen.io/laineus">@laineus</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

## 遷移先でローディング

<p class="codepen" data-height="700" data-default-tab="result" data-slug-hash="yLzBdVL" data-user="laineus" style="height: 700px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/laineus/pen/yLzBdVL">
  画面遷移</a> by laineus (<a href="https://codepen.io/laineus">@laineus</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>

## 比較

みなさんは、どちらが快適に感じたでしょうか？

僕的には、どちらかと言うと後者のほうがサクサク動く感じがします。

どちらも遅いのは間違いないですが、感覚的に言うと、
前者: 全体的に重い
後者: サイトのUIは快適だけど通信が遅い
みたいな…？

### 何故か

ユーザーが僕だとすると、
ユーザーの**欲求は「記事の本文を見たい」**ですが、
記事押下に対して画面に**期待する動作は「ページが遷移する」**です。

ユーザーは「記事を押すと詳細ページに遷移するだろう」と期待しているわけです。

後者の例では、画面がユーザーの期待に即時応えるため、
たとえそれが要求を満たさない不完全なものであっても、
サイトのUI自体は自分の操作にサクサク応じてくれる印象を受けます。

前者の例では、ローディングのバーは即時表示されるものの、それは期待動作ではありません。
期待動作が満たされるのは1秒後です。

||→|→|→|→|
|---|:-:|:-:|:-:|:-:|
|元画面でロード|記事押下||Loading...|UI期待動作 ＆ 要求達成|
|遷移先でロード|記事押下|UI期待動作|Loading...|要求達成|

ちなみに前者の例は、Nuxtのデフォルトのローディング（？）を真似たものです。

Nuxt製のサイトって、SPAなのに操作がもっさりした印象を持っていたんですが、それってスピードの問題よりも、UIの問題が大きいんじゃないかな？と思ったり。

非SPAサイトにおけるブラウザの基本的な挙動も前者に近いですね。
Chromeならタブにローディングを表示しつつ、HTMLのレスポンスがあった段階で遷移します。

サーバーサイドやネットワークのスピードが、UIの操作感に直に悪影響を与えてしまいます。

# いいねボタン等の例

いいねボタンのようなケースでも、いいねボタン押下時にローディングを表示して、通信完了後に、いいねボタンを押下済みデザインに変更すればよいでしょうか？

いいねボタンのようなケースでは、わざわざ通信完了を待つ意味が薄いので、実際にPOSTが完了していなかろうと、即時いいねボタンを押下済みデザインに差し替えてしまうのがいいですね。

ローディングを表示しないほうがいい（＝そもそも何も待たせる必要がない）例の一つでした。

# おわりに

最後に、タイトルには目を引くべく`絶対にやったほうがいい`とは書いたものの、
全てのケースで例で紹介したような対策を入れるべきと言いたいわけではありません。

同じ時間ユーザーを待たせるとき、**どのように待たせるかで大分印象変わりますよね**、と伝えたかったのがメインですので、待機時間のUIに少しでも意識を向けてもらえればいいかなと思います。

そのうえで、やるかどうかや、どうやるかは**ケースに応じて**変えていただければと思います。

もしUI/UXデザイナーが居て、ここらへんを相談できるのであれば、恵まれた環境と思いますが、
各画面の静的なデザインデータだけで開発しなければいけないケースも珍しくありませんので、
そういったとき、エンジニアからも拾い上げたり、問題提起できれば、より良いプロダクトに近づけるんじゃないかと思います。


<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

---

↓↓ よかったらデザインやUI/UXに関して書いた他の記事もお読みください！

https://qiita.com/laineus/items/c43d302e974380993fca

https://qiita.com/laineus/items/3b43bf6f347b45cb6f83

https://qiita.com/laineus/items/00edd8a7abdb336cde3f