Engineering

Apr 16, 2021

ブログをリニューアルするついでにGatsby3に上げたので振り返り

ここしばらく就活をしていてバタバタしていたのですが、無事オファーを頂き仕事も開始して落ち着いて来たので、 そろそろ2年ほど前に改築したブログをまたリニューアルしたいということでブログをリニューアルしました。

なので、そのあたりをまとめて書いておこうかと思います。

リニューアルの経緯

デザインの変更がメインでスタック的にはほとんどNetlify+Gatsbyで変わりはないのですが、しばらく放置していたライブリ郡が古くなり、アップデートして欲しそうな目でこっちを見ていたのでアップデートをしようということになりました。

ちょうど GatsbyConf にリアルタイムで参加できて、Gatsby3.0 のリリースを見ていたのもあってちょうど良いかなということで、Gatsby3.0 へのアップデート + リデザインを行っていきました。

デザインについては、

  • 宣伝したい物があるのでバナーみたいな物をつけたい
  • ポートフォリオ的な位置付けでもあるので、もうちょっと印象に残るデザインが良い
  • 自分でも記事を検索することがあるので検索つけたい
  • モバイルのPageSpeedInsightの評価があまりよくないので改善したい

などなどの個人的な不満があったのでこれらを元に新しいデザインを決めていきました。

ちなみに以前はこういった形でした。

前のバージョンのブログ

自分のブログはこれで大体4代目くらいになります。初代はWordpressで作っていたのですが、ページ読み込みの重さや改めてPHPを書く辛さなどなど から2年ほど前に一年発起し、Wordpress => Gatsbyのリプレイスを行いました。 その後にカナダでの就活を見越してリデザインしたのが上の画像の頃でこれが3代目です。

WordpressブログをGatsby+Netlifyでリプレースした話。

そして、今回が4代目になるといった形です。色々と話を煤前に全体の構成も書いておくとイメージつきやすいかと思うのでそちらか書いてきます。

全体の構成

インフラ構成

Netlifyに移行した時からこちらのような構成だったので構成自体には特に変わりはありません。

ざっくりとした図ではあるのですが、Gatsbyで作成したサイトをNetlifyでホストしているというよくある構成になっています。

Gatsbyはビルド時に gatsby-imagegatsby-image-plugin などを使っていると画像の加工処理が入ってしまって重いので画像は、 実際に公開用の環境にデプロイを行うときだけビルドするようにしており、ローカルで yarn start などで開発を行うときは直接URLで画像をとるようにして、 Gatsbyの画像処理系のコンポーネントは介さないようにしています。

サイトとしてそれぞれの記事(全部で100本くらい)にサムネイルが設定されておりそれらを処理するので、それらの画像を処理してから開発用のサーバを立てるというのが 1, 2 分程度かかるのでローカルでは画像の処理を行わないようにして、開発体験があまり毀損されないようにしています。 2代目へのリニューアルをした時に決定したことなので、Gatsby3 でこのあたりは改善されているのかもしれません。 今回はリニューアルが主眼な作業だったのでそちらはひとまず置いておいて上記に書いたような環境で開発を進めています。

あとは、2代目のリニューアル当初はNetlifyの前にCloudflareを噛ませていたりしたのですが、当時はCloudflareの所で通信に失敗してサイトに不通になるみたいなのが、 少なくない頻度であったのと設定周り色々と面倒なのでNetlifyに直接通信するようにして静的ファイルについてのみCloudflareを噛ませるようにしました。

ちなみに、ブログ中でも記事中の画像など完璧にGatsbyで処理しきれない物があるのでそれらは、直接Cloudflareの画像にアクセスするように設定しています。

そのほか、図にはないですが記事の人気順をとるためにGoogle AnalyticsからPVを取得したり、今回追加されたAlgoriaなども使用しています。

やったこと

下記がリニューアルに当たってやったことです。

技術的な変更点

  • Gatsby3へのアップデート
  • TypeScript化
  • Algoriaの導入

