静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう。
公開日 : 2007-06-25 20:05:59
追記(2007年6月29日):
一連のエントリーで作成したものを取りまとめて公開しました。
もうちょっとだけ掘り下げてみたいと思います。というかあれこれ考えているよりTryしてみる方が早いし建設的かな。WordPressは触ったことがないのですがMTならこんな解決法もあるよ、ということで。
関連エントリー
- 静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(続き)。
- 静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(さらに続き)。
- 静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(完結編!?)。
このエントリーを書くきっかけとなった他の記事
- Webページの静的生成と動的生成のどちらが良いかはサイトの性質とポリシー次第。
- 静的生成と動的生成、Webページをビルドするコストは誰が支払うべきなのか (talk to oneself 2)
- 眠る開発屋blog » WordPressでキャッシュを使うWP-Cache
- 眠る開発屋blog » WordPressでキャッシュを使うWP-Cache
- [N] Movable Typeの再構築を少し高速化するチューニング
- Movable TypeからWordPressへの移行はよく見られるようですが・・・ | bewaad institute@kasumigaseki
Movable Type10分間Cooking!
- Webページの静的生成と動的生成のどちらが良いかはサイトの性質とポリシー次第。
- 静的生成と動的生成、Webページをビルドするコストは誰が支払うべきなのか (talk to oneself 2)
- 眠る開発屋blog » WordPressでキャッシュを使うWP-Cache
- 眠る開発屋blog » WordPressでキャッシュを使うWP-Cache
- [N] Movable Typeの再構築を少し高速化するチューニング
- Movable TypeからWordPressへの移行はよく見られるようですが・・・ | bewaad institute@kasumigaseki
Movable Type10分間Cooking!
再構築はインデックスやRSS, カテゴリー・アーカイブ等に限定し、エントリー・アーカイブはダイナミック生成とする。但し最初のリクエストがあった時にスタティックなファイルを生成してしまう(DBにキャッシュを保存するのではなく、そのhtmlを生成してしまう)。
※まだクライアントキャッシュのところ出来ていないのでGoogleさんに来られると嫌なので rel="nofollow" 付きリンクですが, テスト用サイトを用意してみた。そのうち削除するかも。
テスト用ブログ : Junnama Online (Dynamic)
まず現状のサイト(エントリー数250程度)をMTからエクスポート、新規ブログを作成してインポート。テンプレートは適当。
-
「設定」→「公開」→「再構築オプション」で「テンプレート別に、スタティックHTMLもしくはダイナミック・パブリッシングを選択します」にチェック。
- エントリー・アーカイブの編集画面で「このテンプレートをダイナミック・ページにする」にチェック。
- サイト全体を再構築(インデックスやカテゴリー関係のみの再構築なので軽い。7秒くらいで完了)
- mtview.cgiを用意。実行権限を与える。
#!/usr/bin/perl -w use strict; use lib qw (/path/to/mt/lib/); use lib qw (/path/to/mt/extlib/); use MT; use MT::Blog; use MT::Entry; use MT::Builder; use MT::Template; use MT::TemplateMap; use MT::Template::Context; my $mt = MT->new(Config => '/path/to/mt/mt-config.cgi'); my $base_url = 'http://junnama.alfasado.net'; my $base_pth = '/path/to/htdocs'; my $blog_id = 3; my $request = $ENV{"REDIRECT_URL"}; # /online/2007/06/mt4Movable Typebookmarklet.html my $permalink = $base_url.$request; my @pathes = split(/¥//,$permalink); my $counter = @pathes; my $lastpth = $pathes[$counter-1]; my @basenames = split(/¥./,$lastpth); my $base_len = @basenames; my $basename = ''; my $lastnum = $base_len-1; for (my $i = 0; $i < $lastnum; $i++) { $basename .= $basenames[$i]; if ($lastnum-1 != $i) { $basename .= '.'; } } # basename => mt4Movable Typebookmarklet my $blog = MT::Blog->load({ id => $blog_id }); my $iter = MT::Entry->load_iter({ blog_id => $blog_id, basename => $basename},{ sort => 'modified_on', direction => 'descend', }); if (! defined $iter) { $iter = MT::Entry->load_iter({ blog_id => $blog_id},{ sort => 'modified_on', direction => 'descend', }); } my $build_entry; while (my $entry = $iter->()) { if ($entry->permalink eq $permalink){ $build_entry = $entry; last; } } # read template if (defined $build_entry) { my $tmap = MT::TemplateMap->load( { blog_id => $blog_id, archive_type => 'Individual', is_preferred => 1 },); my $template = MT::Template->load({id => $tmap->template_id}); my $preview_tmpl = $template->text; my $ctx = MT::Template::Context->new; $ctx->stash('entry', $build_entry); $ctx->stash('blog', $blog); $ctx->stash('blog_id', $blog_id); # build entry my $build = MT::Builder->new; my $tokens = $build->compile($ctx, $preview_tmpl); my $html = $build->build($ctx, $tokens); print "content-type: text/html¥n¥n"; if ($html) { # replay and write static file print $html; my $buildfile = $base_pth.$request; open (OUT,">$buildfile"); print OUT $html; close(OUT); } } else { print "content-type: text/html¥n¥n"; print "404 Not Found."; }
- MTが生成した.htaccessファイルがサイトのルートディレクトリにあるので削除。
新たに以下の1行のみ記述した.htaccessを生成。
ErrorDocument 404 /dynamic/mtview.cgi
10分じゃ...終わらなかったけど、まぁ30分コース。
再構築時にはインデックス、カテゴリーアーカイブ等は再構築され、エントリー・アーカイブの再構築は行われない。
最初にリクエストがあったときに「ファイルが存在しなければ」NotFound、つまりmtview.cgiにリクエストが渡されるので、ページを生成してクライアントに返す(同時にファイルを生成する)。
アクセスがあるかどうかわからない古い奥の階層のページまで再構築する必要がないし、データベースへのアクセスは最初の1リクエストのみ、以後は生成されたスタティックなページが使われるのでCGIの起動もデータベースへのアクセスもない。
残りタスク
もちろんこれで完成ではない。「再構築」の代わりに「全消去」のプログラムが必要になる。ただMTのプラグインとか書いたことのある方ならこの処理は簡単なことがわかるだろう。
全消去が出来たらとりあえず運用は可能だけど、「ページをビルドするコストは最初に見た人に支払ってもらう」どころじゃなくてこのままじゃGoogleが全再構築してしまうので、あといくつかの工夫とチューニングが必要。
絶対にやっておきたいのはクライアント・キャッシュを有効に使う方法。
更新されていないページへGoogleが2回目以降のアクセスにやってきたらステータス304を適切に返すこと。
あとは、Permalinkからエントリーを特定するのが非効率的なので別途Permalinkとentry_idを紐付けるようなデータベーステーブルを作っておけば処理も速くなるでしょう。
その他にも再構築の範囲や全消去する時にどこまでを対象とするかを検討したり(このあたりはまさにサイトの内容とポリシーによって最適解を検討していけば良いと思う)。
WordPressだMTだってのは「ダイナミックだスタティックだ」ってな議論とは別の部分で行うべき。逆にWordPressでもこのような考え方をすればスタティックなファイル生成も割と簡単に実現できるんじゃないだろうか。
以上、Movable Type30分Cookingのコーナーでした(エントリー書くのに15分かかった...)
続きあります。
- 静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(続き)。
- 静的生成と動的生成, Webページをビルドするコストは最初の訪問者に支払ってもらいましょう(さらに続き)。