nested iframes: postMessage vs YUI vs Parent

Benchmark created by Marcel Duran on


Description

Compares performance of nested iframes communication using postMessage, YUI sandboxing (no postMessage) and direct access to parent. The test consists of 100 nested iframes, performing message passing starting from the innermost iframe to the outermost one, then again starting from inner iframe #50, #10, #5 and #2 to outermost one.

See test page

Preparation HTML

<script>
  var i, iframe, idoc,
      doc = document,
      body = doc.body,
      numIFrames = 100,
      writeMessage = function (e) {
        var data = parseInt(e.data, 10);
        document.getElementById('msg').innerHTML = data;
        data += 1;
        parent.postMessage(data, '*'); 
      },
      getIframe = function (n) {
        var idoc,
            iframe = doc.getElementsByTagName('iframe')[0];
        for (i = 0; i < n; i += 1) {
          idoc = iframe.contentWindow.document;
          iframe = idoc.getElementsByTagName('iframe')[0];
        }
        return iframe.contentWindow;
      };

  iframe = doc.createElement('iframe');
  body.appendChild(iframe);
  for (i = 0; i < numIFrames; i += 1) {
    idoc = iframe.contentWindow.document;
    idoc.open().write(
      '<!doctype html>' +
      '<html>' +
      '  <head>' +
      '    <script>' +
      '      window.addEventListener("message", ' +
               writeMessage.toString() +
      '      , false);' +
      '    <\/script>' +
      '  </head>' +
      '  <body>' + 
      '    <div id="msg"></div>' + 
           (i < numIFrames - 1? '<iframe></iframe>' : '') +
      '    <script src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js"><\/script>' +
      '    <script>' +
      '      YUI({' +
      '        win: window.parent, ' +
      '        doc: window.parent.document' +
      '      }).use(function (Y) {' +
      '        YUI.Env.msg = function (m) {' +
      '          document.getElementById("msg").innerHTML = m;' +
      '          if (Y.config.win.YUI) Y.config.win.YUI.Env.msg(m + 1);' +
      '        };' +
      '      });' +
      '    <\/script>' +
      '    <script>' +
      '      window._msg = function (m) {' +
      '        document.getElementById("msg").innerHTML = m;' +
      '        if (window.parent._msg) window.parent._msg(m + 1);' +
      '      };' +
      '    <\/script>' +
      '  </body>' +
      '</html>'
    );
    idoc.close();
    if (i < numIFrames - 1) {
      iframe = idoc.getElementsByTagName('iframe')[0];
    }
  }
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
100 postMessage
var start = 99;
getIframe(start).postMessage(numIFrames - start - 1, '*');
 
ready
100 YUI
var start = 99;
getIframe(start).YUI.Env.msg(numIFrames - start - 1);
 
ready
100 parent
var start = 99;
getIframe(start)._msg(numIFrames - start - 1);
ready
50 postMessage
var start = 49;
getIframe(start).postMessage(numIFrames - start - 1, '*');
 
ready
50 YUI
var start = 49;
getIframe(start).YUI.Env.msg(numIFrames - start - 1);
 
ready
50 parent
var start = 49;
getIframe(start)._msg(numIFrames - start - 1);
ready
10 postMessage
var start = 9;
getIframe(start).postMessage(numIFrames - start - 1, '*');
 
ready
10 YUI
var start = 9;
getIframe(start).YUI.Env.msg(numIFrames - start - 1);
 
ready
10 parent
var start = 9;
getIframe(start)._msg(numIFrames - start - 1);
ready
5 postMessage
var start = 4;
getIframe(start).postMessage(numIFrames - start - 1, '*');
 
ready
5 YUI
var start = 4;
getIframe(start).YUI.Env.msg(numIFrames - start - 1);
 
ready
5 parent
var start = 4;
getIframe(start)._msg(numIFrames - start - 1);
ready
2 postMessage
var start = 1;
getIframe(start).postMessage(numIFrames - start - 1, '*');
ready
2 YUI
var start = 1;
getIframe(start).YUI.Env.msg(numIFrames - start - 1);
 
ready
2 parent
var start = 1;
getIframe(start)._msg(numIFrames - start - 1);
 
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.

  • Revision 1: published by Marcel Duran on