10,000枚を超えるギャラリーサイトの高負荷アップロードを静的サイトで最適化した方法

10,000枚を超えるギャラリーサイトの高負荷アップロードを静的サイトで最適化した方法

現在、CMSの中心的存在はWordPressですが、Movable Type(以下、MT)のような静的サイトも再評価されてほしい、と期待しております。ぱくたそカメラマン兼運営管理人のすしぱくです。

ご存知の方もいるかと思いますが、ぱくたそのサイトはMTで構築されています。MTの良い点は、ユーザーのみなさんが閲覧するページを静的に生成してくれることです。静的に表示されることにより、ぱくたそではリアルタイムの同時訪問者が1000を越えても、CPU負荷は10%も上昇しません。

「だから静的サイトは見直されるべき!」と声を大にして言いたいところですが、サイトの内部はCGIで動いているため、ページの更新や写真を追加する作業時にはかなり負荷がかかってしまいます。そのため、運営者としては苦労することも多いのです。

例えば、ぱくたそは「フリー素材サイト」として、画像一覧のサムネイルからダウンロード用の高解像度の写真まで、各種サイズの写真がアップされています。実はこれらは、高解像度の写真を1枚アップロードすれば、すべて自動的に生成されるようになっているのです。

この自動化のおかげで、作業の負担が軽減され、少人数での運営が可能になります。しかしこのシステムは、一般的に知られている手法で構築しようとすると、前述の「静的サイトであるための苦労」をすることが多いのです。

今回の記事では、MTでこのようなシステムを実装したい場合、どうすれば負荷を抑えつつスムーズに実装できるかを解説します。

みんな大好き「MTAssetThumbnailURL」、でも......

MTの画像生成と言ったら、みんな大好き「MTAssetThumbnailURL」ですよね。

 MTAssetThumbnailURL | テンプレートタグリファレンス - CMSプラットフォーム Movable Type -

MTの固有タグなので、別途プラグインを用意しなくても画像生成ができます。

カスタムフィールドからアップロードした写真に各モディファイアを記述することで、自動的にリサイズしてくれます。"ギャラリーサイトを制作する方法"などを解説しているサイトは、ほとんどがこの記述を紹介しています。ぱくたそも昔はこのタグを使っていました。

しかし、枚数が増えてくると、話は別です。

「MTAssetThumbnailURL」はとにかく高負荷

「MTAssetThumbnailURL」では、記事を更新するごとに生成処理が発生するため、都度、サーバーに負荷がかかります。例えば、ぱくたその各写真ページだと、1ページ生成するのに下記項目の画像の生成が必要になります。

  • 拡大用の画像サムネイル
  • ダウンロードLサイズ用画像
  • ダウンロードSサイズ用画像

この3項目は記事にアップロードした写真からそれぞれ生成されます。この程度の枚数と処理であれば負荷は気にならないレベルですが、問題は残りの部分です。

  • 関連用の低品質画像
  • 関連用のスクエア画像

この2項目は関連画像として、25種類(上部)+15種(下部)の画像を生成するものです。前の3項目と異なるのは、この記事にアップロードした写真ではなく、他の記事で使われている写真を読み込んで生成をする点になります。

毎回異なる画像を40枚ずつ生成するわけですから、負荷は当然高くなります。ぱくたその場合、1つの写真を公開するのに約10分以上のロード時間がかかってしまうのです。1日10枚をアップロードすると、約100分以上。テキスト部分の誤字を直す場合も同様なので、仕事になりません。

更に、ページを更新するごとに再構築の処理が走るスタティックのテンプレート・記事テンプレート・カテゴリテンプレートがあると大変です。いっぺんに処理するとなると、ロード時間が長すぎて500エラーが頻発して、再度やり直しです。

実は、これがサービスの立ち上げ時からの課題でした。しかし、「MTAssetThumbnailURL」に変わるものはなく、解決策も見つからず。サイトが成長するごとに、性能がよいサーバーに鞍替えすることでやり過ごしてきましたが、想像以上の費用がかかり、運営の限界を感じるようになります。

