// The port for communicating back to the extension.
var benchmarkExtensionPort = chrome.extension.connect();

// The url is what this page is known to the benchmark as.
// The benchmark uses this id to differentiate the benchmark's
// results from random pages being browsed.

// TODO(mbelshe): If the page redirects, the location changed and the
// benchmark stalls.
var benchmarkExtensionUrl = window.location.toString();

function sendTimesToExtension() {
  var times = window.chrome.loadTimes();

  if (times.finishLoadTime != 0) {
    benchmarkExtensionPort.postMessage({message: "load", url: benchmarkExtensionUrl, values: times});
  } else {
    window.setTimeout(sendTimesToExtension, 100);
  }
}

function loadComplete() {
  // Only trigger for top-level frames (e.g. the one we benchmarked)
  if (window.parent == window) {
    sendTimesToExtension();
  }
}

window.addEventListener("load", loadComplete);

@@ -459,47 +459,189 @@
 %7B%0A  
-var times = window.chrome.loadTimes();%0A
+if (window.parent != window) %7B%0A    return;%0A  %7D%0A%0A  var times = window.chrome.loadTimes();%0A%0A  // If the load is not finished yet, schedule a timer to check again in a%0A  // little bit.
 %0A  i
@@ -846,214 +846,153 @@
 %0A%7D%0A%0A
-functi
+// We can't use the 
 on
- 
 load
-Complete() %7B%0A  // Only trigger for top-level frames (e.g. the one we ben
+ event because this script runs at document idle,%0A// whi
 ch
+ 
 ma
-rked)%0A  if (window.parent == window) %7B%0A    sendTimesToExtension();%0A  %7D%0A%7D%0A%0Awindow.addEventListener(%22load%22, loadComplete
+y run after the onload has completed.%0AsendTimesToExtension(
 );%0A

Update the benchmark to use the document.readyState to measure page-completedness rather than the onload event. Extensions were moved from the pre-onload state to running at document idle some time ago.