UI的な変更点

  • 全体的なレイアウトやコンセプトなど
  • 検索モーダルの追加
  • モバイルトップの表示改善
  • コンソールを使った記事フィルタ
  • 記事中の目次追加

以降ではこれらについて一つずつまとめを書いていきます。

技術的な変更点

Gatsby3へのアップデート

上にも少し書きましたが、元々Gatsby2.xで作られていたのでGatsby本体をアップデートしました。 元々 2.24.60 だった物を 3.1.2 に上げてそのほかバージョンが古くなっていたライブラリも一緒にアップデートしました。

最新のバージョン出ないライブラリがほとんどだったので、 `ncu` を使って雑にアップデートをして動作確認してOKという形でした。

raineorshine/npm-check-updates

% ncu

   ╭──────────────────────────────────────────────╮
   │                                              │
   │      Update available 11.1.1 → 11.3.0        │
   │   Run npm i -g npm-check-updates to update   │
   │                                              │
   ╰──────────────────────────────────────────────╯

Checking /Users/admin/Projects/Private/blog/package.json
[====================] 45/45 100%

 algoliasearch                              ^4.8.6  →   ^4.9.0     
 i18next                                   ^19.9.2  →  ^20.2.1     
 react                                     ^17.0.1  →  ^17.0.2     
 react-dom                                 ^17.0.1  →  ^17.0.2     
 @emotion/styled                           ^11.1.5  →  ^11.3.0     
 @types/react-helmet                        ^6.1.0  →   ^6.1.1     
 babel-preset-gatsby                        ^1.0.0  →   ^1.3.0     
 gatsby                                     ^3.1.2  →   ^3.3.0     
 gatsby-plugin-algolia                     ^0.17.0  →  ^0.19.0     
 gatsby-plugin-canonical-urls               ^3.0.0  →   ^3.3.0     
 gatsby-plugin-emotion                      ^6.1.0  →   ^6.3.0     
 gatsby-plugin-feed                         ^3.0.0  →   ^3.3.0     
 gatsby-plugin-google-analytics             ^3.0.0  →   ^3.3.0     
 gatsby-plugin-image                        ^1.0.1  →   ^1.3.0     
 gatsby-plugin-netlify                      ^3.0.0  →   ^3.3.0     
 gatsby-plugin-react-helmet                 ^4.0.0  →   ^4.3.0     
 gatsby-plugin-sharp                        ^3.0.1  →   ^3.3.0     
 gatsby-plugin-sitemap                      ^3.0.0  →   ^3.3.0     
 gatsby-plugin-twitter                      ^3.0.0  →   ^3.3.0     
 gatsby-plugin-webpack-bundle-analyser-v2  ^1.1.21  →  ^1.1.22     
 gatsby-remark-autolink-headers             ^3.1.0  →   ^4.0.0     
 gatsby-remark-copy-linked-files            ^3.0.0  →   ^4.0.0     
 gatsby-remark-images                       ^4.0.0  →   ^5.0.0     
 gatsby-remark-prismjs                      ^4.0.0  →   ^5.0.0     
 gatsby-source-filesystem                   ^3.0.0  →   ^3.3.0     
 gatsby-transformer-remark                  ^3.0.0  →   ^4.0.0     
 gatsby-transformer-sharp                   ^3.0.0  →   ^3.3.0     
 googleapis                                ^67.1.1  →  ^71.0.0     
 typescript                                 ^4.2.3  →   ^4.2.4     

Run ncu -u to upgrade package.json

こういう形で ncu コマンドを叩くと package.json のライブラリの差分を表示してくれて、 全部を一気にアップデートしたいときは ncu -u とするとライブラリを自動でアップデートしてくれます。 出力結果は実際にリニューアルが終わった後に叩いた物なのですでにアップデートずみになります。

3月頃にアップデートしたばかりなのに今でも結構差分ありますね。。コンソールで叩くと実施は色付きで表示されるのでもう少し見易いかと思います。

