「いいね」ボタンの裏側|JavaScriptは何をしている?

「いいね」は表示ではなくデータ更新です

SNSの「いいね」ボタン。
押すとハートが赤くなり、数字が1増えます。ページも移動しません。

見た目は単純ですが、
あの一瞬でサーバーのデータベースが更新されています。

つまり、ボタンは装飾ではなく「書き込み操作」です。
コメント投稿に近い処理が裏で起きています。

押した瞬間、ブラウザがしていること

ボタンを押すと、まずJavaScriptがクリックを検知します。

<button class="like" data-post="532"></button>
<span id="likeCount">10</span>

ここで重要なのは data-post です。
どの投稿に対する「いいね」かを示しています。

JavaScriptはこのIDを使って通信します。

document.querySelector(".like").addEventListener("click", likePost);

async function likePost(e){
  const id = e.target.dataset.post;

  const res = await fetch("/api/like", {
    method: "POST",
    headers: {"Content-Type":"application/json"},
    body: JSON.stringify({postId:id})
  });

  const data = await res.json();
  updateLike(data.count);
}

これが本体です。
見た目の変化より先に、サーバーへリクエストが送られています。

サーバー側で起きていること

サーバーは次の処理を行います。

  • ユーザーを識別(ログイン情報)
  • 既に「いいね」済みか確認
  • データベース更新
  • 新しいカウントを返却

つまり「いいね」は単なるボタンではなく、
ユーザーと投稿の関係を記録する処理です。

数字が増える仕組み

サーバーは結果をJSONで返します。

{ "count": 11 }

JavaScriptはそれを受け取り、画面を書き換えます。

function updateLike(count){
  document.getElementById("likeCount").textContent = count;
}

ページは移動していません。
しかしデータは確実に変更されています。

なぜ二度押しできないのか

多くのSNSでは、もう一度押すと解除されます。
これはサーバーが状態を管理しているからです。

ユーザーごとに

  • いいね済み
  • 未いいね

が保存されています。

ブラウザだけでは実現できません。
localStorageでは他端末と同期できないためです。

見た目が先に変わる理由

「いいね」を押すと、すぐハートが赤くなります。
通信は数百ミリ秒かかるはずです。

これは楽観的UI(Optimistic UI)と呼ばれます。

流れはこうです。

  • 先に見た目を変更
  • 裏で通信
  • 失敗したら元に戻す
button.classList.add("active");

ユーザーに待ち時間を感じさせないための工夫です。

実務での問題点

便利ですが注意点があります。

連打問題

通信前に何度も押されると、複数回送信されます。
そのため一時的にボタンを無効化します。

button.disabled = true;

通信失敗

電波が悪いと、見た目は「いいね」なのに
実際には登録されていないことがあります。

本来は失敗時のロールバック処理が必要です。

なぜページ遷移しないのか

もし「いいね」のたびにページが再読み込みされたら、
SNSは使いにくくなります。

  • スクロール位置が戻る
  • 投稿が見失われる
  • 操作が途切れる

そこで非同期通信(fetch / Ajax)を使い、
画面を維持したまま更新しています。

まとめ:「いいね」は最小の書き込み処理

「いいね」ボタンは小さなUIですが、
Webアプリケーションの本質が詰まっています。

  • クリックイベント
  • サーバー通信
  • データベース更新
  • DOM書き換え

一つのハートマークの裏で、
ブラウザとサーバーが対話しています。

SNSは投稿を読む場所ではありません。
ユーザーがリアルタイムに参加しているシステムなのです。