パン工房をまるまるリニューアルしました!【Nuxt.js】【Nuxt Content】

こんにちは。お久しぶりです。

なんと2ヶ月ぶりのブログ投稿になってしまいました。ブログを更新できなかった理由ですが、以下の2つが挙げられます。

  1. 出社勤務になったことにより自分の時間が確保しにくくなった
  2. サイト全体をNuxt.jsでリニューアルしていた!

1つ目のほうは単純にブログにかけられる時間が減ったということですが、こちらよりも2つ目のほうが大きな理由です。

パン工房フルリニューアル

この2ヶ月間、密かにパン工房のフルリニューアルを進めていました。この記事が読めているということは、既にリニューアル後のサイトに切り替わっているということです。

リニューアル前のサイトは、Node.jsとExpressを利用して自作しており、いわゆるメインサイト(プロフィールや作品集)、写真公開サイト、ブログでそれぞれアプリケーションが分かれている構成でした。また、ブログの記事に関してはヘッドレスCMSであるContentfulを利用していました。

今回これをNuxt.jsを使ったサイトにフルリニューアルしています。メインサイトとブログを1つのアプリケーションに統合し、SPAサイトとして構築することでスムーズなページ遷移を実現しています。ページ遷移はかなり素早くなっており、UX的にもSEO的にも良いものになっているのではないかなと思います。

リニューアル前のサイトの不満点

今年の4月頃から本更新を始めた当サイトですが、なぜたった数ヶ月でフルリニューアルすることを決めたのか、それにはいくつか理由がありますが、リニューアル前のサイトへの不満が溜まっていたことも大きな理由です。簡単に書いていきます。

サブドメインでアプリケーションを分けていた

パン工房はhttps://pankobo.meというドメインで運営していますが、写真公開サイトはhttps://photos.pankobo.me、ブログはhttps://blog.pankobo.meという具合に、サブドメインを使ってドメインを分けていました。これはある種のサブドメインへの憧れみたいなものから来ているものです。無料のレンタルサーバーやWebホスティングサービスでは独自ドメインを利用することができず、そのサービスのサブドメインを利用することになることが多いと思います。私が今までに作ってきたサイトも例外ではなく、自分のドメインでサブドメインを持つことが夢になっているところがありました。そこでサイト内でアプリケーションを分け、それぞれ別のサブドメインで運営する、ということをやっていたわけです。

しかしこれには問題がありました。サブドメインでアプリケーションを分けてはいたものの、ページのスタイル、ヘッダー・フッターなどのパーツはサイト内で共通です。そのため、複数のアプリケーションに同じ記述をし、どれかを修正したら全て修正する、という作業が必要になってしまっていました。これはなかなかに馬鹿らしい作業です。

アプリケーション間の相互連携が難しい

上の話にも関係してきますが、アプリケーションを分けていたことによって難しくなっていることがありました。それはずばりアプリケーション間の相互連携なのですが、例えばサイトのトップページには人気のブログ記事や注目の写真を表示していました。ただこれを実現するために結構面倒くさいことをしていました。ブログ記事の取得などはブログのアプリケーションが行うべきものだと思いますが、トップページから人気記事を取得するとなると、メインサイト側にもブログ記事を取得する機構を作るか、ブログのアプリケーション側に人気記事を返すAPIのようなものを作ることが必要になります。結局APIを作ることで解決はしましたが、同じサイト内なのに馬鹿らしいなあと思ったものです。

Contentfulでの記事管理が面倒になってきた

リニューアル前のサイトではブログ記事の管理にContentfulを利用していました。ContentfulはヘッドレスCMSと呼ばれるもので、Contentful側に記事のデータを保存しておきAPIで逐一取得することで、データベースや静的ファイル管理などの面倒なことをせずにブログサイトを簡単に構築できるというものになっています。記事が持つ情報(タイトル、カテゴリ、タグなど)の定義を自分で決めることができる柔軟さや、WYSIWYGエディタで編集できる手軽さを気に入って導入することにしました。

しかし、記事の数が増えてくると管理が煩雑になってきたり、書き途中の記事をローカルのサイト上で確認するためにプレビュー用のAPIに切り替える必要があったり、少しずつ管理が面倒になってきていました。また、カテゴリやタグの入力・検索も少々面倒だったり、TwitterのツイートやYouTubeの動画といった埋め込みに弱いという点にも不満があります。

