初心者による、Next.js × microCMSでJamstack構成のウェブサイト構築&リリース
Next.js × microCMSでJamstack構成のウェブサイト構築したので、実装してみての感想や成果物のアーキテクチャ紹介、つまづいたこと・失敗したことなどをご共有したいと思い投稿しました。
なぜ作ろうと思ったか
もともとフリーランスにてWordPressサイトの開発をメインに活動していたのですが、以前からJamstackが気になっていたこと、実際触ってみてその良さを感じたことからJamstack専門のウェブサイト制作サービスを始めることにしました。(当初は名刺代わりの簡単なポートフォリオを作るだけの予定でした)
Jamstack開発の経験がないのにいきなりやるのか!?という感じですが、自分は仕事としてやらないと成長できない人間なので、思い切った判断をしました。
成果物の概要
作ったサイトはこちらです。
(2023/9月現在運用廃止。)
僕にとって初のNext.jsプロジェクトで、デザイン・実装まで全工程を行いました。ワイヤーフレーム・画像素材の作成は全工程Figmaを使いました。
まだまだ手を入れきれていない部分もあるため、とりあえずリリースした上で改善&リファクタしていければと思っています。
アーキテクチャ
抜け漏れがあるかもですが、アーキテクチャを簡単に図式化してみました。
フロントエンドはNext.js(SSG)、ヘッドレスCMSはmicroCMSを採用していて、Jamstackなウェブサイトとしてはごくごくオーソドックスな構成なんじゃないかと思います。
実装した機能
- OGP画像・キャプション
- パンくずリスト
- ページネーション
- サイトマップ
- GoogleAnalytics
- お問い合わせフォーム
- ブログ機能
- ブログ一覧ページ
- カテゴリ一覧ページ
- 記事詳細ページ
- 下書きプレビュー
- SNSシェアボタン
リリースを終えての所感
所感としては、「キャッチアップしながらの制作は大変だったが、楽しかった」です。当初はそもそもJavaScriptやReact自体の理解も浅い状態だったので、もともと興味のあったフロントエンド系の技術を短期間でガッツリ勉強できたのも良かったです。
本来はもっとシンプルな、名刺代わり程度のサイトを2週間ぐらいでリリースする予定でしたが、ところどころ機能を追加したりデザインを作り直したりしているうちに2か月近くが経過してしましました。
プロジェクト進行としては失敗ですが、楽しかったです。
実装で悩んだこと
実装は悩みっぱなしだったので挙げるとキリがありませんが、一部ご紹介したいと思います。
Jamstack構成でのお問い合わせフォーム実装に悩む
Jamstack構成でお問い合わせフォームを実装するには、基本的には外部のメールAPIを利用することになるわけですが、どれを使うのが良いのかわからないということと、フォームの実装自体どうすれば良いのか分からずで少し手が止まりました。
とりあえず、以下の要件は満たしたいと考えていました。
- Googleformだと若干怪しまれそうなので避けたい(ただでさえ怪しそうなデザインなので)
- バリデーションはかけたい(デザインは自分で作りたい)
- とりあえず無料で使い始められるかつ、有料プランに移行した時の料金が許容できるもの
- 将来的にクライアントにも勧められるもの
APIを提供しているメールサービスは色々とあり、かなり迷って色々と試しました。
で、うまくいったりいかなかったりで結局落ち着いたのが
- メールAPIはgetform.io(https://getform.io/pricing)
- フォーム実装はreact hook form(https://react-hook-form.com/jp/get-started)
の組み合わせでした。
getform.ioはイギリス産(多分)のメールAPIなのですが、UIがモダンで使いやすく、無料から使い始められるため気に入りました。公式DocsにNext.jsへの導入方法があるのも◎
react hook formもご存じの方は多いと思いますが、軽量ですし、何より公式Docsが超充実していて初心者の私でも困ることがなかったです。
開発の失敗談
失敗談も挙げるとキリがないので、一部をご紹介。
UIキット(MUIv5)の導入でスタイルが重くなった
当初はUIキットというものになんとなく憧れがあり、とりあえず使ってみたいという漠然とした気持ちからMUIv5(以下MUI)を導入することにしました。ところがこれが原因でスタイルがかなり重くなってしまったのです。
スタイルが重くなってしまった原因は、以下の3つにあると考えています。
- 僕がUIキットのコンセプト・使いどころを理解していなかった(MUIは悪くない)
- 僕がCSS-in-JSに慣れておらず、無駄な記述があった
- MUIはスタイリングのコアライブラリにemotionを用いていおり、これはZero-runtimeではないためそもそも多少は遅くなる
具体的どうしていたかというと、FlexBoxやGridなどの単純で使いまわしするようなレイアウトを作るためだけにMUIコンポーネントを呼び出し、無計画にあちこちでsxPropを記述するという非効率的なスタイリングを行っていました。(あと、アコーディオンメニューのコンポーネントがやたら重かった)
すると、開発半ばでたいしたコンテンツがないにも関わらず、LightHouseのパフォーマンススコアはPCで69(yellow)とかなり低くなってしまいました。これではSSGの意味がない。。
また、style&layout項目の読み込み時間が1,330msもかかっていることから、スタイルの実装に問題があることは明らかでした。(画像はこの時のLightHouseスクリーンショット)
体感速度も明らかに遅くなっていましたし、対処法もわからなかったので今回は割り切って、慣れ親しんだCSS-modulesでのスタイル実装に方向転換しました。(現在のパフォーマンススコアはPCで93~96あたりに落ち着いています)
そもそもシンプルなウェブサイトなので、高機能なUIコンポーネントは必要ないという気づきもありました。手戻りが増えたのは痛かったですが、MUIのキャッチアップ自体はかなり勉強になりました。
gtag(GoogleAnalytics)が読み込めなかった
Next.jsにgtagを埋め込む方法を調べならが実装を進めましたが、devtoolsで吐き出されたソースコードを確認してもgtagのスクリプトが見つからず、どうしたものかと実装したコードを見直したりと半日ぐらい頭を抱えていたのですが、原因は思わぬところに転がっていました。
gtagのスクリプトがブロックされています。
どうしてこんな事になっているのかというと、実装ミスでもなんでもなく、私がBraveブラウザを使って開発・検証していたからです。
BraveはGAのコードもブロックするんすねえ~~~~。chromiumなのに、すごいな。Braveさん一生ついていきます。
はい、Jamstack全く関係ない失敗談で恐縮ですが、共有しておきたいと思いました。開発時のリファレンスブラウザはやはりChromeが無難ですし、そうします。。
今後改善したいところ
諸々のリファクタリング
以下のリファクタは早急にやりたい。
- TSファイルと素のJSファイルが混在している状態なので、これをすべてTSでリファクタしたい(TSまだよくわからん)
- ディレクトリ構成が我流なので、AtomicDesignなど何かしらのシステムを導入したい
- getStaticProps等の非同期処理を各pagesファイルごとにイチから記述しているので、共通しているロジック部分やURLは別ファイルに切り出したい。
- 画像の最適化・読み込みのタイミングはまだ改善の余地がありそう。Next/Imageに色々と面白そうな機能があったので、Docs見ながらいじっていきたい。
次点でやるのは、時間がなくて実装を暫時見送った機能たちです。
- ブログにタグ機能を実装(現在カテゴリのみ)
- ページネーションを番号付きにする
- カテゴリ一覧にもページネーションを実装する
TDD(テスト駆動開発)したい
最初からTDDすれば良かったと後悔していますが、そんな余裕もなかった気がします。
いずれにせよ今後の開発は基本的にテストコードを書きながら進めていきたいと思っています。一人で仕事してるからこそ、コードの品質担保・手戻り防止のためにもテストは重要であると考えています。
CSS-in-JS探訪
今回は紆余曲折あってCSS-modules(scss)でスタイル当てたのですが、やっぱスタイルシートの管理が煩雑でした。Next.jsに限った話ではないですが、CSSベストプラクティスを自前で組むのは結構タフな作業です(嫌いではないけれど、、)
ともかく今後は一度、CSS-in-JSをメインにしたいです。
CSS-in-JSはどうやら戦国時代のようで、色々あって迷いますが、楽しみつつ自分にあうものを見つけていきたいと思います。オススメあったら教えて頂けると嬉しいです。
さいごに今後のいきごみ
JamstackアーキテクチャやNext.jsの理解をもっと深めたいですし、他の技術を使って作ってみたい構成もたくさんあるので、引き続きインプットしながら手を動かしまくりたいと思います。
また、僕は一人でやっているので、待っているだけでは実案件の機会はなかなかやってこないという課題もあります。情報発信にも力を入れつつ、まずは実案件を頂けるように努力していきたいです。
お読み頂きありがとうございました。オススメのCSS-in-JSや思ったことなどありましたら、コメント頂けると喜びます。
Discussion