ちょっと調べると yarn upgrade 系のコマンドでも同様のことができるようなのでyarnを使っていればあえてnpm-check-updatesをインストールしてみたいな形でなくても良いのかもしれません。

yarn upgrade --latest で問答無用で最新バージョンにアップデート(https://classic.yarnpkg.com/en/docs/cli/upgrade/)

yarn upgrade-interactive で対話的にライブラリの更新を確認しながらアップデートというのができるようです。(https://classic.yarnpkg.com/en/docs/cli/upgrade-interactive/)

https://www.gatsbyjs.com/blog/gatsby-v3/

Gatsby3 の変更点ですがこちらの記事によると

  1. ローカルでの開発スピードが 80% 改善
  2. ビルド時間の改善
  3. Web Vital, Lighthouse などのスコア向上
  4. gatsby-plugin-image のリリース

あたりが変更点です。

ちょっとまだ試せていないのですが、開発中のビルドを行う時に差分でページのビルドや画像の加工をしてくれるようになったらしいので開発体験がずいぶん改善されたようです。 構成のパートで言及した開発中の画像加工重い問題がこれのおかげで解消されているのかもしれません。

また、記事によると Faster build times on any service とあるのでビルド時間も短縮されているようです。 これまで Gatsby Cloud のみで動いていていたインクリメンタルビルドがサービスを選ばずに動くようになったようです。 記事をみる限り、ページごとに差分でのビルドを行っているのでそれがビルド時間の短縮につながっている様です。

ビルド時にAlgoriaへのインデックスの登録などを行うように変更したりしていたので、リニューアル前よりビルド時間が伸びていてあまり実感できていなかったり、 他に集中するために開発時のビルドの高速化具合が未確認などというちょっとあれな感じですが、デザインリニューアルをメインに対応したのでひとまずはこれらの確認ペンディングということにしています。

ただ、個人的にこれら変更点を記事で見た限りだとアップデートをしたくなる変更点が多いのかなという感想を持ちました。

TypeScript化

TypesScript全盛な時代になったので、ご多分にもれず自身のブログもTS化しようということでTS化を進めていきました。

Gatsbyだとフロント部分は結構簡単にTS化できるので、地道にJSファイルをTSに書き換えていく作業を行いました。 TSの方はそこまで厳しい設定にはしておらずだんだんと厳しくして行けば良いのかなというくらいのスタンスで、補完が効くなどの理由でTSを使うようにしました。

問題は、ページ生成する側の gatsby-node.js の部分をどうするかという所なのですが、こちらについては ts-node でTS化すると 割と手軽にできるので、gatsby-node.js に以下のように書いてそれ以降読み込むファイルをTSファイルにしています。

require('ts-node').register({
  compilerOptions: {
    module: 'commonjs',
    target: 'esnext',
    esModuleInterop: true,
    resolveJsonModule: true,
  }
})

const path = require('path')
const gatsbyNode = require('./gatsby-node/index')
exports.createPages = gatsbyNode.createPages

exports.onCreateNode = gatsbyNode.onCreateNode
exports.onCreateWebpackConfig = ({
  stage,
  rules,
  loaders,
  plugins,
  actions
}) => {
  actions.setWebpackConfig({
    resolve: {
      fallback: {
        fs: false
      },
...

Gatsbyも 2.x 系の頃から File System Route がサポートされているのでそこでのリファクタも考えたのですが、そこまでいくとまた大変そうだったのでそちらは使わず、createPageを実行する関数を分割してページ構成に合わせて gatsby-node ディレクトリ配下にファイルを配置するようにしました。 まだリファクタの余地ありそうですがここにはあまり時間使わずTS化する部分だけを行いました。

Algoriaの導入

サイトに記事が100本以上あるので、検索のために Algoria を導入しました。 Gatsby の場合は、 gatsby-plugin-algolia を使うと結構手軽に実装できるのでオススメです。 サイト内検索ができるようになったので、過去記事も漁りやすくなっているかと思いますので試してみてください。自分でも過去記事を漁る時があるので導入してみて自分自身も結構満足しています。 

ちゃんとしたプロダクトに入れるとなると細かいチューニングなどなど必要かとは思うのですが、個人ブログのタイトル、記事、カテゴリなどからの全文検索であればざっくり必要なデータをインデックスに入れて引っ張ってこれます。

詳細な導入方法はこちらの記事が良いと思います。

https://www.gatsbyjs.com/docs/adding-search-with-algolia/

簡単な流れを書いておくと

  1. gatsby-plugin-aloglia をインストール
  2. Algoriaのアカウントを作成、API KEYやトークンを取得
  3. gatsby-confing.js に設定
  4. ビルド時に全体の記事のインデックス登録が走る。
  5. インデックス登録された物からデータを取得する場合は、algoriasearch をインストールして使用する。

という形です。インクリメンタルサーチを実装したい場合は、 react-instantsearch-dom を使ってやったりすると良いそうなのですが、 とりあえずそこの部分は自前で実装しても良さそうだったので今回は使わないようにしておきました。

細かい UI 部分は後の部分で触れるのですが、インクリメンタルサーチを実装してみたりしたので、 その部分は個人的に勉強になりました。リクエスト部分をスロットルしてリクエストが飛びすぎないように調整していたりします。

  const onChange = useCallback(
    async (text: string) => {
      setQuery(text)
      if (text.length < 1) {
        return
      }
      const res = await search(text)

      setResult(res)
    },
    [setResult]
  )

  const onChangeThrottled = useMemo(() => throttle(onChange, 1500), [onChange])

  return (
    <div css={styles.container}>
      <SearchField
        initialFocus
        containerStyle={styles.field}
        onChange={onChangeThrottled}
      />
      <ul css={styles.list}>
      ...

実際のスロットリングを行う関数はlodashの物を使っています。 これまでReact でこういった機能を書くことがなかったのでこの機会に実装できてよかったですね。

UI的な変更点

全体的なレイアウトやコンセプトなど

前回のリニューアルのときは、ざっくりレイアウトだけを決めてあとはコーディングしながらデザインを考えるという割とズボラな実装の仕方をしていたのですが、 今回はちゃんと Figma でデザインを起こす所からやりました。

最近、Figma がブラウザで手軽にデザインを書き起こせるので非常に重宝しています。使いこなせているまでは行かないと思うのですが、Figmaでいくつかのサイトをデザインしたので幾分慣れてきたと思います。今回のリニューアルに際しては、一度軽くデザイン作ってみたのですがあまり納得いく物にならなかったので作り直しを行いました。

先に書いたようなデザインとコーディングを並行でやるズボラなやり方だと結構実装の手間が勝ってしまってデザインがおざなりになってしまうので、 予めデザインをしっかり起こしてからコーディングできると良いのかなと思いました。(当たり前ですが・・今までサボっておりできていなかったので)

リデザインに関しては、

  • 宣伝したい物があるのでバナーみたいな物をつけたい
  • ポートフォリオ的な位置付けでもあるので、もうちょっと印象に残るデザインが良い
  • 上に書いたバナーみたいな物を追加したい

みたいな要求(欲求?)があったのでそれを元にレイアウトなどは決めていきました。

また、印象にのこるサイトがよかったので紫(これはReactのイメージカラーから持ってきました。。)を基調に最近ボチボチトレンドなどと言われている Glassmorphism ポイ透け感を入れたサイトにしました。実際に動画などに上がっているGlassmorphismのデザインはもっと派手ですが、記事を読むサイトに置いてあまり派手すぎるとそれはそれで疲れるかなということで抑えめにしています。

デザインは、全然体系的に勉強はしていなので趣味レベルではあるのですが、ちょっと気づいた時にお気に入りのサイトをストックして観察したり、Youtube のデザイン系のYoutuberの動画をみたりして少しづつ知見をためてきたので以前のデザインよりはましになったのかなと思っています。

モバイルの時のUI改善

モバイルでの Page Speed Insight のスコアが悪かったのでその辺りも改善できるように工夫したりし、モバイルの記事の一覧はできるだけシンプルにして サムネイルなどは表示しないようにしました。これは自分でもモバイルで色々な技術系記事をみるのですが、サムネイルがクリックの決め手になることが少ないので まぁ特になくても影響ないとい判断でサムネイルは表示しないシンプルな画面にしました。

モバイルのトップ画面

結果的に元々黄色スコアだったものが緑まで改善されたのと、だいぶ見やすくなったというのがあるのでやってみて成功でした。

検索モーダルの追加

検索を追加したのは上で書きましたが、検索モーダルは二箇所に設置するようにしました。ヘッダーの検索アイコンと各記事の下に検索フォームを設置して、 サイトに訪れたタイミング、記事を読み終えて他の記事もみてみたいとなった時などに利用できるように二つの箇所に設置しました。

実際にどれくらい検索されるのかとかは測定してみるのも良いかなと思うので、どこかのタイミングで測定してみたいです。 (使われてなくても少なくとも自分は使う気がする)

記事への目次の追加

記事中で記事の全体が把握できるように目次を仕込みました。Gatsbyでは gatsby-remark-autolink-headers を使うとマークダウンから生成された見出しにリンクを自動で付与できるのでそれを使って目次を実装しています。

それぞれの記事のデータの見出しは gatsby-transformer-remark でパースした結果に含まれているのでその結果と上記で生成される id属性を結びつける形で 実行できます。お好みでスムーズスクロールにしたり、目次を追従するようにして出来上がりという形です。

目次の表示の形としてモバイルだと今目次が表示できていないので、そこは要改善という形です。モバイルでは目次を最初の見出し前に出すような形で表示するよう考えていますが、記事によっては全く見出しのない記事もあるので「どうしたものか」というのはありますが、とにかくどこか時間を見つけて実装できればと思っています。

コンソールを模した記事フィルタ

前述のように印象に残るようなサイトがよかったので、記事のフィルタとしてコンソールを模した物を配置しています。 こちらはまだまだ作り込み必要な気がしているのですが、とりあえず、

  1. 新着記事
  2. 人気記事準
  3. ピックアップ記事
  4. カテゴリ
  5. タグ

という形で記事を絞り込めるようになっています。

本当のところは、ls, pwd, cd 的な物を実装したかったのですが、ひとまず時間かかりそうなのでリリースを優先してそのまま出しています。

今のところカテゴリ、タグ周りが結構整理されない形でタギングされているような感じもあるのでここらも合わせて整理していきたいです。

振り返り

トータルで結構な作業量にはなったのですが、Figmaからしっかりデザインを起こして実装・リリースまでできたのである程度納得いく形で終えることができました。 サイト内検索をつけて利便性向上していたりもするので満足です。モバイル用の目次の実装やコンソール部分の実装、Gatsby3で改善された画像のビルド部分を踏まえた開発環境の最適化など積み残しはいくらかありますが、記事追加と合わせて少しづつ作業進めて頂ければと思います。

ここまで読んで頂いた方には、ブログの実装で使っているプラグイン等々の情報などが役に立てば良いかなと思います。

では。

関連記事

記事検索

気になるサイト内の記事を検索する

プロフィール

バンクーバー在住のフルスタックエンジニアです。React, Ruby on Rails, Go などでお仕事しています。職場がトロントなので日本、トロント、バンクーバーの三つの時天空を操って生活しています。

プロモーション

Index

  • リニューアルの経緯
  • 全体の構成
  • やったこと
  • 技術的な変更点
  • UI的な変更点
  • 技術的な変更点
  • Gatsby3へのアップデート
  • TypeScript化
  • Algoriaの導入
  • UI的な変更点
  • 全体的なレイアウトやコンセプトなど
  • モバイルの時のUI改善
  • 検索モーダルの追加
  • 記事への目次の追加
  • コンソールを模した記事フィルタ
  • 振り返り