Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Prefetching #9818

Merged
merged 9 commits into from
Dec 24, 2019
Merged

Optimize Prefetching #9818

merged 9 commits into from
Dec 24, 2019

Conversation

Timer
Copy link
Member

@Timer Timer commented Dec 23, 2019

This pull request optimizes our page loader's prefetching by changing the following:

  • Uses prefetch instead of preload when available (so resource loads as low-priority). This lessens CPU load during hydration.
  • A smaller data saver detection snippet was copied from quicklink
  • Fallback-<script> preloading loading was removed as it was for backwards compat, which is now covered by wider-supported prefetch
  • Other code golfing techniques to reduce footprint

Contrary to an assumption we were operating on (IIRC), preload does not preparse the script. In fact, prefetch should actually have better caching characteristics (forces storage in disk cache instead of in-memory, meaning less data transferred on n+1 visit).

Only <link rel="modulepreload"> (Chrome + ESModules only) parses a script prior to execution.

@Timer Timer added this to the 9.1.x milestone Dec 23, 2019
@ijjk
Copy link
Member

ijjk commented Dec 23, 2019

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.2s 13.1s -121ms
nodeModulesSize 48.7 MB 48.7 MB -12.2 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Rendered Page Sizes
zeit/next.js canary Timer/next.js preload Change
index.html 4.06 kB 4.06 kB
index.html gzip 1.04 kB 1.04 kB -1 B
link.html 4.11 kB 4.11 kB
link.html gzip 1.04 kB 1.04 kB
withRouter.html 4.12 kB 4.12 kB
withRouter.html gzip 1.03 kB 1.03 kB
Overall change 12.3 kB 12.3 kB

Diffs

