アセットサイズの縮小

DOMを操作するよりも更に遅い処理があるとしたら、それはサーバからのデータの取得だけでしょう。遅いネットワーク回線にあるモバイル端末においては更に深刻です。Html.LazyHtml.Keyedによる最適化が常に有効なのは確かですが、もし読み込みが遅いのならアプリケーションは遅いままだと感じられるはずです!

これを改善する良い方法は、送信するデータをもっと少なくすることです。たとえば、122キロバイトのアセット(サーバからブラウザに送られるファイル)を9キロバイトにすることができれば、読み込みはずっと早くなります! 次のような手法を使うことで、そのような結果を得ることができます。

  • コンパイル。 Elmコンパイラは、デッドコード除去やレコードフィールドの名前変更のような、パフォーマンス最適化を実施することができます。つまり、生成されたコードの使われていないコードを取り除いたり、userStatusのようなレコードフィールド名を短くしたりすることができます。
  • ミニファイ。 JavaScriptの世界には、いろいろな変換を行う『ミニファイア』(minifiers)と呼ばれるツールがあります。これは、変数名を短くしたり、インライン化をしたり、if文を3項演算子へと置き換えたり、'\u0041''A' に置き換えたりします。いずれもデータ量を削減するためです!
  • 圧縮。 デッドコード除去やミニファイによってコードを可能な限り小さくしたら、そのあとgzipのようなアルゴリズムを使うことでコードを更に圧縮することができます。それ自身を単純に取り除くことが難しいfunctionreturnのような予約語に対して特に有効です。

Elmではこれらの最適化をプロジェクトに対してとても簡単に設定することができます。複雑なビルドシステムは必要ありません。たったふたつのターミナルコマンドだけでできるのです!

最適化のやりかた

最初のステップは、--optimize フラグを付けてコンパイルすることです。これはレコードフィールドの名前を短くするようなことを行います。

次のステップは、出力されたJavaScriptコードをミニファイすることです。私はuglifyjsというミニファイアを使っていますが、別のあなたが好きなものを使っても構いません。uglifyjsのいいところは、その特別なフラグにあります。そのようなフラグを付けると、通常のJSコードに対して実施しても正しく動くかわからない高度な最適化が有効になりますが、Elmのデザインのお陰でこれらの最適化はまったく安全です!

これらを合わせると、src/Main.elmを次のようなふたつのターミナルコマンドで最適化することができます。

elm make src/Main.elm --optimize --output=elm.js
uglifyjs elm.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output=elm.min.js

コマンドの実行が完了すると、elm.jsとそれがもっと小さくなったelm.min.jsファイルのふたつが生成されるでしょう!

Note 1: uglifyjs は、最初の--compressとふたつめの--mangleの2回呼び出されます。これは必要なことです! さもなければ、uglifyjspure_funcsフラグを無視してしまいます。

Note 2: もしuglifyjsコマンドがターミナルで使えない場合は、npm install uglify-js --globalを実行してuglifyjsをダウンロードしてください。もしnpmもないようであれば、nodejsから入手してください。

スクリプト

あのようなuglifyjsのフラグをみんな覚えるのは大変ですので、おそらくそれを実行するスクリプトを書いたほうがいいでしょう。

elm.jselm.min.jsファイルを生成するbashスクリプトが欲しい場合もあると思います。MacかLinuxなら、optimize.shを次のように定義すればいいでしょう。

#!/bin/sh

set -e

js="elm.js"
min="elm.min.js"

elm make --optimize --output=$js $@

uglifyjs $js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output=$min

echo "Compiled size:$(cat $js | wc -c) bytes  ($js)"
echo "Minified size:$(cat $min | wc -c) bytes  ($min)"
echo "Gzipped size: $(cat $min | gzip -c | wc -c) bytes"

これで、もしTodoMVCのプロジェクト上で./optimize.sh src/Main.elmを実行すれば、次のようなものがターミナルに出力されるのを見ることができるでしょう。

Compiled size:  122297 bytes  (elm.js)
Minified size:   24123 bytes  (elm.min.js)
Gzipped size:     9148 bytes

なかなかいいですね! このプログラムをユーザに渡すときは、たった9キロバイトほどを送るだけでいいのです!

このelmuglifyjsはどのプラットフォームでも動く重要なコマンドですので、同じようなことをWindowsで行うのはとても大変というほどでもありません。

アドバイス

これまで見てきたように、Browser.applicationを使い、単一のJavaScriptファイルへとコンパイルするのを書くのをお勧めします。そのJavaScriptファイルは、ユーザがページを最初に訪れたときにダウンロード(とキャッシュ)されるでしょう。JavaScriptを生成する他の有名なプログラミング言語と比較しても、Elmはずっと小さなファイルを作成しますので、ここで見ていただいたように、この戦略に従えばよりいっそう良い結果を得られるでしょう。

Note: 理論的には、Elmでこれよりもさらに小さなアセットにすることも可能です。これは現段階では不可能なのですが、もしあなたがElmで5万行以上のコードを書いているなら、ユーザの使用状況の調査のひとつとして、あなたの状況を教えていただけたらと思います。くわしくはこちらをご覧ください!

results matching ""

    No results matching ""