ITも大抵筋肉でなんとかなる

気が向いたら技術的なことも書くかもしれないですが、技術的なこと=ITとは限りません。

Webサイト更新しました

メトロイド100%クリア version 1.2.xへ更新

これです。 www.geocities.jp 更新内容は下記です。

  • 全ページの読み込み速度改善
  • ページ内リンクの整備
  • トップへ戻るボタンの実装
  • お問い合わせフォームの不具合修正
  • 全体のレイアウト調整
  • その他不具合修正

コンテンツの内容的なお話

特に何か増えたってわけじゃないんですが、ページの読み込み速度を向上させてより快適に攻略を閲覧できるようにしました。攻略チャートは画像をふんだんに使っている影響で読み込みに1秒ほどかかっていますが、それ以外のページでは読み込み処理が分からないほど高速化できたと思います。チャートに関しても読み込み速度はかなり早くなったと思います。
あとはトップへ戻るボタンを実装したので、一番下までスクロールしてから上に戻るときに少し戻りやすくなったかなと。ただし広告が被るんであれなんですけどね…。ボスとかマップに関してもリンククリックしたらスクロールしてくれます。コンテンツ的なアップデートは以上ですかね。
お問い合わせフォームの不具合はしれっと直しておきました。バグってたの気づかなかったヨ。

技術的な話

高速化するに当たり、下記を実施しました。

  1. プリコンパイラの実装
  2. Handlebars.jsの導入
  3. js・cssの結合・minify
  4. できるだけDOMContentLoadedを使う

1.プリコンパイラの実装

ホームページを公開するに当たり、ジオシティーズというYahooのサービスを使っていますが、これは基本静的ファイルしか扱えません(課金すればPHPPerlCGIで動かせるみたいです。DBもSQLiteとかつかえた気がする)。なのでサーバサイドでHTMLを構築して返すというのはできないんですね。そうするとこんな問題があります。

1.HTMLの管理が煩雑になる

2.SEO的に不利な部分がでてくる

3.更新がめんどくさい

1.と3.は、いわゆるDRY原則が守れなくなることで発生する問題ですね。
2.はDRY原則を守ろうとするとこうなるって感じです。
1.は、サーバサイドでHTMLを構築できないせいで「ほとんど同じ構造で一部だけ違うHTMLファイルが量産される」という事態になるんですね。ディレクトリで表示ファイルを変えるわけですから(当然URLのエイリアスとかも使えない)、ディレクトリにファイルを配置しないといけないわけです。HTMLはほとんど同じ記述がすべてのファイルに入ることが多く(共通的に読み込むCSSやJSなど)、これを全ファイルに入れ込まないといけない。面倒ですね。
2.の話ですが、DRY原則を守ろうとすると、ディレクトリに配置するHTMLはガワだけおいておき(ガワが被ってる時点でDRYじゃないんですけどね)、JavaScriptで中身を当て込むという風になると思います。そうなってくると、当然Descriptionタグの中身を書き換えたりTitleを書き換えたりって話になります。そうすると、ロボットの認識的にちゃんと中身を拾ってくれるかどうか怪しいわけです。最近のロボットはJavaScript実行後のページを拾う、みたいな話をどっかで読みましたが少なくとも私が作ったやつは作りの問題なのか、そうはなりませんでした。JavaScriptで作ったDescriptionが読み込まれなかったということですね。titleとかh1も死んでました。となると、この辺は手作業でぺちぺちHTMLを編集することになります。面倒ですね。
3.は1.と2.の結果めんどくさいっていうアレです。もう少しビジネスライクな表現にすると「運用負荷が高い」とでも言いましょうか。ちょっと直すにも全ファイルを直さないといけないというなんとも修行みたいなことを強いられる羽目になるので、めんどくさいという表現を用いましたね。

