• aboutabout
  • servicesservices
  • worksworks
  • mediamedia
  • contactcontact
  • homeサイトトップ
  • about会社概要
  • services業務内容
  • works実績紹介
  • mediaメディア
  • contactお問い合わせ
ja/

media

メディア

  1. サイトトップ
  2. メディア
  3. Web開発の記事
  4. ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #5:静的サイトのビルド

ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #5:静的サイトのビルド

  • 2021.11.28
  • Web開発
  • Jamstack
Updated: 2021.11.28
これまで4回にわたりヘッドレスCMSと静的ページを使ったJamstack構成のウェブサイト制作のフローをまとめてきましたが、第5回目の今回はいよいよ静的サイトのビルドを行っていきます。Nuxt.jsではSSGとしてもとても優秀で、さまざまな最適化がされていたりコマンド1つでビルドできるようになっていますが、何も気にせず進めてしまうとページ数が多い場合にはビルド完了までかなり時間がかかったり、API通信が発生している場合ではサーバーエラーを起こしたりすることもあります。今回はビルド時間短縮のための対応についてまとめていきたいと思います。また、これまでの流れについてはこちらの過去記事をご参考ください。 (過去記事) ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #4:動的ページ(投稿詳細)の実装 ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #3:動的ページ(投稿一覧)の実装 ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #2:フロントエンドでのサイト制作 ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #1:ヘッドレスCMSの構築  
SSGのgenerateで時間短縮の対応
Nuxt.jsではSSGもデフォルト機能として用意されていますので、generateコマンドを実行するだけで、HTMLやJavaScriptファイルが生成されます。あとはそのビルドファイルをホストサーバーにアップロードするだけで公開できるようになります。その時に「nuxt.config.js」の設定で、「ssr」のオプションを「true」に、そして「target」のオプションを「static」に指定しておくことが重要になります。こうすることでビルドが静的サイトに最適化されるようになります。例えば、動的ルーティングの指定が不要になったり、データを静的なJSファイルとして保存してそれを読み込むような形にすることで高速化を実現しているなどがあります。   ただし、動的ルーティングのページでAPI通信を使っている場合などは、そのままgenareteを実行してしまうと、毎回のページをビルドする際にAPIで読み込む形になるのでビルド時間が大幅に増えたりAPIサーバーに対して大きな負担がかかってしまいます。そこで「nuxt.config.js」で「genarete」の「route」オプション設定を下記のように加えていきます。 【nuxt.config.js】※一部抜粋
import axios from 'axios'
export default {
  ssr: 'true',
  target: 'static',
  ......
  generate: {
    subFolders: true,
    routes(callback) {
      axios.get('https://example.com/api/blog/')
        .then((response) => {
          const routeList = response.data.map((post, index) => {
            return {
              route: `/blog/${post.ID}`,
              payload: {
                prev: array[index + 1],
                current: post,
                next: array[index - 1]
              }
            }
          })
          callback(null, routeList)
        })
        .catch(callback)
    },
    interval: 1000
  },
  ......
}
  本来ですと動的ルーティング(参考記事「Nuxt.jsでビルド時にサイトマップの導入と設定方法」)の設定のために使われる処理になりますが、SSGでtargetがstaticになっている場合、ここでAPI経由で読み込んだデータをペイロードデータとして個別ページで使うことができます。そのため、API通信が大幅に減ることになり、ビルド時間の短縮やAPIサーバーへの負担を軽減することができます。また「interval」オプションでは連続するAPI通信の間隔を設定でき、サーバーへのアクセスを分散させることができますので、合わせて設定しておくといいですね。ただし上げ過ぎてしまうとその分ビルド時間も増えてしまうので注意します。   動的ルーティングのページでは下記のように先程読み込んだデータを「asyncData()」メソッドのpayload引数に格納されるようになります。これでページ内にデータを表示させたり、処理で値として使うことができます。その際には、ペイロードデータの有無で通常の開発環境ではAPIを叩いてデータを取得できるようにしておきます。 【pages/blog/_id.vue】
<template>
  <div>
    <post-detail :post-data="posts" />
  </div>
</template>

<script>
  import { $axios } from 'axios';
  import PostDetail from '~/components/PostDetail.vue';
  export default {
    components: {
      PostDetail
    },
    async asyncData({ app, payload }) {
      if(payload) {
        return {
          posts: {
            nextPost: payload.next,
            currentPost: payload.current,
            prevPost: payload.prev
          }
        }
      } else {
        const response = await app.$axios
          .get(`https://example.com/api/blog/${Number(params.id)}`)
          .catch((reason) => {
            return {
              posts: {
                nextPost: response.data[0],
                currentPost: response.data[1],
                prevPost: response.data[2]
              }
            }
          })
          if(response.status !== 200) {
            error({
              statusCode: response.status,
              message: response.data.message
            })
            return
          }
      }
    },
    ......
    head() {
      return {
        title: this.posts.currentPost.title,
        ......
      }
    }
  }