Diff for main-HASH.js
@@ -437,7 +437,7 @@ if (!window.Promise) {
 
 var data = JSON.parse(document.getElementById('__NEXT_DATA__').textContent);
 window.__NEXT_DATA__ = data;
-var version = "9.1.7-canary.3";
+var version = "9.1.7-canary.2";
 exports.version = version;
 var props = data.props,
     err = data.err,
@@ -1390,32 +1390,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1476,7 +1472,7 @@ function () {
   }, {
     key: "loadPageScript",
     value: function loadPageScript(route) {
-      var _this3 = this;
+      var _this2 = this;
 
       route = this.normalizeRoute(route);
       return new _promise["default"](function (resolve, reject) {
@@ -1485,9 +1481,9 @@ function () {
               page = _ref.page,
               mod = _ref.mod;
 
-          _this3.pageRegisterEvents.off(route, fire);
+          _this2.pageRegisterEvents.off(route, fire);
 
-          delete _this3.loadingRoutes[route];
+          delete _this2.loadingRoutes[route];
 
           if (error) {
             reject(error);
@@ -1500,7 +1496,7 @@ function () {
         }; // If there's a cached version of the page, let's use it.
 
 
-        var cachedPage = _this3.pageCache[route];
+        var cachedPage = _this2.pageCache[route];
 
         if (cachedPage) {
           var error = cachedPage.error,
@@ -1514,7 +1510,7 @@ function () {
         } // Register a listener to get the page
 
 
-        _this3.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
+        _this2.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
         // rather downloading it again.
 
 
@@ -1522,22 +1518,22 @@ function () {
           return;
         }
 
-        if (!_this3.loadingRoutes[route]) {
+        if (!_this2.loadingRoutes[route]) {
           if (true) {
-            _this3.getDependencies(route).then(function (deps) {
+            _this2.getDependencies(route).then(function (deps) {
               deps.forEach(function (d) {
                 if (/\.js$/.test(d) && !document.querySelector("script[src^=\"" + d + "\"]")) {
-                  _this3.loadScript(d, route, false);
+                  _this2.loadScript(d, route, false);
                 }
 
                 if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                  loadStyle(d); // FIXME: handle failure
+                  appendLink(d, 'stylesheet'); // FIXME: handle failure
                 }
               });
 
-              _this3.loadRoute(route);
+              _this2.loadRoute(route);
 
-              _this3.loadingRoutes[route] = true;
+              _this2.loadingRoutes[route] = true;
             });
           } else {}
         }
@@ -1573,11 +1569,11 @@ function () {
   }, {
     key: "loadScript",
     value: function loadScript(url, route, isPage) {
-      var _this4 = this;
+      var _this3 = this;
 
       var script = document.createElement('script');
 
-      if ( true && 'noModule' in script) {
+      if ( true && hasNoModule) {
         script.type = 'module'; // Only page bundle scripts need to have .module added to url,
         // dependencies already have it added during build manifest creation
 
@@ -1591,7 +1587,7 @@ function () {
         var error = new Error("Error loading script " + url);
         error.code = 'PAGE_LOAD_ERROR';
 
-        _this4.pageRegisterEvents.emit(route, {
+        _this3.pageRegisterEvents.emit(route, {
           error: error
         });
       };
@@ -1602,7 +1598,7 @@ function () {
   }, {
     key: "registerPage",
     value: function registerPage(route, regFn) {
-      var _this5 = this;
+      var _this4 = this;
 
       var register = function register() {
         try {
@@ -1611,15 +1607,15 @@ function () {
             page: mod["default"] || mod,
             mod: mod
           };
-          _this5.pageCache[route] = pageData;
+          _this4.pageCache[route] = pageData;
 
-          _this5.pageRegisterEvents.emit(route, pageData);
+          _this4.pageRegisterEvents.emit(route, pageData);
         } catch (error) {
-          _this5.pageCache[route] = {
+          _this4.pageCache[route] = {
             error: error
           };
 
-          _this5.pageRegisterEvents.emit(route, {
+          _this4.pageRegisterEvents.emit(route, {
             error: error
           });
         }
@@ -1632,108 +1628,46 @@ function () {
   }, {
     key: "prefetch",
     value: function prefetch(route, isDependency) {
-      var _this2 = this;
-
-      return (0, _asyncToGenerator2["default"])(
-      /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee2() {
-        var scriptRoute, url, cn;
-        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                route = _this2.normalizeRoute(route);
-                scriptRoute = (route === '/' ? '/index' : route) + ".js";
-
-                if ( true && 'noModule' in document.createElement('script')) {
-                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-                }
-
-                url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]"))) {
-                  _context2.next = 6;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 6:
-                _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
-
-                if (!(cn = navigator.connection)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 10:
-                if (!( true && !isDependency)) {
-                  _context2.next = 16;
-                  break;
-                }
-
-                ;
-                _context2.next = 14;
-                return _this2.getDependencies(route);
-
-              case 14:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
+      var _this5 = this;
 
-                _context2.sent.forEach(_context2.t0);
+      // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+      // License: Apache 2.0
+      var cn;
 
-              case 16:
-                if (!hasPreload) {
-                  _context2.next = 19;
-                  break;
-                }
+      if (cn = navigator.connection) {
+        // Don't prefetch if using 2G or if Save-Data is enabled.
+        if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+      }
 
-                preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-                return _context2.abrupt("return");
+      var url = this.assetPrefix;
 
-              case 19:
-                if (!isDependency) {
-                  _context2.next = 21;
-                  break;
-                }
+      if (isDependency) {
+        url += route;
+      } else {
+        route = this.normalizeRoute(route);
+        this.prefetched[route] = true;
+        var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-                return _context2.abrupt("return");
+        if ( true && hasNoModule) {
+          scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+        }
 
-              case 21:
-                if (!(document.readyState === 'complete')) {
-                  _context2.next = 25;
-                  break;
-                }
+        url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+      }
 
-                return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
+      if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+        return;
+      }
 
-              case 25:
-                return _context2.abrupt("return", new _promise["default"](function (resolve) {
-                  window.addEventListener('load', function () {
-                    _this2.loadPage(route).then(function () {
-                      return resolve();
-                    }, function () {
-                      return resolve();
-                    });
-                  });
-                }));
+      appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-              case 26:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2);
-      }))();
+      if ( true && !isDependency) {
+        this.getDependencies(route).then(function (urls) {
+          return urls.forEach(function (url) {
+            _this5.prefetch(url, true);
+          });
+        });
+      }
     }
   }]);
Diff for main-HASH.module.js
@@ -341,7 +341,7 @@ if (!window.Promise) {
 
 var data = JSON.parse(document.getElementById('__NEXT_DATA__').textContent);
 window.__NEXT_DATA__ = data;
-var version = "9.1.7-canary.3";
+var version = "9.1.7-canary.2";
 exports.version = version;
 var {
   props,
@@ -1081,32 +1081,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1206,7 +1202,7 @@ class PageLoader {
               }
 
               if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                loadStyle(d); // FIXME: handle failure
+                appendLink(d, 'stylesheet'); // FIXME: handle failure
               }
             });
             this.loadRoute(route);
@@ -1232,7 +1228,7 @@ class PageLoader {
   loadScript(url, route, isPage) {
     var script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
+    if ( true && hasNoModule) {
       script.type = 'module'; // Only page bundle scripts need to have .module added to url,
       // dependencies already have it added during build manifest creation
 
@@ -1280,65 +1276,42 @@ class PageLoader {
   }
 
   prefetch(route, isDependency) {
-    var _this2 = this;
-
-    return (0, _asyncToGenerator2.default)(function* () {
-      route = _this2.normalizeRoute(route);
-      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
+    // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+    // License: Apache 2.0
+    var cn;
 
-      if ( true && 'noModule' in document.createElement('script')) {
-        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-      }
-
-      var url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
-        return;
-      }
+    if (cn = navigator.connection) {
+      // Don't prefetch if using 2G or if Save-Data is enabled.
+      if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+    }
 
-      _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+    var url = this.assetPrefix;
 
-      var cn;
+    if (isDependency) {
+      url += route;
+    } else {
+      route = this.normalizeRoute(route);
+      this.prefetched[route] = true;
+      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-      if (cn = navigator.connection) {
-        // Don't prefetch if the user is on 2G or if Save-Data is enabled.
-        if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
-          return;
-        }
+      if ( true && hasNoModule) {
+        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
       }
 
-      if ( true && !isDependency) {
-        ;
-        (yield _this2.getDependencies(route)).forEach(url => {
-          _this2.prefetch(url, true);
-        });
-      } // Feature detection is used to see if preload is supported
-      // If not fall back to loading script tags before the page is loaded
-      // https://caniuse.com/#feat=link-rel-preload
+      url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+    }
 
+    if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+      return;
+    }
 
-      if (hasPreload) {
-        preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-        return;
-      }
+    appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-      if (isDependency) {
-        // loadPage will automatically handle dependencies, so no need to
-        // preload them manually
-        return;
-      }
-
-      if (document.readyState === 'complete') {
-        return _this2.loadPage(route).catch(() => {});
-      } else {
-        return new _promise.default(resolve => {
-          window.addEventListener('load', () => {
-            _this2.loadPage(route).then(() => resolve(), () => resolve());
-          });
-        });
-      }
-    })();
+    if ( true && !isDependency) {
+      this.getDependencies(route).then(urls => urls.forEach(url => {
+        this.prefetch(url, true);
+      }));
+    }
   }
 
 }
Diff for index.html
@@ -12,7 +12,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/framework.9c9aa574c484a7d0240e.module.js"
         as="script" crossorigin="anonymous" />
@@ -44,9 +44,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/chunks/framework.4c64484d8a631a55b435.js"
         async="" crossorigin="anonymous" nomodule=""></script>
Diff for link.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -61,9 +61,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>
Diff for withRouter.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -59,9 +59,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>

Serverless Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.6s 13.3s -340ms
nodeModulesSize 48.7 MB 48.7 MB -12.2 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Serverless bundles Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
_error.js 299 kB 281 kB -17.8 kB
_error.js gzip 78.8 kB 74.8 kB -4 kB
hooks.html 4.19 kB 4.19 kB
hooks.html gzip 1.07 kB 1.07 kB
index.js 299 kB 281 kB -17.2 kB
index.js gzip 79.1 kB 75.1 kB -3.97 kB
link.js 306 kB 289 kB -17.2 kB
link.js gzip 81.1 kB 77.2 kB -3.96 kB
routerDirect.js 299 kB 282 kB -17.2 kB
routerDirect.js gzip 79.1 kB 75.2 kB -3.93 kB
withRouter.js 299 kB 282 kB -17.2 kB
withRouter.js gzip 79.3 kB 75.3 kB -3.97 kB
Overall change 1.51 MB 1.42 MB -86.7 kB

Commit: d5349b5

@ijjk
Copy link
Member

ijjk commented Dec 24, 2019

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.3s 13.1s -212ms
nodeModulesSize 48.7 MB 48.7 MB -12.2 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Rendered Page Sizes
zeit/next.js canary Timer/next.js preload Change
index.html 4.06 kB 4.06 kB
index.html gzip 1.04 kB 1.04 kB -1 B
link.html 4.11 kB 4.11 kB
link.html gzip 1.04 kB 1.04 kB
withRouter.html 4.12 kB 4.12 kB
withRouter.html gzip 1.03 kB 1.03 kB
Overall change 12.3 kB 12.3 kB

Diffs

Diff for main-HASH.js
@@ -437,7 +437,7 @@ if (!window.Promise) {
 
 var data = JSON.parse(document.getElementById('__NEXT_DATA__').textContent);
 window.__NEXT_DATA__ = data;
-var version = "9.1.7-canary.3";
+var version = "9.1.7-canary.2";
 exports.version = version;
 var props = data.props,
     err = data.err,
@@ -1390,32 +1390,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1476,7 +1472,7 @@ function () {
   }, {
     key: "loadPageScript",
     value: function loadPageScript(route) {
-      var _this3 = this;
+      var _this2 = this;
 
       route = this.normalizeRoute(route);
       return new _promise["default"](function (resolve, reject) {
@@ -1485,9 +1481,9 @@ function () {
               page = _ref.page,
               mod = _ref.mod;
 
-          _this3.pageRegisterEvents.off(route, fire);
+          _this2.pageRegisterEvents.off(route, fire);
 
-          delete _this3.loadingRoutes[route];
+          delete _this2.loadingRoutes[route];
 
           if (error) {
             reject(error);
@@ -1500,7 +1496,7 @@ function () {
         }; // If there's a cached version of the page, let's use it.
 
 
-        var cachedPage = _this3.pageCache[route];
+        var cachedPage = _this2.pageCache[route];
 
         if (cachedPage) {
           var error = cachedPage.error,
@@ -1514,7 +1510,7 @@ function () {
         } // Register a listener to get the page
 
 
-        _this3.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
+        _this2.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
         // rather downloading it again.
 
 
@@ -1522,22 +1518,22 @@ function () {
           return;
         }
 
-        if (!_this3.loadingRoutes[route]) {
+        if (!_this2.loadingRoutes[route]) {
           if (true) {
-            _this3.getDependencies(route).then(function (deps) {
+            _this2.getDependencies(route).then(function (deps) {
               deps.forEach(function (d) {
                 if (/\.js$/.test(d) && !document.querySelector("script[src^=\"" + d + "\"]")) {
-                  _this3.loadScript(d, route, false);
+                  _this2.loadScript(d, route, false);
                 }
 
                 if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                  loadStyle(d); // FIXME: handle failure
+                  appendLink(d, 'stylesheet'); // FIXME: handle failure
                 }
               });
 
-              _this3.loadRoute(route);
+              _this2.loadRoute(route);
 
-              _this3.loadingRoutes[route] = true;
+              _this2.loadingRoutes[route] = true;
             });
           } else {}
         }
@@ -1573,11 +1569,11 @@ function () {
   }, {
     key: "loadScript",
     value: function loadScript(url, route, isPage) {
-      var _this4 = this;
+      var _this3 = this;
 
       var script = document.createElement('script');
 
-      if ( true && 'noModule' in script) {
+      if ( true && hasNoModule) {
         script.type = 'module'; // Only page bundle scripts need to have .module added to url,
         // dependencies already have it added during build manifest creation
 
@@ -1591,7 +1587,7 @@ function () {
         var error = new Error("Error loading script " + url);
         error.code = 'PAGE_LOAD_ERROR';
 
-        _this4.pageRegisterEvents.emit(route, {
+        _this3.pageRegisterEvents.emit(route, {
           error: error
         });
       };
@@ -1602,7 +1598,7 @@ function () {
   }, {
     key: "registerPage",
     value: function registerPage(route, regFn) {
-      var _this5 = this;
+      var _this4 = this;
 
       var register = function register() {
         try {
@@ -1611,15 +1607,15 @@ function () {
             page: mod["default"] || mod,
             mod: mod
           };
-          _this5.pageCache[route] = pageData;
+          _this4.pageCache[route] = pageData;
 
-          _this5.pageRegisterEvents.emit(route, pageData);
+          _this4.pageRegisterEvents.emit(route, pageData);
         } catch (error) {
-          _this5.pageCache[route] = {
+          _this4.pageCache[route] = {
             error: error
           };
 
-          _this5.pageRegisterEvents.emit(route, {
+          _this4.pageRegisterEvents.emit(route, {
             error: error
           });
         }
@@ -1632,108 +1628,46 @@ function () {
   }, {
     key: "prefetch",
     value: function prefetch(route, isDependency) {
-      var _this2 = this;
-
-      return (0, _asyncToGenerator2["default"])(
-      /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee2() {
-        var scriptRoute, url, cn;
-        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                route = _this2.normalizeRoute(route);
-                scriptRoute = (route === '/' ? '/index' : route) + ".js";
-
-                if ( true && 'noModule' in document.createElement('script')) {
-                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-                }
-
-                url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]"))) {
-                  _context2.next = 6;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 6:
-                _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
-
-                if (!(cn = navigator.connection)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 10:
-                if (!( true && !isDependency)) {
-                  _context2.next = 16;
-                  break;
-                }
-
-                ;
-                _context2.next = 14;
-                return _this2.getDependencies(route);
-
-              case 14:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
+      var _this5 = this;
 
-                _context2.sent.forEach(_context2.t0);
+      // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+      // License: Apache 2.0
+      var cn;
 
-              case 16:
-                if (!hasPreload) {
-                  _context2.next = 19;
-                  break;
-                }
+      if (cn = navigator.connection) {
+        // Don't prefetch if using 2G or if Save-Data is enabled.
+        if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+      }
 
-                preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-                return _context2.abrupt("return");
+      var url = this.assetPrefix;
 
-              case 19:
-                if (!isDependency) {
-                  _context2.next = 21;
-                  break;
-                }
+      if (isDependency) {
+        url += route;
+      } else {
+        route = this.normalizeRoute(route);
+        this.prefetched[route] = true;
+        var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-                return _context2.abrupt("return");
+        if ( true && hasNoModule) {
+          scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+        }
 
-              case 21:
-                if (!(document.readyState === 'complete')) {
-                  _context2.next = 25;
-                  break;
-                }
+        url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+      }
 
-                return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
+      if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+        return;
+      }
 
-              case 25:
-                return _context2.abrupt("return", new _promise["default"](function (resolve) {
-                  window.addEventListener('load', function () {
-                    _this2.loadPage(route).then(function () {
-                      return resolve();
-                    }, function () {
-                      return resolve();
-                    });
-                  });
-                }));
+      appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-              case 26:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2);
-      }))();
+      if ( true && !isDependency) {
+        this.getDependencies(route).then(function (urls) {
+          return urls.forEach(function (url) {
+            _this5.prefetch(url, true);
+          });
+        });
+      }
     }
   }]);
Diff for main-HASH.module.js
@@ -341,7 +341,7 @@ if (!window.Promise) {
 
 var data = JSON.parse(document.getElementById('__NEXT_DATA__').textContent);
 window.__NEXT_DATA__ = data;
-var version = "9.1.7-canary.3";
+var version = "9.1.7-canary.2";
 exports.version = version;
 var {
   props,
@@ -1081,32 +1081,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1206,7 +1202,7 @@ class PageLoader {
               }
 
               if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                loadStyle(d); // FIXME: handle failure
+                appendLink(d, 'stylesheet'); // FIXME: handle failure
               }
             });
             this.loadRoute(route);
@@ -1232,7 +1228,7 @@ class PageLoader {
   loadScript(url, route, isPage) {
     var script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
+    if ( true && hasNoModule) {
       script.type = 'module'; // Only page bundle scripts need to have .module added to url,
       // dependencies already have it added during build manifest creation
 
@@ -1280,65 +1276,42 @@ class PageLoader {
   }
 
   prefetch(route, isDependency) {
-    var _this2 = this;
-
-    return (0, _asyncToGenerator2.default)(function* () {
-      route = _this2.normalizeRoute(route);
-      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
+    // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+    // License: Apache 2.0
+    var cn;
 
-      if ( true && 'noModule' in document.createElement('script')) {
-        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-      }
-
-      var url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
-        return;
-      }
+    if (cn = navigator.connection) {
+      // Don't prefetch if using 2G or if Save-Data is enabled.
+      if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+    }
 
-      _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+    var url = this.assetPrefix;
 
-      var cn;
+    if (isDependency) {
+      url += route;
+    } else {
+      route = this.normalizeRoute(route);
+      this.prefetched[route] = true;
+      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-      if (cn = navigator.connection) {
-        // Don't prefetch if the user is on 2G or if Save-Data is enabled.
-        if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
-          return;
-        }
+      if ( true && hasNoModule) {
+        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
       }
 
-      if ( true && !isDependency) {
-        ;
-        (yield _this2.getDependencies(route)).forEach(url => {
-          _this2.prefetch(url, true);
-        });
-      } // Feature detection is used to see if preload is supported
-      // If not fall back to loading script tags before the page is loaded
-      // https://caniuse.com/#feat=link-rel-preload
+      url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+    }
 
+    if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+      return;
+    }
 
-      if (hasPreload) {
-        preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-        return;
-      }
+    appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-      if (isDependency) {
-        // loadPage will automatically handle dependencies, so no need to
-        // preload them manually
-        return;
-      }
-
-      if (document.readyState === 'complete') {
-        return _this2.loadPage(route).catch(() => {});
-      } else {
-        return new _promise.default(resolve => {
-          window.addEventListener('load', () => {
-            _this2.loadPage(route).then(() => resolve(), () => resolve());
-          });
-        });
-      }
-    })();
+    if ( true && !isDependency) {
+      this.getDependencies(route).then(urls => urls.forEach(url => {
+        this.prefetch(url, true);
+      }));
+    }
   }
 
 }
Diff for index.html
@@ -12,7 +12,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/framework.9c9aa574c484a7d0240e.module.js"
         as="script" crossorigin="anonymous" />
@@ -44,9 +44,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/chunks/framework.4c64484d8a631a55b435.js"
         async="" crossorigin="anonymous" nomodule=""></script>
Diff for link.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -61,9 +61,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>
Diff for withRouter.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -59,9 +59,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>

Serverless Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.6s 13.4s -215ms
nodeModulesSize 48.7 MB 48.7 MB -12.2 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Serverless bundles Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
_error.js 299 kB 281 kB -17.8 kB
_error.js gzip 78.8 kB 74.8 kB -4 kB
hooks.html 4.19 kB 4.19 kB
hooks.html gzip 1.07 kB 1.07 kB
index.js 299 kB 281 kB -17.2 kB
index.js gzip 79.1 kB 75.1 kB -3.97 kB
link.js 306 kB 289 kB -17.2 kB
link.js gzip 81.1 kB 77.2 kB -3.96 kB
routerDirect.js 299 kB 282 kB -17.2 kB
routerDirect.js gzip 79.1 kB 75.2 kB -3.93 kB
withRouter.js 299 kB 282 kB -17.2 kB
withRouter.js gzip 79.3 kB 75.3 kB -3.97 kB
Overall change 1.51 MB 1.42 MB -86.7 kB

Commit: 7f02403

@ijjk
Copy link
Member

ijjk commented Dec 24, 2019

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.4s 13.1s -253ms
nodeModulesSize 48.7 MB 48.7 MB -12.2 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Rendered Page Sizes
zeit/next.js canary Timer/next.js preload Change
index.html 4.06 kB 4.06 kB
index.html gzip 1.04 kB 1.04 kB -1 B
link.html 4.11 kB 4.11 kB
link.html gzip 1.04 kB 1.04 kB
withRouter.html 4.12 kB 4.12 kB
withRouter.html gzip 1.03 kB 1.03 kB
Overall change 12.3 kB 12.3 kB

Diffs

Diff for main-HASH.js
@@ -437,7 +437,7 @@ if (!window.Promise) {
 
 var data = JSON.parse(document.getElementById('__NEXT_DATA__').textContent);
 window.__NEXT_DATA__ = data;
-var version = "9.1.7-canary.3";
+var version = "9.1.7-canary.2";
 exports.version = version;
 var props = data.props,
     err = data.err,
@@ -1390,32 +1390,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1476,7 +1472,7 @@ function () {
   }, {
     key: "loadPageScript",
     value: function loadPageScript(route) {
-      var _this3 = this;
+      var _this2 = this;
 
       route = this.normalizeRoute(route);
       return new _promise["default"](function (resolve, reject) {
@@ -1485,9 +1481,9 @@ function () {
               page = _ref.page,
               mod = _ref.mod;
 
-          _this3.pageRegisterEvents.off(route, fire);
+          _this2.pageRegisterEvents.off(route, fire);
 
-          delete _this3.loadingRoutes[route];
+          delete _this2.loadingRoutes[route];
 
           if (error) {
             reject(error);
@@ -1500,7 +1496,7 @@ function () {
         }; // If there's a cached version of the page, let's use it.
 
 
-        var cachedPage = _this3.pageCache[route];
+        var cachedPage = _this2.pageCache[route];
 
         if (cachedPage) {
           var error = cachedPage.error,
@@ -1514,7 +1510,7 @@ function () {
         } // Register a listener to get the page
 
 
-        _this3.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
+        _this2.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
         // rather downloading it again.
 
 
@@ -1522,22 +1518,22 @@ function () {
           return;
         }
 
-        if (!_this3.loadingRoutes[route]) {
+        if (!_this2.loadingRoutes[route]) {
           if (true) {
-            _this3.getDependencies(route).then(function (deps) {
+            _this2.getDependencies(route).then(function (deps) {
               deps.forEach(function (d) {
                 if (/\.js$/.test(d) && !document.querySelector("script[src^=\"" + d + "\"]")) {
-                  _this3.loadScript(d, route, false);
+                  _this2.loadScript(d, route, false);
                 }
 
                 if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                  loadStyle(d); // FIXME: handle failure
+                  appendLink(d, 'stylesheet'); // FIXME: handle failure
                 }
               });
 
-              _this3.loadRoute(route);
+              _this2.loadRoute(route);
 
-              _this3.loadingRoutes[route] = true;
+              _this2.loadingRoutes[route] = true;
             });
           } else {}
         }
@@ -1573,11 +1569,11 @@ function () {
   }, {
     key: "loadScript",
     value: function loadScript(url, route, isPage) {
-      var _this4 = this;
+      var _this3 = this;
 
       var script = document.createElement('script');
 
-      if ( true && 'noModule' in script) {
+      if ( true && hasNoModule) {
         script.type = 'module'; // Only page bundle scripts need to have .module added to url,
         // dependencies already have it added during build manifest creation
 
@@ -1591,7 +1587,7 @@ function () {
         var error = new Error("Error loading script " + url);
         error.code = 'PAGE_LOAD_ERROR';
 
-        _this4.pageRegisterEvents.emit(route, {
+        _this3.pageRegisterEvents.emit(route, {
           error: error
         });
       };
@@ -1602,7 +1598,7 @@ function () {
   }, {
     key: "registerPage",
     value: function registerPage(route, regFn) {
-      var _this5 = this;
+      var _this4 = this;
 
       var register = function register() {
         try {
@@ -1611,15 +1607,15 @@ function () {
             page: mod["default"] || mod,
             mod: mod
           };
-          _this5.pageCache[route] = pageData;
+          _this4.pageCache[route] = pageData;
 
-          _this5.pageRegisterEvents.emit(route, pageData);
+          _this4.pageRegisterEvents.emit(route, pageData);
         } catch (error) {
-          _this5.pageCache[route] = {
+          _this4.pageCache[route] = {
             error: error
           };
 
-          _this5.pageRegisterEvents.emit(route, {
+          _this4.pageRegisterEvents.emit(route, {
             error: error
           });
         }
@@ -1632,108 +1628,46 @@ function () {
   }, {
     key: "prefetch",
     value: function prefetch(route, isDependency) {
-      var _this2 = this;
-
-      return (0, _asyncToGenerator2["default"])(
-      /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee2() {
-        var scriptRoute, url, cn;
-        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                route = _this2.normalizeRoute(route);
-                scriptRoute = (route === '/' ? '/index' : route) + ".js";
-
-                if ( true && 'noModule' in document.createElement('script')) {
-                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-                }
-
-                url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]"))) {
-                  _context2.next = 6;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 6:
-                _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
-
-                if (!(cn = navigator.connection)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 10:
-                if (!( true && !isDependency)) {
-                  _context2.next = 16;
-                  break;
-                }
-
-                ;
-                _context2.next = 14;
-                return _this2.getDependencies(route);
-
-              case 14:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
+      var _this5 = this;
 
-                _context2.sent.forEach(_context2.t0);
+      // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+      // License: Apache 2.0
+      var cn;
 
-              case 16:
-                if (!hasPreload) {
-                  _context2.next = 19;
-                  break;
-                }
+      if (cn = navigator.connection) {
+        // Don't prefetch if using 2G or if Save-Data is enabled.
+        if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+      }
 
-                preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-                return _context2.abrupt("return");
+      var url = this.assetPrefix;
 
-              case 19:
-                if (!isDependency) {
-                  _context2.next = 21;
-                  break;
-                }
+      if (isDependency) {
+        url += route;
+      } else {
+        route = this.normalizeRoute(route);
+        this.prefetched[route] = true;
+        var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-                return _context2.abrupt("return");
+        if ( true && hasNoModule) {
+          scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+        }
 
-              case 21:
-                if (!(document.readyState === 'complete')) {
-                  _context2.next = 25;
-                  break;
-                }
+        url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+      }
 
-                return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
+      if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+        return;
+      }
 
-              case 25:
-                return _context2.abrupt("return", new _promise["default"](function (resolve) {
-                  window.addEventListener('load', function () {
-                    _this2.loadPage(route).then(function () {
-                      return resolve();
-                    }, function () {
-                      return resolve();
-                    });
-                  });
-                }));
+      appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-              case 26:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2);
-      }))();
+      if ( true && !isDependency) {
+        this.getDependencies(route).then(function (urls) {
+          return urls.forEach(function (url) {
+            _this5.prefetch(url, true);
+          });
+        });
+      }
     }
   }]);
Diff for main-HASH.module.js
@@ -341,7 +341,7 @@ if (!window.Promise) {
 
 var data = JSON.parse(document.getElementById('__NEXT_DATA__').textContent);
 window.__NEXT_DATA__ = data;
-var version = "9.1.7-canary.3";
+var version = "9.1.7-canary.2";
 exports.version = version;
 var {
   props,
@@ -1081,32 +1081,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1206,7 +1202,7 @@ class PageLoader {
               }
 
               if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                loadStyle(d); // FIXME: handle failure
+                appendLink(d, 'stylesheet'); // FIXME: handle failure
               }
             });
             this.loadRoute(route);
@@ -1232,7 +1228,7 @@ class PageLoader {
   loadScript(url, route, isPage) {
     var script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
+    if ( true && hasNoModule) {
       script.type = 'module'; // Only page bundle scripts need to have .module added to url,
       // dependencies already have it added during build manifest creation
 
@@ -1280,65 +1276,42 @@ class PageLoader {
   }
 
   prefetch(route, isDependency) {
-    var _this2 = this;
-
-    return (0, _asyncToGenerator2.default)(function* () {
-      route = _this2.normalizeRoute(route);
-      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
+    // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+    // License: Apache 2.0
+    var cn;
 
-      if ( true && 'noModule' in document.createElement('script')) {
-        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-      }
-
-      var url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
-        return;
-      }
+    if (cn = navigator.connection) {
+      // Don't prefetch if using 2G or if Save-Data is enabled.
+      if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+    }
 
-      _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+    var url = this.assetPrefix;
 
-      var cn;
+    if (isDependency) {
+      url += route;
+    } else {
+      route = this.normalizeRoute(route);
+      this.prefetched[route] = true;
+      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-      if (cn = navigator.connection) {
-        // Don't prefetch if the user is on 2G or if Save-Data is enabled.
-        if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
-          return;
-        }
+      if ( true && hasNoModule) {
+        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
       }
 
-      if ( true && !isDependency) {
-        ;
-        (yield _this2.getDependencies(route)).forEach(url => {
-          _this2.prefetch(url, true);
-        });
-      } // Feature detection is used to see if preload is supported
-      // If not fall back to loading script tags before the page is loaded
-      // https://caniuse.com/#feat=link-rel-preload
+      url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+    }
 
+    if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+      return;
+    }
 
-      if (hasPreload) {
-        preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-        return;
-      }
+    appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-      if (isDependency) {
-        // loadPage will automatically handle dependencies, so no need to
-        // preload them manually
-        return;
-      }
-
-      if (document.readyState === 'complete') {
-        return _this2.loadPage(route).catch(() => {});
-      } else {
-        return new _promise.default(resolve => {
-          window.addEventListener('load', () => {
-            _this2.loadPage(route).then(() => resolve(), () => resolve());
-          });
-        });
-      }
-    })();
+    if ( true && !isDependency) {
+      this.getDependencies(route).then(urls => urls.forEach(url => {
+        this.prefetch(url, true);
+      }));
+    }
   }
 
 }
Diff for index.html
@@ -12,7 +12,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/framework.9c9aa574c484a7d0240e.module.js"
         as="script" crossorigin="anonymous" />
@@ -44,9 +44,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/chunks/framework.4c64484d8a631a55b435.js"
         async="" crossorigin="anonymous" nomodule=""></script>
Diff for link.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -61,9 +61,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>
Diff for withRouter.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -59,9 +59,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-61c9f5a18beee988f275.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-68ef09cab458ca1f02cf.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>

Serverless Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 14s 13.9s -78ms
nodeModulesSize 48.7 MB 48.7 MB -12.2 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Serverless bundles Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
_error.js 299 kB 281 kB -17.8 kB
_error.js gzip 78.8 kB 74.8 kB -4 kB
hooks.html 4.19 kB 4.19 kB
hooks.html gzip 1.07 kB 1.07 kB
index.js 299 kB 281 kB -17.2 kB
index.js gzip 79.1 kB 75.1 kB -3.97 kB
link.js 306 kB 289 kB -17.2 kB
link.js gzip 81.1 kB 77.2 kB -3.96 kB
routerDirect.js 299 kB 282 kB -17.2 kB
routerDirect.js gzip 79.1 kB 75.2 kB -3.93 kB
withRouter.js 299 kB 282 kB -17.2 kB
withRouter.js gzip 79.3 kB 75.3 kB -3.97 kB
Overall change 1.51 MB 1.42 MB -86.7 kB

Commit: c47e246

@ijjk
Copy link
Member

ijjk commented Dec 24, 2019

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13s 13.9s ⚠️ +879ms
nodeModulesSize 48.7 MB 48.7 MB -1.8 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Rendered Page Sizes
zeit/next.js canary Timer/next.js preload Change
index.html 4.06 kB 4.06 kB
index.html gzip 1.04 kB 1.04 kB ⚠️ +1 B
link.html 4.11 kB 4.11 kB
link.html gzip 1.04 kB 1.05 kB ⚠️ +1 B
withRouter.html 4.12 kB 4.12 kB
withRouter.html gzip 1.03 kB 1.03 kB ⚠️ +2 B
Overall change 12.3 kB 12.3 kB

Diffs

Diff for main-HASH.js
@@ -1390,32 +1390,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1476,7 +1472,7 @@ function () {
   }, {
     key: "loadPageScript",
     value: function loadPageScript(route) {
-      var _this3 = this;
+      var _this2 = this;
 
       route = this.normalizeRoute(route);
       return new _promise["default"](function (resolve, reject) {
@@ -1485,9 +1481,9 @@ function () {
               page = _ref.page,
               mod = _ref.mod;
 
-          _this3.pageRegisterEvents.off(route, fire);
+          _this2.pageRegisterEvents.off(route, fire);
 
-          delete _this3.loadingRoutes[route];
+          delete _this2.loadingRoutes[route];
 
           if (error) {
             reject(error);
@@ -1500,7 +1496,7 @@ function () {
         }; // If there's a cached version of the page, let's use it.
 
 
-        var cachedPage = _this3.pageCache[route];
+        var cachedPage = _this2.pageCache[route];
 
         if (cachedPage) {
           var error = cachedPage.error,
@@ -1514,7 +1510,7 @@ function () {
         } // Register a listener to get the page
 
 
-        _this3.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
+        _this2.pageRegisterEvents.on(route, fire); // If the page is loading via SSR, we need to wait for it
         // rather downloading it again.
 
 
@@ -1522,22 +1518,22 @@ function () {
           return;
         }
 
-        if (!_this3.loadingRoutes[route]) {
+        if (!_this2.loadingRoutes[route]) {
           if (true) {
-            _this3.getDependencies(route).then(function (deps) {
+            _this2.getDependencies(route).then(function (deps) {
               deps.forEach(function (d) {
                 if (/\.js$/.test(d) && !document.querySelector("script[src^=\"" + d + "\"]")) {
-                  _this3.loadScript(d, route, false);
+                  _this2.loadScript(d, route, false);
                 }
 
                 if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                  loadStyle(d); // FIXME: handle failure
+                  appendLink(d, 'stylesheet'); // FIXME: handle failure
                 }
               });
 
-              _this3.loadRoute(route);
+              _this2.loadRoute(route);
 
-              _this3.loadingRoutes[route] = true;
+              _this2.loadingRoutes[route] = true;
             });
           } else {}
         }
@@ -1573,11 +1569,11 @@ function () {
   }, {
     key: "loadScript",
     value: function loadScript(url, route, isPage) {
-      var _this4 = this;
+      var _this3 = this;
 
       var script = document.createElement('script');
 
-      if ( true && 'noModule' in script) {
+      if ( true && hasNoModule) {
         script.type = 'module'; // Only page bundle scripts need to have .module added to url,
         // dependencies already have it added during build manifest creation
 
@@ -1591,7 +1587,7 @@ function () {
         var error = new Error("Error loading script " + url);
         error.code = 'PAGE_LOAD_ERROR';
 
-        _this4.pageRegisterEvents.emit(route, {
+        _this3.pageRegisterEvents.emit(route, {
           error: error
         });
       };
@@ -1602,7 +1598,7 @@ function () {
   }, {
     key: "registerPage",
     value: function registerPage(route, regFn) {
-      var _this5 = this;
+      var _this4 = this;
 
       var register = function register() {
         try {
@@ -1611,15 +1607,15 @@ function () {
             page: mod["default"] || mod,
             mod: mod
           };
-          _this5.pageCache[route] = pageData;
+          _this4.pageCache[route] = pageData;
 
-          _this5.pageRegisterEvents.emit(route, pageData);
+          _this4.pageRegisterEvents.emit(route, pageData);
         } catch (error) {
-          _this5.pageCache[route] = {
+          _this4.pageCache[route] = {
             error: error
           };
 
-          _this5.pageRegisterEvents.emit(route, {
+          _this4.pageRegisterEvents.emit(route, {
             error: error
           });
         }
@@ -1632,108 +1628,46 @@ function () {
   }, {
     key: "prefetch",
     value: function prefetch(route, isDependency) {
-      var _this2 = this;
-
-      return (0, _asyncToGenerator2["default"])(
-      /*#__PURE__*/
-      _regeneratorRuntime.mark(function _callee2() {
-        var scriptRoute, url, cn;
-        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
-          while (1) {
-            switch (_context2.prev = _context2.next) {
-              case 0:
-                route = _this2.normalizeRoute(route);
-                scriptRoute = (route === '/' ? '/index' : route) + ".js";
-
-                if ( true && 'noModule' in document.createElement('script')) {
-                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-                }
-
-                url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]"))) {
-                  _context2.next = 6;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 6:
-                _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
-
-                if (!(cn = navigator.connection)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 10;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 10:
-                if (!( true && !isDependency)) {
-                  _context2.next = 16;
-                  break;
-                }
-
-                ;
-                _context2.next = 14;
-                return _this2.getDependencies(route);
-
-              case 14:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
+      var _this5 = this;
 
-                _context2.sent.forEach(_context2.t0);
+      // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+      // License: Apache 2.0
+      var cn;
 
-              case 16:
-                if (!hasPreload) {
-                  _context2.next = 19;
-                  break;
-                }
+      if (cn = navigator.connection) {
+        // Don't prefetch if using 2G or if Save-Data is enabled.
+        if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+      }
 
-                preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-                return _context2.abrupt("return");
+      var url = this.assetPrefix;
 
-              case 19:
-                if (!isDependency) {
-                  _context2.next = 21;
-                  break;
-                }
+      if (isDependency) {
+        url += route;
+      } else {
+        route = this.normalizeRoute(route);
+        this.prefetched[route] = true;
+        var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-                return _context2.abrupt("return");
+        if ( true && hasNoModule) {
+          scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+        }
 
-              case 21:
-                if (!(document.readyState === 'complete')) {
-                  _context2.next = 25;
-                  break;
-                }
+        url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+      }
 
-                return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
+      if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+        return;
+      }
 
-              case 25:
-                return _context2.abrupt("return", new _promise["default"](function (resolve) {
-                  window.addEventListener('load', function () {
-                    _this2.loadPage(route).then(function () {
-                      return resolve();
-                    }, function () {
-                      return resolve();
-                    });
-                  });
-                }));
+      appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-              case 26:
-              case "end":
-                return _context2.stop();
-            }
-          }
-        }, _callee2);
-      }))();
+      if ( true && !isDependency) {
+        this.getDependencies(route).then(function (urls) {
+          return urls.forEach(function (url) {
+            _this5.prefetch(url, true);
+          });
+        });
+      }
     }
   }]);
Diff for main-HASH.module.js
@@ -1081,32 +1081,28 @@ var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 /* global document, window */
 
 
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
   } catch (_unused) {
     return false;
   }
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
 
-function preloadLink(url, resourceType) {
+function appendLink(href, rel, as) {
   var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
   link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
+  link.href = href;
+  link.rel = rel;
+  if (as) link.as = as;
   document.head.appendChild(link);
 }
 
@@ -1206,7 +1202,7 @@ class PageLoader {
               }
 
               if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                loadStyle(d); // FIXME: handle failure
+                appendLink(d, 'stylesheet'); // FIXME: handle failure
               }
             });
             this.loadRoute(route);
@@ -1232,7 +1228,7 @@ class PageLoader {
   loadScript(url, route, isPage) {
     var script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
+    if ( true && hasNoModule) {
       script.type = 'module'; // Only page bundle scripts need to have .module added to url,
       // dependencies already have it added during build manifest creation
 
@@ -1280,65 +1276,42 @@ class PageLoader {
   }
 
   prefetch(route, isDependency) {
-    var _this2 = this;
-
-    return (0, _asyncToGenerator2.default)(function* () {
-      route = _this2.normalizeRoute(route);
-      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
+    // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+    // License: Apache 2.0
+    var cn;
 
-      if ( true && 'noModule' in document.createElement('script')) {
-        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-      }
-
-      var url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
-        return;
-      }
+    if (cn = navigator.connection) {
+      // Don't prefetch if using 2G or if Save-Data is enabled.
+      if (cn.saveData || /2g/.test(cn.effectiveType)) return;
+    }
 
-      _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
+    var url = this.assetPrefix;
 
-      var cn;
+    if (isDependency) {
+      url += route;
+    } else {
+      route = this.normalizeRoute(route);
+      this.prefetched[route] = true;
+      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-      if (cn = navigator.connection) {
-        // Don't prefetch if the user is on 2G or if Save-Data is enabled.
-        if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
-          return;
-        }
+      if ( true && hasNoModule) {
+        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
       }
 
-      if ( true && !isDependency) {
-        ;
-        (yield _this2.getDependencies(route)).forEach(url => {
-          _this2.prefetch(url, true);
-        });
-      } // Feature detection is used to see if preload is supported
-      // If not fall back to loading script tags before the page is loaded
-      // https://caniuse.com/#feat=link-rel-preload
+      url += "/_next/static/" + encodeURIComponent(this.buildId) + "/pages" + encodeURI(scriptRoute);
+    }
 
+    if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+      return;
+    }
 
-      if (hasPreload) {
-        preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-        return;
-      }
+    appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script');
 
-      if (isDependency) {
-        // loadPage will automatically handle dependencies, so no need to
-        // preload them manually
-        return;
-      }
-
-      if (document.readyState === 'complete') {
-        return _this2.loadPage(route).catch(() => {});
-      } else {
-        return new _promise.default(resolve => {
-          window.addEventListener('load', () => {
-            _this2.loadPage(route).then(() => resolve(), () => resolve());
-          });
-        });
-      }
-    })();
+    if ( true && !isDependency) {
+      this.getDependencies(route).then(urls => urls.forEach(url => {
+        this.prefetch(url, true);
+      }));
+    }
   }
 
 }
Diff for index.html
@@ -12,7 +12,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-c0e154c9c5e27167cccb.module.js"
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/framework.9c9aa574c484a7d0240e.module.js"
         as="script" crossorigin="anonymous" />
@@ -44,9 +44,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-092f6549c73c0b7a8ee7.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-c0e154c9c5e27167cccb.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/chunks/framework.4c64484d8a631a55b435.js"
         async="" crossorigin="anonymous" nomodule=""></script>
Diff for link.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-c0e154c9c5e27167cccb.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -61,9 +61,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-092f6549c73c0b7a8ee7.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-c0e154c9c5e27167cccb.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>
Diff for withRouter.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-c0e154c9c5e27167cccb.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -59,9 +59,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-092f6549c73c0b7a8ee7.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-c0e154c9c5e27167cccb.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>

Serverless Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 14.2s 13.9s -305ms
nodeModulesSize 48.7 MB 48.7 MB -1.8 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 17.7 kB -819 B
main-HASH.js gzip 6.52 kB 6.33 kB -186 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -819 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.2 kB -318 B
main-HASH.module.js gzip 5.44 kB 5.35 kB -88 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -318 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Serverless bundles
zeit/next.js canary Timer/next.js preload Change
_error.js 299 kB 299 kB
_error.js gzip 78.8 kB 78.8 kB -3 B
hooks.html 4.19 kB 4.19 kB
hooks.html gzip 1.07 kB 1.07 kB ⚠️ +2 B
index.js 299 kB 299 kB
index.js gzip 79.1 kB 79.1 kB -1 B
link.js 306 kB 306 kB
link.js gzip 81.1 kB 81.1 kB -1 B
routerDirect.js 299 kB 299 kB
routerDirect.js gzip 79.1 kB 79.1 kB -1 B
withRouter.js 299 kB 299 kB
withRouter.js gzip 79.3 kB 79.3 kB -3 B
Overall change 1.51 MB 1.51 MB

Commit: 5c2753c

@ijjk
Copy link
Member

ijjk commented Dec 24, 2019

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.3s 13.3s ⚠️ +52ms
nodeModulesSize 48.7 MB 48.7 MB -1.16 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 18.2 kB -404 B
main-HASH.js gzip 6.52 kB 6.43 kB -89 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -404 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.4 kB -174 B
main-HASH.module.js gzip 5.44 kB 5.41 kB -27 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -174 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Rendered Page Sizes
zeit/next.js canary Timer/next.js preload Change
index.html 4.06 kB 4.06 kB
index.html gzip 1.04 kB 1.04 kB -1 B
link.html 4.11 kB 4.11 kB
link.html gzip 1.04 kB 1.05 kB ⚠️ +1 B
withRouter.html 4.12 kB 4.12 kB
withRouter.html gzip 1.03 kB 1.03 kB
Overall change 12.3 kB 12.3 kB

Diffs

Diff for main-HASH.js
@@ -1387,36 +1387,32 @@ var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("+oT+"));
 var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
 var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
-/* global document, window */
 
-
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
-  } catch (_unused) {
-    return false;
-  }
-}
-
-var hasPreload = supportsPreload(document.createElement('link'));
-
-function preloadLink(url, resourceType) {
-  var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
-  link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
+  } catch (_unused) {}
 }
 
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
-  document.head.appendChild(link);
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
+
+function appendLink(href, rel, as) {
+  return new _promise["default"](function (res, rej, link) {
+    link = document.createElement('link');
+    link.crossOrigin = "anonymous";
+    link.href = href;
+    link.rel = rel;
+    if (as) link.as = as;
+    link.onload = res;
+    link.onerror = rej;
+    document.head.appendChild(link);
+  });
 }
 
 var PageLoader =
@@ -1531,7 +1527,9 @@ function () {
                 }
 
                 if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                  loadStyle(d); // FIXME: handle failure
+                  appendLink(d, 'stylesheet')["catch"](function () {// FIXME: handle failure
+                    // Right now, this is needed to prevent an unhandled rejection.
+                  });
                 }
               });
 
@@ -1577,7 +1575,7 @@ function () {
 
       var script = document.createElement('script');
 
-      if ( true && 'noModule' in script) {
+      if ( true && hasNoModule) {
         script.type = 'module'; // Only page bundle scripts need to have .module added to url,
         // dependencies already have it added during build manifest creation
 
@@ -1637,97 +1635,57 @@ function () {
       return (0, _asyncToGenerator2["default"])(
       /*#__PURE__*/
       _regeneratorRuntime.mark(function _callee2() {
-        var scriptRoute, url, cn;
+        var cn, url, scriptRoute;
         return _regeneratorRuntime.wrap(function _callee2$(_context2) {
           while (1) {
             switch (_context2.prev = _context2.next) {
               case 0:
-                route = _this2.normalizeRoute(route);
-                scriptRoute = (route === '/' ? '/index' : route) + ".js";
-
-                if ( true && 'noModule' in document.createElement('script')) {
-                  scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-                }
-
-                url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-                // its own deduping mechanism.
-
-                if (!(_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]"))) {
-                  _context2.next = 6;
-                  break;
-                }
-
-                return _context2.abrupt("return");
-
-              case 6:
-                _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
-
                 if (!(cn = navigator.connection)) {
-                  _context2.next = 10;
+                  _context2.next = 3;
                   break;
                 }
 
-                if (!((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData)) {
-                  _context2.next = 10;
+                if (!(cn.saveData || /2g/.test(cn.effectiveType))) {
+                  _context2.next = 3;
                   break;
                 }
 
                 return _context2.abrupt("return");
 
-              case 10:
-                if (!( true && !isDependency)) {
-                  _context2.next = 16;
-                  break;
-                }
-
-                ;
-                _context2.next = 14;
-                return _this2.getDependencies(route);
+              case 3:
+                url = _this2.assetPrefix;
 
-              case 14:
-                _context2.t0 = function (url) {
-                  _this2.prefetch(url, true);
-                };
+                if (isDependency) {
+                  url += route;
+                } else {
+                  route = _this2.normalizeRoute(route);
+                  _this2.prefetched[route] = true;
+                  scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-                _context2.sent.forEach(_context2.t0);
+                  if ( true && hasNoModule) {
+                    scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+                  }
 
-              case 16:
-                if (!hasPreload) {
-                  _context2.next = 19;
-                  break;
+                  url += "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute);
                 }
 
-                preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-                return _context2.abrupt("return");
-
-              case 19:
-                if (!isDependency) {
-                  _context2.next = 21;
+                if (!document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
+                  _context2.next = 7;
                   break;
                 }
 
                 return _context2.abrupt("return");
 
-              case 21:
-                if (!(document.readyState === 'complete')) {
-                  _context2.next = 25;
-                  break;
-                }
-
-                return _context2.abrupt("return", _this2.loadPage(route)["catch"](function () {}));
-
-              case 25:
-                return _context2.abrupt("return", new _promise["default"](function (resolve) {
-                  window.addEventListener('load', function () {
-                    _this2.loadPage(route).then(function () {
-                      return resolve();
-                    }, function () {
-                      return resolve();
-                    });
-                  });
-                }));
+              case 7:
+                return _context2.abrupt("return", _promise["default"].all([appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script'),  true && !isDependency && _this2.getDependencies(route).then(function (urls) {
+                  return _promise["default"].all(urls.map(function (url) {
+                    return _this2.prefetch(url, true);
+                  }));
+                })]).then( // do not return any data
+                function () {}, // swallow prefetch errors
+                function () {}));
 
-              case 26:
+              case 8:
               case "end":
                 return _context2.stop();
             }
Diff for main-HASH.module.js
@@ -1078,36 +1078,32 @@ var _asyncToGenerator2 = _interopRequireDefault(__webpack_require__("+oT+"));
 var _promise = _interopRequireDefault(__webpack_require__("eVuF"));
 
 var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
-/* global document, window */
 
-
-var prefetchOrPreload = undefined ? 'prefetch' : 'preload';
-
-function supportsPreload(el) {
+function hasPrefetch(link) {
   try {
-    return el.relList.supports(prefetchOrPreload);
-  } catch (_unused) {
-    return false;
-  }
+    link = document.createElement('link');
+    return link.relList.supports('prefetch');
+  } catch (_unused) {}
 }
 
-var hasPreload = supportsPreload(document.createElement('link'));
-
-function preloadLink(url, resourceType) {
-  var link = document.createElement('link');
-  link.rel = prefetchOrPreload;
-  link.crossOrigin = "anonymous";
-  link.href = url;
-  link.as = resourceType;
-  document.head.appendChild(link);
-}
-
-function loadStyle(url) {
-  var link = document.createElement('link');
-  link.rel = 'stylesheet';
-  link.crossOrigin = "anonymous";
-  link.href = url;
-  document.head.appendChild(link);
+var relPrefetch = hasPrefetch() ? // https://caniuse.com/#feat=link-rel-prefetch
+// IE 11, Edge 12+, nearly all evergreen
+'prefetch' : // https://caniuse.com/#feat=link-rel-preload
+// macOS and iOS (Safari does not support prefetch)
+'preload';
+var hasNoModule = 'noModule' in document.createElement('script');
+
+function appendLink(href, rel, as) {
+  return new _promise.default((res, rej, link) => {
+    link = document.createElement('link');
+    link.crossOrigin = "anonymous";
+    link.href = href;
+    link.rel = rel;
+    if (as) link.as = as;
+    link.onload = res;
+    link.onerror = rej;
+    document.head.appendChild(link);
+  });
 }
 
 class PageLoader {
@@ -1206,7 +1202,9 @@ class PageLoader {
               }
 
               if (/\.css$/.test(d) && !document.querySelector("link[rel=stylesheet][href^=\"" + d + "\"]")) {
-                loadStyle(d); // FIXME: handle failure
+                appendLink(d, 'stylesheet').catch(() => {// FIXME: handle failure
+                  // Right now, this is needed to prevent an unhandled rejection.
+                });
               }
             });
             this.loadRoute(route);
@@ -1232,7 +1230,7 @@ class PageLoader {
   loadScript(url, route, isPage) {
     var script = document.createElement('script');
 
-    if ( true && 'noModule' in script) {
+    if ( true && hasNoModule) {
       script.type = 'module'; // Only page bundle scripts need to have .module added to url,
       // dependencies already have it added during build manifest creation
 
@@ -1283,61 +1281,38 @@ class PageLoader {
     var _this2 = this;
 
     return (0, _asyncToGenerator2.default)(function* () {
-      route = _this2.normalizeRoute(route);
-      var scriptRoute = (route === '/' ? '/index' : route) + ".js";
-
-      if ( true && 'noModule' in document.createElement('script')) {
-        scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
-      }
-
-      var url = _this2.assetPrefix + (isDependency ? route : "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute)); // n.b. If preload is not supported, we fall back to `loadPage` which has
-      // its own deduping mechanism.
-
-      if (_this2.prefetched[route] || document.querySelector("link[rel=\"" + prefetchOrPreload + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
-        return;
-      }
-
-      _this2.prefetched[route] = true; // Inspired by quicklink, license: https://github.com/GoogleChromeLabs/quicklink/blob/master/LICENSE
-
+      // https://github.com/GoogleChromeLabs/quicklink/blob/453a661fa1fa940e2d2e044452398e38c67a98fb/src/index.mjs#L115-L118
+      // License: Apache 2.0
       var cn;
 
       if (cn = navigator.connection) {
-        // Don't prefetch if the user is on 2G or if Save-Data is enabled.
-        if ((cn.effectiveType || '').indexOf('2g') !== -1 || cn.saveData) {
-          return;
-        }
+        // Don't prefetch if using 2G or if Save-Data is enabled.
+        if (cn.saveData || /2g/.test(cn.effectiveType)) return;
       }
 
-      if ( true && !isDependency) {
-        ;
-        (yield _this2.getDependencies(route)).forEach(url => {
-          _this2.prefetch(url, true);
-        });
-      } // Feature detection is used to see if preload is supported
-      // If not fall back to loading script tags before the page is loaded
-      // https://caniuse.com/#feat=link-rel-preload
+      var url = _this2.assetPrefix;
 
+      if (isDependency) {
+        url += route;
+      } else {
+        route = _this2.normalizeRoute(route);
+        _this2.prefetched[route] = true;
+        var scriptRoute = (route === '/' ? '/index' : route) + ".js";
 
-      if (hasPreload) {
-        preloadLink(url, url.match(/\.css$/) ? 'style' : 'script');
-        return;
+        if ( true && hasNoModule) {
+          scriptRoute = scriptRoute.replace(/\.js$/, '.module.js');
+        }
+
+        url += "/_next/static/" + encodeURIComponent(_this2.buildId) + "/pages" + encodeURI(scriptRoute);
       }
 
-      if (isDependency) {
-        // loadPage will automatically handle dependencies, so no need to
-        // preload them manually
+      if (document.querySelector("link[rel=\"" + relPrefetch + "\"][href^=\"" + url + "\"], script[data-next-page=\"" + route + "\"]")) {
         return;
       }
 
-      if (document.readyState === 'complete') {
-        return _this2.loadPage(route).catch(() => {});
-      } else {
-        return new _promise.default(resolve => {
-          window.addEventListener('load', () => {
-            _this2.loadPage(route).then(() => resolve(), () => resolve());
-          });
-        });
-      }
+      return _promise.default.all([appendLink(url, relPrefetch, url.match(/\.css$/) ? 'style' : 'script'),  true && !isDependency && _this2.getDependencies(route).then(urls => _promise.default.all(urls.map(url => _this2.prefetch(url, true))))]).then( // do not return any data
+      () => {}, // swallow prefetch errors
+      () => {});
     })();
   }
Diff for index.html
@@ -12,7 +12,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-e8a4701898cc078b37e0.module.js"
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/framework.9c9aa574c484a7d0240e.module.js"
         as="script" crossorigin="anonymous" />
@@ -44,9 +44,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/runtime/webpack-7928590be3ef2e55b835.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-28970b5a87d524ca5f50.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-e8a4701898cc078b37e0.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/chunks/framework.4c64484d8a631a55b435.js"
         async="" crossorigin="anonymous" nomodule=""></script>
Diff for link.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-e8a4701898cc078b37e0.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -61,9 +61,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-28970b5a87d524ca5f50.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-e8a4701898cc078b37e0.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>
Diff for withRouter.html
@@ -18,7 +18,7 @@
         as="script" crossorigin="anonymous" />
         <link rel="preload" href="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         as="script" crossorigin="anonymous" />
-        <link rel="preload" href="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <link rel="preload" href="/_next/static/runtime/main-e8a4701898cc078b37e0.module.js"
         as="script" crossorigin="anonymous" />
     </head>
     
@@ -59,9 +59,9 @@
         async="" crossorigin="anonymous" nomodule=""></script>
         <script src="/_next/static/chunks/de003c3a9d308750aa009870a5926f9b18ab31f4.bdb1895cb5ac008f5797.module.js"
         async="" crossorigin="anonymous" type="module"></script>
-        <script src="/_next/static/runtime/main-c7894c8b919067f5cc96.js"
+        <script src="/_next/static/runtime/main-28970b5a87d524ca5f50.js"
         async="" crossorigin="anonymous" nomodule=""></script>
-        <script src="/_next/static/runtime/main-dabb7de42544cbe5a6be.module.js"
+        <script src="/_next/static/runtime/main-e8a4701898cc078b37e0.module.js"
         async="" crossorigin="anonymous" type="module"></script>
         <script src="/_next/static/BUILD_ID/_buildManifest.js" async=""
         crossorigin="anonymous" nomodule=""></script>

Serverless Mode (Decrease detected ✓)
General Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
buildDuration 13.9s 14s ⚠️ +135ms
nodeModulesSize 48.7 MB 48.7 MB -1.16 kB
Client Bundles (main, webpack, commons) Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.js 18.6 kB 18.2 kB -404 B
main-HASH.js gzip 6.52 kB 6.43 kB -89 B
webpack-HASH.js 1.53 kB 1.53 kB
webpack-HASH.js gzip 746 B 746 B
4952ddcd88e7..1db6754d3.js 12 kB 12 kB
4952ddcd88e7..54d3.js gzip 4.68 kB 4.68 kB
commons.HASH.js 10.9 kB 10.9 kB
commons.HASH.js gzip 4.06 kB 4.06 kB
de003c3a9d30..17cdc0d60.js 38.3 kB 38.3 kB
de003c3a9d30..0d60.js gzip 13.9 kB 13.9 kB
framework.HASH.js 126 kB 126 kB
framework.HASH.js gzip 39.5 kB 39.5 kB
Overall change 207 kB 206 kB -404 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
zeit/next.js canary Timer/next.js preload Change
main-HASH.module.js 14.5 kB 14.4 kB -174 B
main-HASH.module.js gzip 5.44 kB 5.41 kB -27 B
webpack-HASH.module.js 1.53 kB 1.53 kB
webpack-HASH..dule.js gzip 746 B 746 B
4952ddcd88e7..b9.module.js 14.9 kB 14.9 kB
4952ddcd88e7..dule.js gzip 5.56 kB 5.56 kB
de003c3a9d30..e3.module.js 33.1 kB 33.1 kB
de003c3a9d30..dule.js gzip 12.5 kB 12.5 kB
framework.HASH.module.js 126 kB 126 kB
framework.HA..dule.js gzip 39.4 kB 39.4 kB
Overall change 190 kB 189 kB -174 B
Legacy Client Bundles (polyfills)
zeit/next.js canary Timer/next.js preload Change
polyfills-HASH.js 15.3 kB 15.3 kB
polyfills-HASH.js gzip 4.76 kB 4.76 kB
Overall change 15.3 kB 15.3 kB
Client Pages
zeit/next.js canary Timer/next.js preload Change
_app.js 2.94 kB 2.94 kB
_app.js gzip 1.33 kB 1.33 kB
_error.js 10.4 kB 10.4 kB
_error.js gzip 4.07 kB 4.07 kB
hooks.js 1.44 kB 1.44 kB
hooks.js gzip 779 B 779 B
index.js 318 B 318 B
index.js gzip 222 B 222 B
link.js 6.88 kB 6.88 kB
link.js gzip 2.93 kB 2.93 kB
routerDirect.js 411 B 411 B
routerDirect.js gzip 283 B 283 B
withRouter.js 421 B 421 B
withRouter.js gzip 282 B 282 B
Overall change 22.8 kB 22.8 kB
Client Pages Modern
zeit/next.js canary Timer/next.js preload Change
_app.module.js 1.54 kB 1.54 kB
_app.module.js gzip 757 B 757 B
_error.module.js 7.35 kB 7.35 kB
_error.module.js gzip 3.06 kB 3.06 kB
hooks.module.js 651 B 651 B
hooks.module.js gzip 371 B 371 B
index.module.js 276 B 276 B
index.module.js gzip 212 B 212 B
link.module.js 5.54 kB 5.54 kB
link.module.js gzip 2.49 kB 2.49 kB
routerDirect.module.js 383 B 383 B
routerDirect..dule.js gzip 273 B 273 B
withRouter.module.js 394 B 394 B
withRouter.m..dule.js gzip 272 B 272 B
Overall change 16.1 kB 16.1 kB
Client Build Manifests
zeit/next.js canary Timer/next.js preload Change
_buildManifest.js 81 B 81 B
_buildManifest.js gzip 61 B 61 B
_buildManifest.module.js 81 B 81 B
_buildManife..dule.js gzip 61 B 61 B
Overall change 162 B 162 B
Serverless bundles
zeit/next.js canary Timer/next.js preload Change
_error.js 299 kB 299 kB
_error.js gzip 78.8 kB 78.8 kB
hooks.html 4.19 kB 4.19 kB
hooks.html gzip 1.07 kB 1.07 kB ⚠️ +1 B
index.js 299 kB 299 kB
index.js gzip 79.1 kB 79.1 kB
link.js 306 kB 306 kB
link.js gzip 81.1 kB 81.1 kB ⚠️ +1 B
routerDirect.js 299 kB 299 kB
routerDirect.js gzip 79.1 kB 79.1 kB
withRouter.js 299 kB 299 kB
withRouter.js gzip 79.3 kB 79.3 kB -1 B
Overall change 1.51 MB 1.51 MB

Commit: 69ff434

@Timer Timer marked this pull request as ready for review December 24, 2019 04:06
@Timer Timer merged commit 632e40f into vercel:canary Dec 24, 2019
@Timer Timer deleted the preload branch December 24, 2019 15:07
@vercel vercel locked as resolved and limited conversation to collaborators Jan 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants