1

メインの html ドキュメントの JavaScript コードは、ブラウザーによってブロックされない限り、iframe のコードとデータにアクセスできます。しかし、パフォーマンスはどうですか?iframe の境界を越えてパフォーマンスが低下することはありますか?

簡単なテストを行ったところ、ブラウザに依存することがわかりました。

  • chrome 28: メイン ドキュメントから iframe 内の関数を呼び出すことは、メイン ドキュメント内の関数を呼び出すのと同じくらい高速です。
  • firefox 23: iframe での関数の呼び出しが大幅に遅くなります (~6x)。
  • IE 11 プレビュー: iframe での関数の呼び出しはかなり遅くなりますが (~3.5x)、Firefox よりは優れています。

これらの違いの原因を知りたいですか?メイン ドキュメントと iframe のコードは同じ JavaScript VM で実行されますか?

近い将来、firefox と IE によってこれらのパフォーマンスの低下が軽減されるか、さらには解消されると期待できますか?

私のテストコードは次のとおりです。

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Calc in iframe</title>
</head>
<body>
    <button onclick="testCalcIFrame()">testCalcIFrame</button>
    <button onclick="testCalc()">testCalc</button>
    <button onclick="iwin.testCalcAllIframe()">testCalcAllIframe</button>
    <iframe id="iframe" style="display:none;"></iframe>
    <script>
        var iwin = document.getElementById('iframe').contentWindow;
        iwin.document.open('text/html');
        iwin.document.close();        

        //Copy functions calc() and testCalcAllIframe() into the iframe.
        iwin.eval(calc.toString());
        iwin.eval(testCalcAllIframe.toString());

        var icalc = iwin.calc;

        var arrLength = 1000 * 1000;

        var arr = new Array(arrLength);
        for (var i = 0; i < arrLength; i++)
            arr[i] = i;

        function calc() {
            var n = 0;
            for (var i = 0; i < 2; i++) {
                n += Math.round(arguments[i] / 3);
            }
            return n;
        }

        //test calling calc() in the main document
        function testCalc() {
            var t1 = performance.now();
            var r = arr.reduce(calc);
            console.log('testCalc(' + arr.length + '):time:' + (performance.now() - t1) + ', result:' + r);
        }

        //test calling calc() in the iframe
        function testCalcIFrame() {
            var t1 = performance.now();
            var r = arr.reduce(icalc);
            console.log('testCalcIFrame(' + arr.length + '):time:' + (performance.now() - t1) + ', result:' + r);
        }

        function testCalcAllIframe() {
            var arr2 = new Array(1000 * 1000);
            for (var i = 0; i < arr2.length; i++)
                arr2[i] = i;

            var t1 = performance.now();
            var r = arr2.reduce(calc);
            console.log('testCalcAllIframe(' + arr2.length + '):time:' + (performance.now() - t1) + ', result:' + r);
        }

    </script>
</body>
</html>

テスト コードを試すには、ブラウザで開発者ツールのコンソールを開き、「testCalcIFrame」を押して iframe 内の関数の呼び出しをテストし、「testCalc」を押してメイン ドキュメント内の関数の呼び出しをテストします。

更新: Jan Dvorak が提案したように、eval() を使用する代わりに iframe にスクリプト要素を挿入しようとしました:

//iwin.eval(...) replaced by:
var iscript = iwin.document.createElement('script');
iwin.document.body.appendChild(iscript);
iscript.textContent = calc.toString() + '\n' + testCalcAllIframe.toString();

ただし、パフォーマンスは eval() を使用した場合とほぼ同じです。

4

0 に答える 0