これらの問題を解決するには、HTMLとHTMLに当てるデータを切り離して、デプロイ前にHTMLとデータをバインドするみたいな機構が必要だなーとか思っていて、「それってテンプレートエンジンっぽくね?」ってことでなんかそれっぽいアレを作りました。
残念ながら変数・定数・メソッドしか使えない(ループとif文は使えない)んですけどね。あとデータもDB使えないんでJSON読み込みまっせっていう仕様です。この辺の話は後日。

2.Handlebars.jsの導入

プリコンパイルしたところで、それって自動でHTMLファイルを事前に作りますよの話なので、それだけだと足りないんですよね。例えば更新履歴をトップページと更新履歴ページの両方に表示したいってなった時にどうすんねんって話があったりとか。あと顕著なのは、攻略チャートですかね。あれってHTMLは完全に1ファイルにしてあるんですね。なのでチャート1もチャート2も同じファイルなわけです。どうなってるかというと、getパラメータをJavaScriptで参照して、当該のチャートリソース(JavaScriptオブジェクトとして記述)を読み込んで画面を構築しているんですけど、そういうことはプリコンパイラでは不可能なんですよね。 なんでそんな面倒なことをしているかっていうと、チャートのページでは構造が大体決まっていて、

  1. ルートマップ
  2. 説明
  3. 説明に使う画像

ってな構造になっているんですけど、この辺のHTMLを書きたくなかったって言う理由ですね。同じ構造の繰り返しなのに同じように毎ページ毎ページHTML書くのはエンジニアとしてはナンセンスだなーーーと思ったので。ちなみに「画像1」みたいなのをクリックすると画像が表示されたり、ボスやアイテム名がリンクになっているのもJavaScriptでやってます。 こういうことがあって、一部描画はJavaScriptでやらざるを得ないなーということで、元々はテキストファイルにHTMLを切り出してAjaxで読み込んでいました。なんですけど想像以上に切り出すHTMLが増えたせいでページ読み込みのボトルネックなっちゃんたんですよね。しかもコード量も多くなるし。っていうので、テンプレートエンジンないかなーーーていう理由でHandlebars.jsにしました。採用理由はまた別途記事にします。

3.js・cssのminify

これは言わずもがなですよね。minifyしてファイルサイズを抑えてロードを短くしようっていうアレです。結合も似たような話で、何回も問い合わせに行くより一回の問い合わせでJS全部取ってこようキャンペーンって話です。JS取ってこないと画面の描画できないのでこの辺は地味に効果あった気がします。

4.できるだけDOMContentLoadedを使う

DOMが読み込まれる前に「var hoge = document.getElementById('hoge');」みたいなことすると「見つかんないよ!」って怒られますよね。なので大抵の場合下記のようにすると思います。

window.onload = function() {
    var hoge = document.getElementById('hoge');
};

ところがこれ、全部のリソースが読み込まれるまで待っちゃうので、ジオシティーズの場合 広告の読み込みも待ってしまう んですよね。ツール使って調べると広告の描画が一番のボトルネックになってしまっていたということがあり(2番目がGoogleからのフォント読み込み)、広告の読み込みは待ちたくなかったんですよね。ということで、すべてのリソースではなくHTMLのDOM読み込みが終了した時点で発火する「DOMContentLoaded」をできるだけ使うようにしました。こんな感じで。

window.addEventLitener('DOMContentLoaded', function() {
   var hoge = document.getElementById('hoge');
}, false);

こうしたおかげで広告の表示を待たずに画面表示を行なえるようになったので描画速度が圧倒的に向上しました。トップページの表示速度とか意味わからないぐらい改善できましたね。ちなみに第2のボトルネックだったGoogleからのWebフォント読み込みはあえてloadイベント発火時にやってます。フォント読み込み時間かかるので、うっかりloadイベントに登録したりするとそれ以降の描画が遅くなってしまうので。

やってみて

今回やってみてわかったことは、おとなしく最初からテンプレートエンジン使えって話でした。
あとこれは当たり前なんですけどやっぱりRDB使えた方が楽ですね。