vulcanizeでPolymer Web Componentsの初期ロードを速くする


この記事はPolymer Advent Calendar 22日目の記事です。

まず、、Polymerのアドベントカレンダー全然人気ないw

まさかの22日目にして初めの一稿です。

なぜでしょう?半年前に登場した時は結構注目を浴びていた気がしたのですが。。Web Componentsの思想は世界的にも支持されているとは思いますが、polyfillであるpolymerは時期尚早だったのでしょうか。

個人的な意見ですが、多分対応ブラウザの問題とか学習コストが地味に多いとかもありますが、やっぱりpolyfillの実装のせいで若干遅かったりコンポーネントのロードが遅かったり等パフォーマンスに関する不安がPolymerがいまいち世間で採用されていない理由の大きい要素なのかなと思います。実践投入を考えるとパフォーマンスは非常に重要ですからねぇ。

だた、もしパフォーマンスが改善されれば、そこそこ実践で使う方も増えてくるのではないでしょうか?

ちなみに余談ですが、現在preview段階のv0.8.0ではpolymer自体のファイルサイズが87%減するらしいです。(不思議なくらいの激減w)

参考: Polymer v0.8.0 Preview 所感
http://havelog.ayumusato.com/develop/webcomponents/e635-polymer_080_preview.html

さて、そんなこんなで今回はPolymerで作ったページの初期ロードパフォーマンスを劇的にアップすることができるvulcanizeというツールを紹介します。

Polymer Web ComponentsビルドツールVulcanize

Polymerで、例えばmaterial designのcore系やpaper系のUIモジュール(Web Components)を読み込んでアプリを作っていくと、コンポーネントのdependencyのチェーンによりHTMLでimportする量がどんどん増えていってしまいます。特にpaper系のコンポーネントをimportすると、気づけば1ページ表示するのに50リクエストくらい発生したりします。さすがに実践的ではないですねぇ。

vulcanize
https://github.com/Polymer/vulcanize

このツールを使うとimportを辿って複数のweb componentsを結合したファイルを作成することができます。リクエスト数が大幅に減らせるので、Polymerによる実装でも遅さを感じないアプリケーションを作ることができそうです。

ところで、vulcanizeを日本語に訳すと加硫だそうです。

以下、wikipediaより抜粋。

加硫(かりゅう)とは、架橋反応の一種で、ゴム系の原材料(生ゴムなど)を加工する際に、弾性限界を大きくするために、硫黄などを加える行程のことである。

とりあえずvulcanizeって響きがなんかカッコイイw

vulcanizeの使い方紹介

1. npmでinstall
npm install -g vulcanize

2. コマンドで実行
web componentsをimportして構成したページをindex.htmlだとすると、以下のコマンドでimport先を辿って、一つのファイルとして展開してくれます。

vulcanize index.html

デフォルトだと出力ファイル名がvulcanized.htmlになるので、変更したい場合は-oオプションで指定できます。

vulcanize -o build.html index.html

–inlineオプションについて
–inlineを付けないとbuild.htmlの中に外部スクリプトタグが残ります。

<script src="bower_components/webcomponentsjs/webcomponents.js"></script>

–inlineを付けると、各web componentsだけではなく、例えば上記のwebcomponents.js読み込み等、他のscriptもinlineで展開されるためネットワーク越しに必要なリソースは全て一つのファイルに記述されます。

その他のオプション紹介

  • –verbose, -v: 詳細ログ用
  • –help, -v, -?: helpメッセージ
  • –config: configファイルを指定
  • –strip, -s: コメントやHTMLタグ間の隙間等を消す
  • –csp: XSS対策等のためにinlineのscriptを外部ファイルに出すオプション
  • –abspath, -p: サイトルートを指定してファイルパスを絶対パスで解釈させる
  • –no-strip-excludes: importで読み込むものをinlineに展開しないようにする
  • –version, -V: versionを出力

コマンドだけでなく、node moduleとしてJSのプログラムの中で呼ぶこともできます。また、gruntとgulpのモジュールも提供されています。

grunt-vulcanize
https://github.com/Polymer/grunt-vulcanize

gulp-vulcanize
https://github.com/sindresorhus/gulp-vulcanize

vulcanizeを試してみた

自作のWeb Componentsのデモページを例にとって、実験してみました。
(※Polymerのバージョンはv0.5.2です)

demoページ
http://tejitak.github.io/left-swipe-action/demo.html

このPolymerで作った自作Web Componentsは、以前HTML5mitnuesというイベントやqiitaの「PolymerでWeb Componentsを自作してbowerで公開する」という記事にも掲載しているものです。

通常このdemoページをロードすると以下のようにimportを辿ってかなりのファイルを取得するためのリクエストが発生しています。

スクリーンショット 2014-12-19 15.32.31

このdemo.htmlに対して、vulcanizeをinlineオプションで実行してみました。

vulcanize -o demo_build.html demo.html --inline

demoページ(vulcanized版)
http://tejitak.github.io/left-swipe-action/demo_build.html

vulcanizeしたページのソースを見るといきなりwebcomponents.jsの内容が展開されているのが分かると思います。

このデモではpaperエレメント系を少し使っているので、結構リクエスト数が多かったですが、vulcanizeを–inlineオプションで指定したのでweb components関連の読み込みはわずか1つになりました。(demoサイトではsocial系のshareボタンでリクエストが発生していて比較が分かりづらかったので掲載しませんが、合計24リクエストも減りました。)

体感的にも速くなったと思います。めでたしめでたし。

以上、Polymer使って何かアプリ作って公開するときには、積極的に(必ず?)vulcanizeしましょうという記事でした。

明日のアドベントカレンダーではビルド的な話ではなく、Polymerのコンポーネントをlazy loadするパフォーマンスTipsについて紹介しようかと思います。