fetch をしっかり学んでみる


こんにちは、上條(mk-0A0)です。
Web 開発においてデータ通信の実装は避けて通れません。今まで私は GraphQL を使ったりプロジェクト既存の通信作法に従って実装することはあったのですが、基本の fetch については理解不足と感じたので、今回改めて調べてみます。

fetch の使い方

fetch は Web 標準の API なのでライブラリなどのインストールは必要ありません。
構文は以下の通りです。

fetch(resource, options)

resource にリクエストを送る URL を指定し、データを取得します。
以下は users.json から取得したデータを console で表示しているサンプルです。
fetch は Promise を返すため、then で繋げて非同期処理を書くことができます。then の引数には Response オブジェクトが格納されており、その中の json() を使うことで取得したデータを json にパースできます。

fetch("users.json").then((res) => {
  console.log("res", res);
  return res.json().then((json) => {
    json.map((user) => {
      console.log("user", `${user.name},${user.age}`);
    });
  });
});

fetch のメリット

デフォルトでキャッシュが効く

fetch はデフォルトでキャッシュを保持してくれるため、更新頻繁が低いページでは読み込みの時間が短縮され高速化に繋がります。キャッシュが必要な場面でキャッシュが効かないと、アクセスするたびにリソースをダウンロードするためページの描画に時間がかかってしまいます。

サービスワーカーで使用できる

サービスワーカーとは PWA の核となる技術で、web サイトをオフライン状態で利用可能にしたり、サイトのデータをキャッシュしておくことでページの高速化などが期待できるそうです。
サービスワーカーの使用 – Web API | MDN

今のところ触れる機会がないので、詳しくは必要になったときにまた調べてみようと思います。

fetch の注意点とその対策

キャッシュを使いたくない場合はオプションで設定が必要

メリットで「デフォルトでキャッシュが効く」と書きましたが、逆にキャッシュを使いたくない場合はオプションの cache で設定がいるので注意が必要です。
キャッシュにもいくつか種類があり、キャッシュを使わない場合は no-store を指定します。
そのほかの設定は Request オブジェクトの cache をご確認ください。

fetch(resource, { cache: 'no-store' })

ファイルアップロードの progress が取得できない

HTTP クライアントライブラリの axios ではファイルアップロードの progress が取得できるそうですが、fetch は取得できません。用途としては、ユーザーが画像などをアップロードした際にローディングが必要な場合などが挙げられます。
今のところこのような実装が必要な機会がないため、必要になったときに改めて調べてみようと思います。

リクエストを途中でキャンセルできない

fetch は一度送ったリクエストのキャンセルができません。先程 fetch は Promise を返すと書きましたが、Promise は成功 or 失敗なので、キャンセルの処理は AbortController を使って実装します。AbortController のインスタンスから取得できる signal を fetch のオプション signal に渡します。
こちらの記事に掲載されているコードを参考に挙動を確認してみました。console を見るとちゃんとキャンセルされていることが確認できます。

const controller = new AbortController();
const signal = controller.signal;
fetch("users.json", { signal: signal })
  .then((res) => {
    console.log("success", res);
  })
  .catch((err) => {
    console.log(`error: ${err.message}`);
  });

setTimeout(() => controller.abort(), 0);

参考資料

fetch() グローバル関数 – Web API – MDN Web Docs
まだXMLHttpRequestを使ってるの? fetchのすすめ
会話形式で綴る「fetch()のキャッシュ」

まとめ

今回は fetch についてまとめてみました。web 標準の技術を使えるようになるのは大事ですね。Next.js での fetch は独自に拡張されているそうなので、使い勝手が変わってきそうです。どのような違いがあるのか、後日記事にできたらいいなと思っています。

Gaji-Laboでは、 Next.js 経験が豊富なフロントエンドエンジニアを募集しています

弊社では Next.js の知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違う Gaji-Labo を味わいに来ませんか?

Next.js の設計・実装を得意とするフロントエンドエンジニア募集要項

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!


投稿者 Kamijo Momoka

フロントエンドエンジニア。
HTML/CSS/JavaScript/WordPressでのサイト制作からNext.js/TypeScriptなどを使ったWebアプリ開発、FigmaでのUIデザインまで広く経験しています。 デザインエンジニアと名乗るのが夢です。