アプリケーション側でも問題がありました。本来はページが読み込まれるたびに必要な記事のデータのみAPIアクセスで取得するという方法が普通かと思いますが、なるべくページの表示を早くしようと、ブログアプリケーション再起動時に全ての記事を取得してメモリに保持し、ページ遷移したらその中から該当の記事データを探してきて表示する、というプログラムにしていました。記事数が少ないとこちらのやり方のほうが良いのかもしれませんが、記事が増えてくると1つの変数に大量のデータが格納されることになり、サーバーにも負荷がかかって良くないということに気づきました。

そしてContentfulのAPIですが、どんな構造のサイトにも対応できるよう非常に薄い作りになっているため、記事のフィールドを取り出すためにいちいち

const url = post.fields.eyecatch.fields.url

のような記述をしなければならず、コードがどんどん見通しが悪くなっていくのも感じていました。Contentfulは非常に良いサービスだと思いますが、自分の好きなように管理したい用途と、どんなサイトにも合う作りというものがマッチしなかったかなと思っています。

新サイトで導入した技術

こういった不満を解消しようとパン工房のフルリニューアルを決めたわけですが、使う技術は悩みました。またSEO的にもサブドメインより単一ドメイン内でのディレクトリ分けのほうが良いという話を読んでいましたが、サブドメインをやめることにも抵抗がありました。

一方で趣味プログラマーである自分は、完成よりも作っている過程を楽しんでいるということもあります。またそのときちょうどVue.jsを触り始めており、SPAのページ遷移の早さに感動を覚えていました。せっかく自分の自由にできる個人サイトなので、思い切って今まで触ったことのない技術を取り入れようと、Nuxt.jsの導入を決めたわけです。

Nuxt.js

Nuxt.jsは、Vue.jsやwebpackなどを組み合わせてNode.jsサーバー上で動かすことで、リッチなWebアプリケーションを作成することができるフレームワークです。SPAサイトを簡単に作ることができるVue.jsですが、サーバーサイドレンダリングやルーティングに関しては強くありません。SPAの良さを保ちつつSEO的にも優れたサイトを作る選択肢としてNuxt.jsが挙げられます。

自分の好きなようにカスタマイズできることを考えてアプリケーションを自作していましたが、Nuxt.jsでも同じように高い自由度で開発できると考えて導入しました。むしろ自分が面倒でやりたくないような処理がフレームワークとして既に用意されているので、非常に便利です。

リニューアル前のサイトではテンプレートエンジンとしてEJSを使っていましたが、それをそのままVue.jsのテンプレートに置き換えたような感じです。Vue.jsは単一ファイルコンポーネントで管理できるため、ロジックと見た目がディレクトリから別の箇所にあったリニューアル前のアプリケーションより、かなり管理しやすくなったと感じています。

Nuxt Content

ブログの記事管理にはNuxt Contentを利用しています。Nuxt Contentは2020年5月にリリースされたばかりの新しいNuxt.js用モジュールです。プロジェクト内にcontentディレクトリを用意し、その中にMarkdownやJSONなどの形式で記事ファイルを作っていくと、それを自動的にプログラム内で読み込める形にしてくれるGitベースのヘッドレスCMSです。

Nuxt.js専用に作られているため、Nuxt.jsアプリケーションとの相性が非常に良いです。もちろんサーバーサイドレンダリングにもSPAでの遷移にも対応しており、カテゴリ、タグなどのフィールドを持つこともできます。

記事をローカル環境で書くことができるため、その場でページでの表示を確認することができます。記事ファイルを保存するたびにブラウザで自動的に再読み込みされるため、記事を書く効率が格段に上がります。

登場したばかりのモジュールですが継続的にアップデートが繰り返されており、将来の機能アップにも大いに期待しています。

その他豊富なモジュール

Nuxt.jsは機能を追加できるモジュールが非常に充実しており、今まで自前で実装していたようなこともモジュールで実現しています。今回導入したものでは、Nuxt Contentと連携してRSSフィードを作成してくれるもの、sitemap.xmlを自動で作成してくれるもの(これもNuxt Contentとの連携も可能)、Google Analyticsをいい感じに読み込んでくれるものなどです。

