個人ブログを支える技術 2023 年版

最近、立て続けにこの個人ブログ (kenwagatsuma.com) のリファクタリングやアップデートを行った。その備忘録。

基本戦略としては "Simple is the best"。長年開発してきて積もり積もった技術負債や不要な要件をバッサリ切り落とした。

Cloudflare Pages への移行

一番大きい変更は、Netlify から Cloudflare Pages への移行。フレームワークとしては Gatsby を利用しており、ビルドして静的アセットを出力して配信するだけなので Netlify でも大きな不満はなかったが、会社で Cloudflare を使っているので個人でも使っておきたかったという理由が大きい。

移行作業は至ってスムーズで、Cloudflare Pages 側で配信設定をした後、DNS レコードを変更するだけ。Cloudflare Pages も今の所大きな不満はない。

Gatsby v5 へのアップデート

NPM パッケージの更新が滞っていたので、これを機に全ての依存パッケージのバージョンを最新の安定版にした。Gatsby は v4 から v5 にアップデートした。いくつか Deprecated になっていた GraphQL Query を修正したり、依存パッケージをアップデートしたりと、細々とした作業は必要だったが、大きなブロッカーは存在しなかった。

Google Analytics の廃止

当たり前のように Google Analytics を導入していた。時々ダッシュボードを閲覧して、人気記事や検索クエリを確認していた。しかし、冷静に考えると、会社で扱うプロダクトのようにかっちりとマーケティングして Page View をあげていくために運用していきたいわけではない。個人ブログは、技術の実験場であり、コーディングの癒しの遊び場であり、書いた本や集めた知識のアウトプットの場である。「書く」ことに集中するために「分析」を捨てることにした。

Google Analytics によって若干発生していた余分な HTTP リクエストやタグの読み込みが減るので、ユーザーにとってもメリット。

タグ関連スコア計算による Neo4j 依存の廃止

以前にこの記事、Blog Relevant Tags Internalsで紹介したように、タグの関連スコアを Neo4j を利用してビルド時に計算して算出していた。

当時は Neo4j に在籍していたので、その練習がてらこのような実装にしていたのだが、ビルド時に Neo4j に依存するのは運用コストも嵩み、かつ Cypher クエリの学習も済ませたので、今回を機にピュアな JavaScript 実装に置き換えた。

オーダー計算量が上がり、一時的に利用するメモリ使用量は増えているのだが、個人ブログのビルドの頻度なんて数えるくらいだし、依存パッケージや Neo4j のプロセスを廃止できる運用コストへの寄与を考えると、シンプルな設計に大きく貢献した。

難易度レベルの廃止

過去に書いたこの記事、Blog: Post "Level" Introducedでも紹介したように、ブログの難易度レベルというのをメタデータで管理して表示していた。しかし、そこまで運用するモチベーションも利用実績もなかったので、思い切って廃止した。

品質の低いブログ記事の削除

過去にただアウトプットしたいがために無理矢理書いたような品質の低いブログ記事を、英語・日本語両方から大幅に削除した。

「編集」の肝は、いかに余分な贅肉をカットするか、という点にある。品質の高い文章を書くためには、何度も推敲プロセスを経て、冗長な文章を削ぎ落とし、品質の高い文章だけを残していく。個人ブログを一つの壮大な書籍と考えたときに、その遂行と編集のプロセスは必要不可欠だと考えている。

品質の低いプロジェクトの削除

ブログ記事の削除と同様に、品質の低いサブプロジェクトのソースコードを大幅に削除した。具体的には、Error Budget のオンライン計算ツールや、任意のテキストの QRCode 生成ツール、JSON/YAML 変換ツールなど。

JavaScript の実験場としての役割もあって、個人で使いたいツールを時々作る。車輪の再開発の側面は大いにあるのだが、すでにあるオンラインツールだと、広告が多すぎて利用するのにも集中を阻害するノイズが多かったり、微妙に使い勝手が悪かったりするので便利ではある。一方で、ブームが過ぎると途端に利用しなくなるようなツールもあるので、思い切ってシンプルにするために削ぎ落としてみた。

React Components のリファクタリング

再利用できるビジネスロジックが複数のコンポーネントに散らばってきたので、モジュール化を促進した。具体的には、複数のイメージを表示させるための Gallery コンポーネントを新設したり、リンクを表示させるためのコンポーネントを一つの SmartLink コンポーネントに束ねたりした。また、Pagination コンポーネントの仕様を若干使いやすくしたり、リデザインしたりも同時に行った。

Typography の改善

以前は Typography.js を利用していた。独特なフォントを気軽に導入できるので愛用していたのだが、そのためだけに追加でパッケージを入れるのが気に入らなくなったので、思い切って標準フォントに切り替えて削除することにした。日本語でも英語でも読みやすい font-family に切り替えてみた。集中して読むことができる個人ブログにするために、line-height や margin/padding も意識して微調整し、ブログ本文にはコンポーネントは追加しないようにもしてみた。

画像一覧ページの新設

Images ページを新設した。これは、ブログから引用されている画像一覧を表示している。画像をクリックすると、画像が引用されているブログに飛べる。動機としては、リンク切れで不要になった画像があるのを検知したかったのと、単純にこれがあると開発時に既存画像を再利用しやすくなるからだ。このページを新設するにあたって、曖昧に管理されていた画像アセットも特定のディレクトリで一貫して管理するようにした。

実現方法としては、gatsby build でページを出力する際に、gatsby-config.js 内でブログの HTML Abstract Syntax Tree (AST) を活用する。unist (Universal Syntax Tree) を利用して AST を解析し、画像タグがあったときは逆引きのインデックスを作成している。そこで作成したインデックスを、画像一覧ページの出力に利用している。

お気に入り一覧ページの新設

Bookmarks ページを新設した。特にフレームワークなどを使わず LocalStorage API をシンプルに利用している。データはクライアント側に保存されているため、サーバー側では誰がどのような記事をお気に入りに入れているかは分からない。ブログの本数が増えてきたので、時々ブックマークしておきたい記事が増えてきたという自身のニーズを満たす目的が大きい。

最後に

以上、最近の個人ブログの変更履歴についてまとめてみた。次の展望としては、以下のような機能実装を考えている。

  • 検索機能の実装。最適なインデックス生成や効率的な検索アルゴリズムはフレームワークを使わずネイティブに実装してみる
  • プロジェクトの新規追加。シンプルな 2D ゲームなどいくつかアイデアは溜まってきている
  • 技術ブログの定期更新。以前は Neo4j を中心とした技術ブログをアウトプットしていたが、最近の興味に沿った内容も定期的に更新したい
2023-09-27