【HTML】【JavaScript】JavaScript ファイル読み込み中のプログレスバーを作る

 Babel 等で複数の JavaScript ファイル、特に React, Vue.js の様な巨大なライブラリをまとめて一つの JavaScript ファイルにバンドルし、それを HTML ファイル上で読み込むことが多々あります。この読み込み中の時、マウント用の Element を用意してある HTML ファイルが本当にマウント用の Element 以外見た目が何もない場合、ユーザはそれなりの時間真っ白な画面を見ることになります。これを防ぐにはいくつか方法があります(例えばサーバサイドレンダリング)。この記事では簡単なスクリプトと HTML コードでJavaScript ファイル読み込みのプログレスバーを表示する方法を示します。
 実装は次です。

<body>
<div id="app">
    <!-- React等のマウント先要素内部にプログレス用の要素を置くことでローディング完了後の掃除の手間を省けます -->
    ロード中です<div id='progress-msg'>0%</div>
    <!-- progress 要素で簡単にプログレスバーを用意できます。 -->
    <!-- @see https://developer.mozilla.org/ja/docs/Web/HTML/Element/progress -->
    <progress id="progress" max="100" value="0"></progress>
</div>
<script>
const jsScriptUrl = '読み込み先JavaScript ファイルの URL';
// プログレスを示すための要素の指定を用意
const progressEl = document.querySelector('#progress')
const progressMsgEl = document.querySelector('#progress-msg')
/** プログレスが変化する度に画面に反映させる関数 */
const updateProgressEvent = function(event){
    // event は XMLHttpRequest の progress_event です
    // @see https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/progress_event

    // total は 送られてくるコンテンツの長さがわかる時、それが入ります。
    // web サーバ内での gzip 化設定などが原因で total = 0 の場合がままあります。
    // そういった時、 0 割りで異常動作になるのを防ぎます
    if(event.total){
        // loaded には読み込み済みのコンテンツの長さが入ります。これでどこまで読み込んだかの割合がわかります
        progressEl.value = (event.loaded / event.total);
        // 100 かける、と toFixed メソッドで見やすいパーセンテージを表記します
        progressMsgEl.innerText = `${((event.loaded / event.total) * 100).toFixed(2)}%`
    }
}
// JavaScript ファイル読み込みの XHR です
// ajax, axios を使わないのは ajax, axios の読み込み待ちの時間がもったいないからです。
// そういった意味では XHR 同様にブラウザ組み込みの fetch が XHR の代役に向いています。
// fetch のストリーム関連が上手く操れれば XHR より良いかもしれません。
// @see https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
const request = new XMLHttpRequest();
request.onprogress=updateProgressEvent;// ↑のプログレス表記、更新イベントをセット
request.open('GET', jsScriptUrl, true);// リクエストを初期化
request.onreadystatechange = function () {
    // 状態が 4 == DONE になったならば読み込んだ内容を script タグにセット
    // @see https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest/readyState
    if (request.readyState == 4) {
        // script タグとして HTML に追加
        const scriptEl = document.createElement('script');
        scriptEl.textContent = request.response;
        document.head.appendChild(scriptEl);

        // プログレスが動かなかった時の保険
        progressEl.value = 100;
        progressMsgEl.innerText = `100%`

        // JavaScript 読み込み後の待ち時間の説明
        progressEl.remove()
        progressMsgEl.innerText = `React 構築中`
    }
};
request.send();// リクエストを送信
</script>
</body>

 こんな感じのちょっとしたスクリプトで次の様に JavaScript ファイル読み込み中のプログレスバーを作れます。また readyState== 4 になった後の処理を工夫して JavaScritp ファイル以外にも応用できます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG