ブラウザの一時停止アニメーションを防ぐための html5 WebWorkers サンプル コード共有

黄舟
リリース: 2017-03-20 16:10:30
オリジナル
1692 人が閲覧しました

Web 開発中、ブラウザがイベントに応答せず、アニメーションが一時停止した状態になったり、「スクリプトの実行時間が長すぎます」というプロンプト ボックスが表示されたりすることがよくあります。これが発生した場合は、スクリプトが正常に動作していないことを意味します。制御不能。

ブラウザには少なくとも 3 つのスレッドがあります: js エンジン スレッド (js の処理)、GUI レンダリング スレッド (ページのレンダリング)、ブラウザ イベント トリガー スレッド (対話の制御)。

1: JavaScript エンジン は、イベント駆動型の シングルスレッド 実行に基づいています。JS エンジンは、タスクキュー内のタスクの到着を待ってから、それらを処理します。ブラウザーでは、1 つの JS スレッドのみが実行されます。いつでも JS プログラムを実行できます。

2: GUI レンダリング スレッドは、ブラウザ インターフェイスのレンダリングを担当します。インターフェイスを再描画 (再描画) する必要がある場合、または何らかの操作によってリフローが発生した場合、このスレッドが実行されます。ただし、GUI レンダリング スレッドと JS エンジンは相互に排他的であることに注意してください。JS エンジンが実行されると、GUI スレッドは一時停止され、GUI の更新はキューに保存され、JS エンジンが実行されるとすぐに実行されます。アイドル。

3: イベントトリガースレッド。イベントがトリガーされると、スレッドは保留キューの最後にイベントを追加し、JS エンジンによる処理を待ちます。これらのイベントは、setTimeOut などの JavaScript エンジンによって現在実行されているコード ブロック、またはマウス クリック、AJAX 非同期リクエストなどのブラウザ カーネル内の他のスレッドから発生する可能性があります。ただし、JS のシングルスレッド関係により、すべてのイベントが発生します。これらのイベントは、JS エンジンによる処理のためにキューに入れられる必要があります。

ブラウザのカーネル処理方法を理解すれば、ブラウザが一時停止アニメーション状態になる理由を理解するのは難しくありません。JS スクリプトが長時間プロセッサを占有すると、ブラウザの GUI の更新が一時停止され、その後のイベント応答が中断されます。キュー内のキューもブロックされるため、ブラウザが一時停止アニメーション状態にロックされます。さらに、DOM 操作は JS スクリプトで実行されるため、JS 呼び出しが完了すると、次のタスクを開始する直前に GUI レンダリングが実行されます。そのため、JS での DOM 操作が多数発生すると、イベントの応答が遅くなる場合があります。 IE6 で一度に大量の HTML を挿入するなど、ブラウザをフリーズします。 「スクリプトの実行時間が長すぎます」というプロンプト ボックスが表示された場合は、JS スクリプトに無限ループが含まれているか、深すぎる再帰操作を実行する必要があることを意味します。

このような状況に遭遇した場合、コードを最適化するだけでなく、それ以上のことを行うことができます。HTML5 webWorkers は、複雑で時間のかかる純粋な js ロジック処理をブラウザーのバックグラウンド スレッドに配置できるようにする js バックグラウンド処理スレッド API を提供します。 js スレッドが UI スレッドのレンダリングをブロックしないようにします。このスレッドは、要素やアラートの取得など、ページと対話することはできません。同じ方法で複数のスレッド間でデータを転送することもできます。

コードを直接見てみましょう:

例: ユーザーが数値を入力し、加算 (+=) を実行します

以前のアプローチ:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>webworkers--calculate</title>
</head>
<body>
    <input id="num" name="num" type="text"/>
    <button onclick = "calculate()">计算</button><br />
    <div id="result" style="color:red;"></div>
    <div id="time" style="color:red;"></div>
    <script type="text/javascript" src="calculate.js"></script>
    <script type="text/javascript">
        function calculate(){
            data1 = new Date().getTime();
            var num = document.getElementById("num").value;
            var val = parseInt(num,10);
            var result =0;
            for(var i =0; i<num;i++){
                result += i;
            }
            data2 = new Date().getTime();
            document.getElementById("result").innerHTML ="计算结果:"+result;
            document.getElementById("time").innerHTML ="普通 耗时:"+ (data2 - data1)+"ms";
        }
    </script>
</body>
</html>
ログイン後にコピー

webWorkers を使用した後:

Calculate.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>webworkers--calculate</title>
</head>
<body>
    <input id="num" name="num" type="text"/>
    <button onclick = "calculate()">计算</button><br />
    <div id="result" style="color:red;"></div>
    <div id="time" style="color:red;"></div>
    <script type="text/javascript" src="calculate.js"></script>
    <script type="text/javascript">
        var worker = new Worker("calculate.js");
        var data1 =0;
        var data2 =0;
        worker.onmessage = function(event){
                var data = event.data;
                data2 = new Date().getTime();
                document.getElementById("result").innerHTML ="计算结果:"+data;
                document.getElementById("time").innerHTML ="workers 耗时:"+ (data2 - data1)+"ms";
            };
         function calculate(){
            data1 = new Date().getTime();
            var num = document.getElementById("num").value;
            var val = parseInt(num,10);
            worker.postMessage(val);
        }
    </script>
</body>
</html>
ログイン後にコピー

Calculate.js

onmessage = function(event){
    var num = event.data;
    var result = 0;
    for(var i = 0; i<num;i++){
        result += i;
    }
    postMessage(result);
};
ログイン後にコピー

webWorker コードを Web サーバーに入れる必要があります。localhost を使用している場合は、Chrome ブラウザの上位バージョンを使用してください。Firefox ブラウザが localhost を処理すると、「ドメインを取得できませんでした!」というエラーが表示されます。 」と表示されます

上記2つの実装方法を比較すると、計算値が100億に達すると、通常の方法では時間がかかり、通常は行き詰まってしまいます。

Chrome15 での webWorkers の効果。 訂正: getTime() は秒 (s) ではなくミリ秒 (ms) を返す必要があります。

Chrome 15 での通常のメソッドの効果

今後の Web アプリケーションでは、WebWorkers が依然として非常に価値があることがわかります。

以上がブラウザの一時停止アニメーションを防ぐための html5 WebWorkers サンプル コード共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート