Home JavaScript Greasemonkey PHP

自作のブログシステムに OTCHY.NET を移行しました2021-03-15


元々 WordPress で構築していて Google App Engine でホストしていたこのサイト OTCHY.NET を、フルスクラッチで自作したブログシステムに移行しました。レンタルサーバ上で動いていた CentOS + Apache + php_mod + MySQL から Google App Engine に移行した前回のリニューアルが 2016 年 8 月 1 日なので、実に約 4 年半ぶりのシステム更新になりますね。

実は今回、そもそもで言うとそのような大がかりなリニューアルをする予定はありませんでした。というかむしろ、OTCHY.NET 上でブログ更新をするのは辞めて、note に移行するつもりでいました。より正確に言えば、一度 note に移行したのです。実際に「敗北宣言」というポエム note を書いているのでそこから一部引用します。

自分のドメインで自分のサイトを持って色々作って公開するのは実に楽しかった。自分のホームでは全ての責任が自分にあるけど全てが自分の思いのままで、何でもできた。

ブログ始めようって思ったのが 2008 年。もちろん独自ドメイン以外の選択肢は無かったんだけど、<中略>ブログのドメインは新しく otchy.net を取ることに決めた。

ブログシステム全部自分で書く…ってのも一瞬頭をよぎったけれどさすがに面倒過ぎて追加で借りたサーバに WordPress をインストール。

技術系の記事は Qiita に移行してしまった。<中略>技術系記事を Qiita に移行した後も、読み物系の記事は細々と otchy.net に書き続けていた。

だけれども今日、2020 年。初めてこの note を書いた。だからこれは敗北宣言。

引用した内容からも感じ取れるところがあると思いますが、OTCHY.NET で WordPress を立ち上げてブログを運用している間、自分のドメインでブログをやっている事にはプライドを持っていて、立ち上げた当初の想いで言えば「死ぬまでここでやるぞ」という想いだったわけです。

それが、やっぱり技術系記事を書くのは Qiita が楽だしバズりやすいしで途中から技術系記事は Qiita で書くようになってしまったのが 2013 年。その後もずっと WordPress の運用は続いていくものの、そもそもブログシステムを維持管理するのが辛くなり、もう読み物系の記事も外部サービスに頼るか。老いたな…。と思って書いたのが前述の敗北宣言だったわけです。

そこまで聞くと、フルスクラッチで自作のブログシステムを作って移行するなんていうのは真逆の方向性ですし、ほんの数ヶ月前に敗北宣言を書いた時には自身でも夢にも思わなかった展開なのですが、結果としては元サヤ、究極の理想とも言えるところに戻ってくることになって、いまリニューアル後最初のこの記事を書いています。

なんでこうなったのか?

いったん自分のブログを note に移行して少し経った頃に、GAE 上でずっと WordPress を動かしておくのは無しだな、と思いました。というのも、OTCHY.NET は PHP を走らすだけだったら GAE の無料枠で十分すぎる程度のアクセスしかないサイトではあるものの、WordPress を動かすための MySQL に関しては GCP 上での課金が必須なんですね。つまり、note に移行して今後は記事が増えない、言わばリードオンリーモードのブログの MySQL に対して、今後何十年にも渡って課金し続けるのは無しだな、と思ったわけです。

OTCHY.NET にはそれなりに過去にバズった記事もあり、未だに流入が続いている特異点のような記事もあり、完全にシャットダウンしてしまうという選択肢は無かったので、じゃあ本当の意味でリードオンリー、全部の記事を静的な HTML に移行してしまえば良いではないかという発想になりました。おりしも2021年だから人類はHTMLを手打ちしろなんていう記事を読んで感銘を受けていたところだったので、なおさらこのアイディアが気に入りました。

さてそうなると、どうやってそれまでの WordPress の記事や各種の一覧ページ (月別・カテゴリ・タグ) の内容と URL を保ったまま移行するかの検討が必要です。強力なエコシステムを持つ WordPress にはもちろんその手の静的 HTML 出力プラグインがいくつも存在するので、最初はそれらの調査を行いました。ボタンを一つ押すと現在の WordPress のデータベースや設定に基づき特定のディレクトリ以下に多量の HTML が URL 構造を保った形で出力され、そのディレクトリを丸ごと持ち運べばどこでも静的なサイトとしてそのまま全てが動く、というようなものが理想的でした。ところが ── WordPress のプラグインである以上当たり前ではあるのですが ── どのプラグインも WordPress が稼働中である事を前提として、通常の動的なページをあらかじめ静的に出力しておくことでパフォーマンスを向上することができる、というコンセプトのものばかりでした。

これは違います。目指しているゴールは WordPress からの脱却だったので、WordPress の稼働を前提とする仕組みはお話になりません。ですので結局、WordPress のデータベースを直接読んで HTML を生成するツールを自作することにしました。まあブログシステムを自作するわけでは無く、データベースに入っている情報を元に HTML を生成するツールを作るだけならそんなに面倒では無いと踏んだわけです。そもそも WordPress にまだ夢を描いている頃にいくつかプラグインを書いた事があって、WordPress のデータベースのテーブル構造がかなりシンプルである事を知っていた、というのも背中を押してくれました。

そうこの時点ではまだ、ブログシステムとして移行するつもりは無く、一度限りのスクリプトを走らせてリードオンリーにしたら終わりにする予定だったのです。

よし設計だ!

しよせんおれおれツールだし、まっとうなドキュメントを書いたりはしていないんですが、どんな感じの仕組みにするかの設計はしました。図は書かないまでも箇条書きのメモ程度は書きました。

前述のように一番初めはデータベースを読みながら直接 HTML を出力することを考えていました。ただ程なくして、まずデータベースのデータをただのテキストファイルにエクスポートするステップと、エクスポートしたテキストファイルから HTML を生成する次のステップに分ける事に決定します。

というのも将来何らかの理由でコンテンツの更新が必要になったりした場合に、いちいちデータベースを立ち上げてその内容を更新し、ツールを走らせ直すというのが面倒だからです。またほとんどのケースで問題はないだろうと思いつつも、データベースからの一発変換で全て綺麗に HTML 化できる確証もありませんでした。いったん中間形式たるテキストファイルを経由すればそのテキストファイルの変更は簡単なので、将来の更新の問題、エクスポート時の微調整などの問題が解決します。

そしてテキストファイルでデータを管理するメリットはまだあります。データを全部 git に突っ込んで変更履歴や更新途中の状態を管理できることです。また WordPress に縛られた苦い過去もあり、データの可搬性が高いという面もメリットとして感じていました。

さて、git でデータを管理しようとなったのならば、GitHub 上にデータを持ち、静的 HTML のホスト先としてそのまま GitHub Pages を使うのはもはや必然でした。そして、データベースからテキストファイルへのエクスポートで、data/path/to/article/ ディレクトリに content.htmlmeta.json を書き出すのが最初のステップ。そして data/path/to/article/ にあるファイルを読んで docs/path/to/article/index.html を書き出すのが次のステップ。というのも自然に決定したのです。もちろん、data 以下に保存されているファイルを全部読んで、カテゴリ一覧ページなどを自動生成するのもセットです。

あれ?

ふと気付きました。「これブログシステムそのものじゃねーの?」と。だって任意のパスに content.htmlmeta.json を置いてツールを走らせたらそのままいい感じに公開出来るって事は、そこに新しい記事を追加するのも簡単ですから。

敗北宣言からものの数ヶ月で敗北宣言撤回です。他者の都合に一切左右されない究極の理想、自作ブログシステムを作って運用することが決定した瞬間でした。

どのようなシステムを目指すか

一度やる気になるとあれもこれもやりたいと欲が出てきました。

今回作ったブログシステムは静的サイトジェネレータというプログラムに分類されます。静的サイトジェネレータというと、生成物自体はシンプルで非常に高速に動作する一方で、HTML の出力自体はあまり高速に動作しないというのが一般的です。まあ普通にトレードオフですよね。まずこいつを覆してやろうと思いました。これが遅いと、記事を書き直したりあるいはデバッグの度にいちいちい引っかかることになるのでそれを避けたかったのです。

結果どのようになったかというと、数百ページ程度のサンプルで偉そうにするなと言われてしまえばそれまでですが、いま手元で高速モードでビルドをしてみるとこんな結果になります。

% npm run build:dev

> no-more-wordpress@1.0.0 build:dev /Users/otchy/Dropbox/workspace/no-more-wordpress
> node bin/build.mjs --mode=dev

Start writing HTML files.
Done! (Built 425 pages in 612 msecs)

425 の HTML を出力してかかった時間が 612 ミリ秒、1 ページあたり 1.5 ミリ秒以下です。この位だと待ち時間、という感覚はありません。なお各種の最適化が全て走る本番モードだと、さすがにもっと遅くて同量の HTML で 4320 ミリ秒、1 ページあたり約 1 秒でしたが、全然許容範囲じゃないでしょうか。

また、最終的に出力されるサイトの速度にもかなりこだわりました。長大で鈍重な動的ページ生成システムである WordPress をシンプルで軽量な静的サイトジェネレータに置き換えるのならば、とことんやってやれと思ったわけです。試しにいま見ているこのページをリロードしてみて下さい。どうですか?回線速度にもよりますが、リロードを感知できないレベルで早くなかったですか?

実際、WordPress で運用されていた旧サイトと GitHub Pages でホストされている新サイト両方で、Google Chrome 付属の Lighthouse で測定しパフォーマンスを比較してみたのですが、旧サイトはパフォーマンスのスコアがデスクトップで 53、モバイルで 60 だったところ、新サイトは双方とも 98 と圧倒的な向上が見られました。

特にデスクトップでのパフォーマンスが圧巻で、手元の環境 (光 1GB -> 802.11ac) だと、First Contentful Paint 0.1 s、Speed Index 0.1 s、Largest Contentful Paint 0.1 s、Time to Interactive 0.4 s、Total Blocking Time 50ms。これがリロードを感知できないレベルのスピードです。

Lighthouse Report

高速静的サイトジェネレータの作り方

では実際のところ、どのようにして WordPress のデータを抽出し、このビルドも出力結果も高速な静的サイトジェネレータを作ったのか。…については、あらためて次の記事で解説したいと思います。

まずは新サイトのお披露目まで。

(追記)

この記事を書いてから、何と 1 年半以上も経ってようやく「いかに爆速ブログシステムを自作し WordPress を置き換えたか」を公開しました。


カテゴリ: Information タグ: wordpress