電子版の紙面1ページは大きな画像です。長辺2000ピクセルで、小さな文字がぎっしり詰まっています。読者は10ページ、20ページとめくり、しかも回線の不安定なスマートフォンで読むことも少なくありません。セルフホスト型電子版プラットフォーム Inkfold のバージョン1.1で、最初に作り直したのが紙面の表示速度でした。
1ページを3つのサイズで保存する
アップロード時、各ページはGDで3つのファイルに再エンコードされます。原寸の紙面、幅約1100ピクセルの中サイズ、そしてページ一覧用のサムネイルです。形式はサーバーごとに一度だけ決まり、PHPが対応していればWebP、そうでなければJPEGになります。テスト用の紙面では、WebPにすることで同じ画質のままページの容量がおよそ3分の1減りました。ページ数の多いサイトでは、これがどの最適化よりも効きます。
再エンコードでは、埋め込みのカラープロファイルやカメラ情報など不要なデータも取り除き、透明部分は白で塗りつぶします。組版ソフトから書き出したPNGが黒い背景で表示されることはありません。
まず中サイズ、原寸は必要なときだけ
リーダーは通常、中サイズの画像を表示します。普通の表示サイズでは原寸と見分けがつかず、容量はその数分の一です。読者が拡大すると、スクリプトは表示幅に端末のピクセル比を掛けた値を画像の実際の幅と比べます。中サイズでは明らかに足りない大きさまで拡大されたら、原寸画像を裏で読み込み、届いた時点で差し替えます。

拡大しない読者は原寸画像を一度もダウンロードしません。拡大する読者も待たされません。大きな画像の準備ができるまで中サイズが表示され続けるからです。同じ号の次のページは中サイズで先読みされるので、ページめくりは一瞬です。
記事の切り抜きは一度だけ作ってキャッシュする
各記事エリアは、ポップアップ表示や共有のために単独の画像として開けます。以前はリクエストのたびに切り抜きを生成していました。現在は最初のリクエストで切り抜いてメディアディスクに保存し、ファイル名にはエリアと紙面画像のハッシュを含めます。エリアを描き直したりページを差し替えたりすると、自動的に新しいファイルになります。レスポンスには1週間のキャッシュヘッダーを付けています。
メディアはどのストレージにも、CDNの背後にも
ファイルへのアクセスはすべて1つのヘルパーを通り、ローカルディスクに固定されていません。INKFOLD_DISK=s3 を設定すれば、紙面画像・PDF・切り抜きは Amazon S3、Cloudflare R2、DigitalOcean Spaces に移ります。ファイルを手元に置きたい場合は、INKFOLD_MEDIA_URL で画像URLを Cloudflare や Bunny などのプル型CDN経由にできます。ファイル名には20文字のランダム部分が残るため、どのストレージでも有料ページを推測されることはありません。
ポイント
- アップロード時に3サイズで一度だけエンコードし、可能ならWebPを使う。
- まず中サイズを表示し、拡大で差が見えるときだけ原寸を読み込む。
- 生成した切り抜きは、元データが変わればキーも変わる形でキャッシュする。
- ファイルアクセスを1つの抽象化にまとめ、S3やCDNへの切り替えを設定だけで済ませる。
シリーズ次回は、左右のページの高さをそろえる見開き表示です。ここで紹介した機能はすべて Inkfoldのライブデモ で試せます。ソフトウェアは Charming Theme で入手できます。
新聞や雑誌をオンラインで発行していて、表示の遅さにお困りですか?ご相談ください — ArtinTech Solution はこうした出版システムの開発と高速化を手がけています。