link rel="import" によるロードはやはりちょっと時間がかかる。Polymer の場合どうしてもインポート数が増えるのでなんとかしたい。

もちろん vulcanize すれば import 自体は解決するが、created/attached まわりの処理もチリも積もればという感じで、なかなか時間がかかるので、根本的解決にならない。

特に appmanifest によってスタンドアロンアプリ表示させている場合、ロードまでの間完全に真っ白の画面になり、プログレスバーも出ないのでかなり残念なことになる。

ということで、一旦ローディング画面を挟みたい。

問題点:first paint がなかなか発生しない

HTML Imports はポリフィルされていない場合ブロックする (Chrome にしかネイティブ実装されてないから Chrome だけ)。インポート先がインポートしている場合再帰的にインポートするので、依存全部インポートが終わるまで表示が完全にブロックし、head内でインポートしていると画面描画が全く走らない。

Chrome の場合 first paint が走るまで現在表示中の内容を消さないので、リロードした場合特に「全く操作はできないのに表示はされている」状態になって気持ちが悪い。

なので、まずはインポートなしの状態ないし、最低限必要なものだけをインポートしてから、ロード画面を表示する。

ローディングプログレスがとれない

link要素のloadイベントでひとつのインポートの完了はわかるが、再帰的な全てのリクエストのプログレスをとることができない。

どうしようもない?ぽいので、intermidate なローディングプログレス表示するしかない。

CSS でアニメーションさせるのが現状では一番マシっぽい。

コード

		<div class='loading'></div>
		<my-app></my-app>
		<script>
			requestAnimationFrame(function () {
				var link = document.createElement('link');
				link.rel = "import";
				link.href = "src/app.html"; // my-app の定義
				link.addEventListener('load', function () {
					var loading = document.querySelector('.loading');
					loading.parentNode.removeChild(loading);
				});
				document.body.appendChild(link);
			});
		</script>

link rel="import" は作って挿入してもちゃんと動いてくれるのでこれで良い。polyfill もちゃんと動いててうまく動く。

load イベントは再帰的なロードが全部終わってから発火するようになっている。

将来性

HTTP2 化してもカスタムエレメントの初期化処理はなくならないので、大量のカスタムエレメントを使う場合なんらかのローディング表示が必要ではないかという気がする。

appmanifest によるスタンドアロンアプリ化ではコンテナ(ブラウザ)側でそのうちちゃんとローディング出せるようになりそう。

  1. トップ
  2. tech
  3. webcomponentsjs/Polymer、HTML Imports が終わるまでの間ローディングを出したい。
▲ この日のエントリ