</script>
  これでビルドを行う準備ができました。コマンドについてはnpm scriptがデフォルトで用意されているので、下記のようにpackage.jsonを確認し、環境に合わせたコマンドを実行します。(参考記事「Nuxt.jsでcross-envを使って本番環境と開発環境のURLを切り分けてみる」) 【package.json】※一部抜粋
{
  "scripts": {
    .......
    "generate": "nuxt generate",
    "generate-dev": "cross-env NODE_ENV=development nuxt generate",
    "generate-stg": "cross-env NODE_ENV=staging nuxt generate",
    "generate-prod": "cross-env NODE_ENV=production nuxt generate",
  },
  .......
}
  では実際に下記のようにコマンドを実行すると静的サイトでのビルドが始まり、どんどんページが生成されていく様子がわかります。
$ yarn generate-prod
  SSGでgenerateコマンドを使ってビルドした場合には、下記のような形で指定されているビルド用のディレクトリ配下にファイルが生成されます。先述の通り、データは静的なJavaScriptファイルとして、 _nuxtディレクトリ配下にあるstaticディレクトリにデータが格納されているのが確認できました。
/DIST_DIR
  ┣ _nuxt
    ┣ static
    ┣ CHUNK_FILE
    ┣ ........
    ┣ HASH_NUM
      ┣ PAGE_DIR
        ┣ payload.js
        ┗ state.js
      ┣ ........
      ┣ payload.js
      ┗ state.js
    ┣ PAGE_DIR
    ┣ ........
  ┣ assets
    ┣ css
    ┣ js
    ┣ images
    ┣ ........
  ┣ index.html
  ┣ 404.html
  ┣ favicon.ico
  ┣ .nojekyll
  ┣ sitemap.xml
  ┣ ........
  あとは、これらのファイル群を一式ホスト用のサーバーにアップロードして実際に表示されるかどうかをチェックしてみます。  
API側である程度データの下処理をしておく
API通信で動的ルーティングを含むサイトのビルドでは、都度API通信が行われることを避ける以外にも、API側である程度データを整理しておくことも重要になります。とりあえずデータだけ一括で取得し、それをJavaScriptで加工するとなった場合、使わないデータも数多く含まれるため、できるだけサーバー側のAPIで必要最低限となるデータをクライアント側に返すようにしておきます。そうしないとビルド後のデータが膨大に膨れ上がってしまい、サーバーの容量も圧迫する原因にもなってしまいます。参考までに約800ページ相当のサイトの場合、下記のような差が出るようになりました。うまく設計しないと、ビルド時間がかなり長くなったり、書き出し後のファイル容量が膨大になってしまうので注意しておきたいですね。
【Before】
intervalの設定値:3000
generate所要時間:59分
ビルドファイルデータサイズ:3.4GB

↓

【After】
intervalの設定値:1000
generate所要時間:18分
ビルドファイルデータサイズ:369.5MB
   
その他ソースコード管理に合わせた対応
Nuxt.jsでビルドされたファイルにはキャッシュ対応のためファイル名がハッシュ値になっているものが存在します。基本的にビルド後のファイルをソースコード管理することは少ないと思いますが、差分を取りたいという場合にはビルド後のファイル名を固定で設定することができます。下記のようにnuxt.config.jsで「build」オプションの「filenames」でそれぞれ静的ファイルの命名ルールを変更することができます。 【nuxt.config.js】※一部抜粋
export default {
  .....
  build: {
    filenames: {
      app: () => '[id].js',
      chunk: () => '[id].js',
      css: () => '[name].js',
      img: () => '[path][name].[ext]',
      font: () => '[path][name].[ext]',
      video: () => '[path][name].[ext]'
    },
    ......
  },
  ......
}
  また、先述の通りSSGではpayload.jsとstore.jsが生成されますがこのディレクトリ名も、毎回ハッシュ値が当てられるようになっているため、配下のファイルは内容が変わっていない場合でも全て差分として扱われることになります。そこで、このディレクトリ名も固定値にすることで、純粋な差分を取得できるようにします。こちらもnuxt.config.jsで「generate」オプションの「staticAssets」で下記のように固有の値を指定します。 【nuxt.config.js】※一部抜粋
export default {
  .....
  generate: {
    staticAssets: {
      version: 'payloads'
    },
    ......
  },
  ......
}
  指定後にビルドを行うと、実際にペイロードファイルのディレクトリ名が変わっているのが確認できます。
