超できすぎくんの裏話とか
2008/09/17 にリリースされた「超できすぎくん」の裏話をご紹介してみるです。
そもそも「超できすぎくん」とは、ザックリ言ってしまえば CMS なわけです。
弊社とご提携して頂いているサムライファクトリー様の Ninja Tools の一部機能であるホームページスペースに、システムで生成した HTML をアップロードする機能になります。
で、アップロードする HTML を構築する際の流れが以下のような感じ。
- 商品単位に設定画面でパーツを追加・削除して大まかなレイアウトを決定する。
- そのパーツ毎に設定出来る項目が決まっており、テキストを変更したり、文字色・背景色を設定したり、商品画像を選んだりする。
- 確認画面では、ほぼ実際にアップロードされるレイアウトでプレビュー表示される。
- 同様にしてトップページ (index.html) も設定する。
- 最後に「アップロードする」的なボタンを押すと Ninja Tools に対してアップロードを行う。
実にシンプルですね(?)。
んで、その設定画面では JavaScript をガッツリ使って実装されてるわけです。
ライブラリはお約束の Prototype.js と Script.aculo.us を使ってるわけです。
そのときの苦労話とかをちょっくら書いてみる。
まぁ、苦労って言っても基本的にはライブラリが素敵だから、大した苦労はしてません。
が、まぁ、Windows な Internet Explorer が結構 アホの 素敵な 子で、ちょっとその辺で苦労してたわけです。
ウェブ開発をやったことあるエンジニアさんなら分かるかとは思いますが、IE は XPath を実装していません。
他の大手ブラウザ (Firefox, Safari, Opera) あたりはレンダリングエンジンが違い、ちゃんと XPath を実装しております。
で、XPath が無いと何がキツいかってーと、任意の要素を取得する際に、凄く重いんですね。
ってことで、ちょっと比較を交えて書いてみる。
まずは、ページ内で一意な要素 (id 属性が付いている) を取得する場合は、以下のような感じ。
<div id="foo"> ... </div>
// Prototype.js var foo = $('foo');
と、ダラー関数を使って取得します。
これは document.all とか document.getElementById とかを呼んでるっぽいので軽い。
でも、問題となるのは XPath 的な引き方 (正確に言うと XPath ではなくて CSS のセレクタなんだけど) をする場合。
<p class="foo" rel="bar">hoge</p>
var foo_bar = $$('p.foo[rel="bar"]');
と、ダブルダラー関数を使って取得します。(まぁ、Element.select() ってのもアリですが。)
これの内部実装に於いて、Mozilla とかのブラウザに関してはセレクタを XPath に変換して取得してます。
が、IE の場合は XPath を実装していないので document.getElementsByTagName とか使って全要素を取得したあとに、セレクタに一致するような要素をひたすら検索してるっぽいです。
まぁ、そりゃぁ重いよね。一回調べた要素はキャッシュしてるみたいですが、それでもメモリは食うしループがイッパイ発生することには変わりないわけです。
で、話を本題に戻すと、「超できすぎくん」の苦労話ってのが、そこに帰着するわけで。
私は開発環境が Mac なのでテスト段階までは Firefox とか Safari とかで開発をしています。
んで、最後にレイアウト崩れとか JavaScript のエラーが無いかとかを調べる際に Parallels Desktop 経由で Windows 立ち上げて Internet Explorer を起動するわけです。
「超できすぎくん」に関しても同じように開発してました。
Firefox で開発してる分にはサクサク動くので、サクサク開発も進み、最後に IE でチェックする段になって「うおっ!重っっっ!!!」ってなったわけです。
結構メモリを割り当ててるにも関わらず、IE 用にカスタマイズする前の段階ではページを開くのに軽く 20 秒は掛かってました。
結局、リリースまでの開発工数のうち 3 割くらいは IE 向けの高速化改修に持って行かれたのが実際のところだったりするわけです。
ま、最初から IE で開発すりゃええやんって話なんですけどね…。