2011-12-29

文字コードを意識すべし

現在のWebブラウザというのは、いろんな外部コンポーネントも使って作ってるわけなんだけど、例えば、HTMLを解析しながら文字コードを変換なんてしてたら複雑になりすぎてバグを増やすきっかけになってしまう。HTMLパーサーに渡される時点で特定の文字コードで渡すようになってる。そのため、文字コード変換はオープンソースだったらlibicuのようなものを利用したりする (WebKitは現にlibicu使ってる) し、プロプラであっても、Internet ExplorerのようにブラウザじゃなくてOSのコンポーネント(MLANG.DLL)を使ってたりする。ちなみにMozillaではuconvと呼ばれるライブラリを自分たちでメンテナンスしてる。

また、現在のWebブラウザというのは内部的にはUTF-16またはUTF-8を使ってる場合がほとんどなので、コンテンツ(HTML/CSS/JS)が別の文字コードである場合にはそれを変換して読み込むわけなんだ。なので、出来る限りコンテンツに使う文字コードってのは、意識すべきなんだよね。

また、現在の主流のCPU(X86とARM)の場合の例で考えると、7ビットのASCII文字からUTF-16への変換はいちいち while(*a) u = (uint16_t)*a++; なんてコードを書くまでもなくもっと高速化可能になってる。X86の場合は、SSE2 or SSSE3を使ってSIMDでシャッフル演算すれば、一度にASCII8文字をUTF-16の8文字に変換できるし、ARMの場合はNEONを使うことで、同じように8文字のナロー・ワイド変換が可能なんだ。そのため、us-asciiやUTF-8からUTF-16への変換の場合は、このような最適化コードを使ってる可能性がある (現にFirefoxでは使ってる)。もちろんus-asciiやUTF-8の場合で7ビット文字じゃないものを含む場合は、そのパスを使わずに従来通りの変換を行ってるけどね。

us-ascii以外でもやってるかというと、やらないことがほとんどというかやらない。そういう文字コードの場合は文字変換テーブルを利用して文字を変換したりする必要があるから、あえてそんなところに複雑なコードパスを作ることはないだろう。だって、その文字コードはとある言語では必要かもしれないけど、全体として少数派になってしまうからね。

だから、@charset "euc-jp"なんて書いたCSSがあったとすると、Webブラウザ的にはeuc-jp用の文字コード変換コードが実行されるんだけど、おそらくテーブルを使った変換を行うので、そのCSSが7ビットASCIIだけで書かれていたとしても、速度的なことは期待できない。

なので、コメント書く必要がないようなCSSとかJSとかだったら、文字コードをus-asciiとかutf-8とかにして、コンテンツは7ビットASCIIのみを使った方がより速く文字コード変換が行われるかもよってこと。速度を意識する必要がないのであれば別に構わないけどさ。