もちろんモジュールだけでは実現できない機能もありますが、そういったものはプラグインという形で自前で実装しNuxt.jsに組み込むことができます。これも便利です。

Nuxt.jsに切り替えたことによるデメリット

もちろんNuxt.jsに切り替えたことによる変化は良かったことばかりではありません。

初回読み込みが遅い

これはSPA全てに言えることかと思いますが、SPAはページ遷移が素早くなる代わりに初回アクセスの読み込みがもたつきます。あらゆるものを先読みして一度に表示しているからです。特にブログは情報量が多いため結構もたつきますが、その他のページでも同じアプリケーションで動かしているためブログに引きずられて読み込みが遅くなります。

リニューアル前のサイトは、アプリケーションの再起動時にContentfulから全ての記事データを取得し、ページの読み込みではメモリ上のデータを読むだけであったため、再起動後のアクセス以外は軽快に読み込むことができました。それと比べるとやはりもたつきを感じますが、初回読み込み以降のページ遷移は爆速になったためこれは許容範囲内としましょう。

ちなみにNuxt.jsは最近静的サイト生成に対応しました。Nuxt.jsを静的サイトジェネレーターとして利用することで、読み込まれる可能性のあるページを全て静的ページとしてファイル生成し、静的サイトとしてサーバー上に配置する方法です。今回可能であれば静的サイト化したいと考えていましたが、ビルドの際どうしてもJavaScriptのメモリ確保エラーになってしまい上手くいきませんでした。このあたりはNuxt Contentを利用しているからなのでしょうか(Nuxt Content公式は静的サイト生成にも対応しているとしています)。

ビルドに時間がかかる

今回Nuxt.jsはサーバーモードで使用していますが、ビルド時に全てのアセット(画像ファイルなど)を読み込み、最小化やハッシュ化をしています。Nuxt Contentを利用し始めたことで全ての記事データとそれに含まれる画像ファイルを処理する必要があり、これに非常に時間がかかります。リニューアル前は一瞬で再起動が完了していたため、ここもリニューアルによるマイナスポイントです。とはいえ、コマンドを連結して連続実行すれば待っていれば勝手にビルド後に起動してくれるので、そこまで大きな問題ではありません。

素のページが作れない

今回全てのページがVue.jsのコンポーネント上で動くようになったことで、ちょっとしたツールを作る際もVue.js・Nuxt.jsのルールに則って作る必要が出てきました。リニューアル前はページによってはjQueryでDOM操作をしたり、Chart.jsなどをscript要素で読み込んだりして自由に作ることができましたが、Nuxt.js上ではページ遷移やデータバインディングと干渉して上手く動かない場合があります。Chart.jsはVue.jsのモジュールとしても提供されているため今回移行できた作品もありますが、パッと簡単に作るにはハードルが上がったかもしれません。

URLを変えたためリダイレクト処理が必要

これはNuxt.jsを導入したからというよりフルリニューアルをしたからということですが、サブドメインをやめたことでURLが大きく変わりました。また一部ページはまだ移行できていないので、そのあたりをWebサーバー側で制御しなくてはなりません。

URLが変更されたページのリダイレクト処理をしないと、検索エンジンからの流入が404エラーになってしまうほか、新しいほうのページが検索エンジンに重複したコンテンツと判定されてしまう可能性があり、サイト評価上良くありません。パン工房ではWebサーバーにNginxを利用しており、そこでリダイレクト設定を入れる必要があります。


今回は久しぶりのブログ投稿ということで、サイトをフルリニューアルしていたこと、リニューアル前後の比較について書きました。

ちなみにまだ未完成でリニューアル前と比べて機能が落ちているところもあります。上でも言及したトップページですが、人気記事やおすすめ写真の表示はまだ実装できていません。そもそも写真公開ページは移行すらできていません。サイドバーの人気記事や本文下の関連記事なんかも移行できていません。作品集も公開が追いついていない作品があります。

とはいえNuxt.jsアプリケーションに移行したことで開発の効率もかなり上がりました。作品についてもブログについても今後はしっかりと更新していきたいと考えていますので、今後ともパン工房をよろしくお願いします。

それではまた。

関連記事