「AutoThumbnailURL」の負荷はアップロード時のみ

「MTAssetThumbnailURL」は、ページを更新する度に画像が生成されるため、CPUに負荷がかかると説明しました。誤字の直しのように、写真を差し替えなくても、そのエントリテンプレートに「MTAssetThumbnailURL」の記述があれば、自動生成の処理が都度、走ってしまうからです。

OFFに設定する項目はありません。悩ましい問題です。

そこで、考え方を変えてみることにしました。

  • 拡大用の画像サムネイル
  • ダウンロードLサイズ用画像
  • ダウンロードSサイズ用画像
  • 関連用の低品質画像
  • 関連用のスクエア画像

これらの画像は、前述したように、生成されるサイズがあらかじめ決まっています。

  • 拡大用の画像サムネイル--横幅が800px
  • ダウンロードSサイズ用画像--横幅が1600px
  • 関連用の低品質画像--横幅が640px
  • 関連用のスクエア画像--正方形(スクエア)の400px

これらのサイズを「MTAssetThumbnailURL」が自動的に生成していたのですが......、これって、先にリサイズした画像をアップロードしておけば負荷はかからないのではないか?

要は、何かしらの画像編集ソフトを使ってリサイズとリネームを行い、画像を先にサーバーにアップロードしておけばいいという発想です。実にアナログですね。

この方法で記事の更新をすると、ロード時間が20秒程度となります。サーバーの負荷もなく改善されたかのように思われますが、人力で画像加工を行う手間とリネームミスの負担が大きく、結局は「MTAssetThumbnailURL」と同じくらいの時間を費やしてしまう結果でした。

これを自動化できれば改善の見通しが立ちます。ということで、最適なプラグインを探していたところ、「AutoThumbnail」に出会うのです。

「AutoThumbnail」の導入とできること

「AutoThumbnail」は、エンジニアのBUNさんが開発しているMTプラグインです。

國分 亨(@BUN)さん | Twitter

ぱくたそでもお世話になっている「 bit part 合同会社」さんのパートナーとして活動されています。

「AutoThumbnail」のプラグインは下記よりダウンロードいただけます。
 GitHub - dreamseeker/mt-plugin-AutoThumbnail: 画像アップロードの際にサムネイル画像を生成する Movable Type プラグインです。
※ 商用・非商用共に自由にご利用いただけます。

さて、「AutoThumbnail」を使うとどうなるか。

  • 拡大用の画像サムネイル--横幅が800px
  • ダウンロードSサイズ用画像--横幅が1600px
  • 関連用の低品質画像--横幅が640px
  • 関連用のスクエア画像--正方形(スクエア)の400px

これらの生成するサイズを、あらかじめ「AutoThumbnail」に記述します。管理画面の設定は次の通りです。

[「AutoThumbnail」に各サイズの情報を記述する]

サムネイル画像1 は、横幅1600px-jpeg品質90で生成
サムネイル画像2 は、横幅640px-jpeg品質30で生成

サムネイル画像1の記述を説明すると、横基準(Width)で幅は1600px、正方形(スクエア形)にトリミングはしない(0)、JPEGの品質は90、pngの品質は8という設定です。このように写真をアップロードすれば記述したサイズで生成します。

さて、気になる生成のタイミングですが、「AutoThumbnail」では、アイテムのアップロード時に処理を行います。

「MTAssetThumbnailURL」のように記事の更新時ではないため、空いた時間に写真をドラッグ・アンド・ドロップしておけば自動的に生成します。手間もかからず楽で便利ですね。

次に、リサイズした画像は任意の接尾語を付与することができます。

[TP_Vと入力するとサムネイル画像1は、TP_V_1 2は、TP_V_2 となります]

このように、生成された画像のファイル名を記事テンプレートに記述します。

replace を使って生成された画像を指定することで、「MTAssetThumbnailURL」の記述が必要なくなります。長年悩んでいたことですが、あっという間に解決できてしまいました。ぱくたそではこのような流れで、各写真をリサイズして表示しています。

MTを使ってギャラリーサイトを運用している方は、ぜひご検討ください。