/DIST_DIR
  ┣ _nuxt
    ┣ static
    ┣ CHUNK_FILE
    ┣ ........
    ┣ payloads
      ┣ PAGE_DIR
        ┣ payload.js
        ┗ state.js
      ┣ ........
    ┣ payload.js
    ┗ state.js
 
  これでヘッドレスCMSとSSGを使ったJamstackなサイトを公開することができました。サイトの仕様によってはそれ以外にもいろんな処理が必要になりますが、ベーシックなブログサイトであればそこまでハードルは高く無いのではないでしょうか。ビルド作業の手間はかかるものの、これまでのCMSサイトは基本的にサーバーサイドで動的にページが生成されているので、高速化などのパフォーマンス面から見てもこの方法で構築するのも選択肢の一つとしてはアリなのではないでしょうか。   (過去記事) ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #4:動的ページ(投稿詳細)の実装 ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #3:動的ページ(投稿一覧)の実装 ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #2:フロントエンドでのサイト制作 ・ヘッドレスCMSのWordPressとNuxt.jsのSSGでJamstackなサイトを作成してみる #1:ヘッドレスCMSの構築
XでシェアLINEで送るはてブに追加

この記事を書いた人オガワ シンヤ

合同会社デザインサプライ代表兼CEO / ディレクター・ウェブデザイナー・フロントエンドエンジニアをやっています。「ウェブとデザインでヒト・モノ・サービスを繋げ新しい価値を生み出す」をコンセプトに日々奮闘中!制作中はダイエットコーラとチョコレートが欠かせないアラフォーWebクリエイター。

Sponsored Link

  • Showcase
  • Startify UI
  • Functional Gradation Generator
  • Coloooors

keyword search

categories

  • サーバー構築(31)
  • ウェブアプリケーション(12)
  • 開発環境構築(11)
  • Jamstack(6)
  • セキュリティ(4)
  • 制作・開発進行管理(2)
  • モバイルアプリ開発(2)
  • システム・コーディング設計(2)
  • PWA(1)
  • ウェブサイト保守(1)

recent articles

  • Shopifyでのテーマ開発に便利なローカル環境を構築する#2:Shopify CLI
    read more

    Shopifyでのテーマ開発に便利なローカル環境を構築する#2:Shopify CLI

    2023.05.07/開発環境構築
  • Shopifyでのテーマ開発に便利なローカル環境を構築する#1:Shopify Theme Kit
    read more

    Shopifyでのテーマ開発に便利なローカル環境を構築する#1:Shopify Theme Kit

    2023.04.29/開発環境構築
  • Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#7:動的ルーティングとデータベース更新処理
    read more

    Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#7:動的ルーティングとデータベース更新処理

    2023.03.23/ウェブアプリケーション
  • Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#6:ミドルウェアの設定と認証ページ作成
    read more

    Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#6:ミドルウェアの設定と認証ページ作成

    2023.02.10/ウェブアプリケーション
  • Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#5:ログイン認証機能の実装
    read more

    Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#5:ログイン認証機能の実装

    2023.01.20/ウェブアプリケーション
  • Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#4:ログイン認証ユーザー作成
    read more

    Docker+Laravelでバックエンドの開発環境構築とウェブアプリケーション制作#4:ログイン認証ユーザー作成

    2023.01.13/ウェブアプリケーション
  • 次の記事
  • 一覧に戻る
  • 前の記事

まだ依頼内容が決まっていなくても、ご相談ください。

課題の整理や小さな検証、UI/UX・フロントエンドの部分的な支援から始められます。

お問い合わせやご相談はこちらから

Webサイト・プロダクトの企画設計/UI・UXデザイン/フロントエンド開発合同会社デザインサプライ(DesignSupply. LLC)

Office:大阪府大阪市天王寺区清水谷町3-22
Email:info@designsupply-web.com
home
  • サイトトップ
about
  • 3つのポリシー
  • 経営理念
  • 代表・クリエイター紹介
  • 会社概要
services
  • ビジネス・プロダクト支援
  • UI/UX・フロントエンド開発支援
  • プロジェクトの進め方・支援体制
  • エデュケーション事業
works
  • 開発プロジェクト支援
  • クリエイティブ制作
  • 自社プロダクト
media
  • デザイン
  • プログラミング
  • マーケティング
  • Web開発
  • 写真・動画制作
contact
  • お問い合わせ
news
  • インフォメーション
privacy
  • プライバシーポリシー

WE THINK WITH YOU, DESIGN FOR PEOPLE, AND BUILD WHAT WORKS.

WE THINK WITH YOU, DESIGN FOR PEOPLE, AND BUILD WHAT WORKS.

© 2013 - 2026 DesignSupply.LLC
サイトトップへ
contact