Page D

The following content represents a basic overview of this page's script structure and [intended] execution flow. When a particular script is mentioned below, it is linked to the "debug" version, as a convenient reference, but the page actually uses the minified versions when available. For a better (more reliable?) explanation of this page's loading behavior, re-run the results.  ==>

1.  Load init-d.js

init-d.js is hard-coded in the page's <head> section. This is the only hard-coded <script> element in this document; the other scripts are dynamically appended to the <head>.

        <meta charset="utf-8" />
        <title>Page D</title>
        <link type="text/css" rel="stylesheet" href="css/style.css" />
        <script type="text/javascript" src="js/init-d.js"></script>

2.  Execute init-d.js

init-d.js is just like init-c.js.

    (function() {

        // Define configuration object for require.js
        require = {

            // ...

            // callback: undefined

            // deps: undefined

            shim: {
                'sammy': {
                    deps: ['jquery'],
                    exports: 'Sammy'


        // Define a function that will execute on page load
        var lazyFunction = function() {
            var s = document.createElement('script');
            s.type = 'text/javascript';
            s.src = 'lib/require/require.js';
            s.setAttribute('data-main', 'app/main-d');

        window.onload = function() {


3.  Load & Execute require.js

4.  Load main-d.js and Begin App

The main difference between this page and the others is that this page uses modified copies of Durandal's router plugin (router2.js) and shell (shell2.js & shell2.html. The modifications are intended to make the sample application load its default route without changing the URL (e.g., by appending a hash 'n' slash). In other words, on pages A, B, and C, the sample app is coded such that all routes depend on a URL hash ( #/ ). So for example, page-a.html automatically changes to page-a.html#/, and `#/` triggers the default route. In contrast, Page D is coded such that page-d.html alone (i.e., without a hash) triggers the default route.

This distinction seems to make a huge difference in how's waterfall graphs are rendered. Specifically, only Page D's waterfalls look as you'd expect: with a few HTTP requests before the Document Complete line, and everything else (i.e., the sample app's modules) loading after it.

Yet to be whether this difference is due to browsers behaving differently or calculating the Document Complete event differently.

Update: See related discussion on WPT forum:

Single-page App Won't Lazy-load When Hash Fragment is Present