Merge pull request #5951 from meteor/webapp-caching-improvements

Webapp caching improvements
This commit is contained in:
Martijn Walraven
2016-01-11 13:04:06 +01:00
4 changed files with 400 additions and 61 deletions

View File

@@ -218,8 +218,10 @@ Reload._reload = function (options) {
var tryReload = function () { _.defer(function () {
if (Reload._migrate(tryReload, options)) {
// Tell the browser to shut down this VM and make a new one
window.location.reload();
// Make the browser reload the page
// Using location.replace() instead of location.reload() avoids
// validating assets with the server if we still have a fresh cached copy.
window.location.replace(window.location.href);
}
}); };

View File

@@ -1,65 +1,390 @@
{
"dependencies": {
"connect": {
"version": "2.9.0",
"version": "2.30.2",
"dependencies": {
"qs": {
"version": "0.6.5"
"basic-auth-connect": {
"version": "1.0.0"
},
"cookie-signature": {
"version": "1.0.1"
},
"buffer-crc32": {
"version": "0.2.1"
},
"cookie": {
"version": "0.1.0"
},
"bytes": {
"version": "0.2.0"
},
"fresh": {
"version": "0.2.0"
},
"pause": {
"version": "0.0.1"
},
"uid2": {
"version": "0.0.2"
},
"debug": {
"version": "0.7.2"
},
"methods": {
"version": "0.0.1"
},
"multiparty": {
"version": "2.1.8",
"body-parser": {
"version": "1.13.3",
"dependencies": {
"readable-stream": {
"version": "1.0.17"
"iconv-lite": {
"version": "0.4.11"
},
"stream-counter": {
"version": "0.1.0"
"on-finished": {
"version": "2.3.0",
"dependencies": {
"ee-first": {
"version": "1.1.1"
}
}
},
"raw-body": {
"version": "2.1.5",
"dependencies": {
"bytes": {
"version": "2.2.0"
},
"iconv-lite": {
"version": "0.4.13"
},
"unpipe": {
"version": "1.0.0"
}
}
}
}
},
"bytes": {
"version": "2.1.0"
},
"cookie": {
"version": "0.1.3"
},
"cookie-parser": {
"version": "1.3.5"
},
"cookie-signature": {
"version": "1.0.6"
},
"compression": {
"version": "1.5.2",
"dependencies": {
"accepts": {
"version": "1.2.13",
"dependencies": {
"mime-types": {
"version": "2.1.9",
"dependencies": {
"mime-db": {
"version": "1.21.0"
}
}
},
"negotiator": {
"version": "0.5.3"
}
}
},
"compressible": {
"version": "2.0.6",
"dependencies": {
"mime-db": {
"version": "1.21.0"
}
}
},
"vary": {
"version": "1.0.1"
}
}
},
"connect-timeout": {
"version": "1.6.2",
"dependencies": {
"ms": {
"version": "0.7.1"
}
}
},
"content-type": {
"version": "1.0.1"
},
"csurf": {
"version": "1.8.3",
"dependencies": {
"csrf": {
"version": "3.0.0",
"dependencies": {
"base64-url": {
"version": "1.2.1"
},
"rndm": {
"version": "1.1.1"
},
"scmp": {
"version": "1.0.0"
},
"uid-safe": {
"version": "2.0.0"
}
}
}
}
},
"debug": {
"version": "2.2.0",
"dependencies": {
"ms": {
"version": "0.7.1"
}
}
},
"depd": {
"version": "1.0.1"
},
"errorhandler": {
"version": "1.4.2",
"dependencies": {
"accepts": {
"version": "1.2.13",
"dependencies": {
"mime-types": {
"version": "2.1.9",
"dependencies": {
"mime-db": {
"version": "1.21.0"
}
}
},
"negotiator": {
"version": "0.5.3"
}
}
},
"escape-html": {
"version": "1.0.2"
}
}
},
"express-session": {
"version": "1.11.3",
"dependencies": {
"crc": {
"version": "3.3.0"
},
"uid-safe": {
"version": "2.0.0",
"dependencies": {
"base64-url": {
"version": "1.2.1"
}
}
}
}
},
"finalhandler": {
"version": "0.4.0",
"dependencies": {
"escape-html": {
"version": "1.0.2"
},
"on-finished": {
"version": "2.3.0",
"dependencies": {
"ee-first": {
"version": "1.1.1"
}
}
},
"unpipe": {
"version": "1.0.0"
}
}
},
"fresh": {
"version": "0.3.0"
},
"http-errors": {
"version": "1.3.1",
"dependencies": {
"inherits": {
"version": "2.0.1"
},
"statuses": {
"version": "1.2.1"
}
}
},
"method-override": {
"version": "2.3.5",
"dependencies": {
"methods": {
"version": "1.1.1"
},
"vary": {
"version": "1.0.1"
}
}
},
"morgan": {
"version": "1.6.1",
"dependencies": {
"basic-auth": {
"version": "1.0.3"
},
"on-finished": {
"version": "2.3.0",
"dependencies": {
"ee-first": {
"version": "1.1.1"
}
}
}
}
},
"multiparty": {
"version": "3.3.2",
"dependencies": {
"readable-stream": {
"version": "1.1.13",
"dependencies": {
"core-util-is": {
"version": "1.0.2"
},
"isarray": {
"version": "0.0.1"
},
"string_decoder": {
"version": "0.10.31"
},
"inherits": {
"version": "2.0.1"
}
}
},
"stream-counter": {
"version": "0.2.0"
}
}
},
"on-headers": {
"version": "1.0.1"
},
"parseurl": {
"version": "1.3.0"
},
"pause": {
"version": "0.1.0"
},
"qs": {
"version": "4.0.0"
},
"response-time": {
"version": "2.3.1"
},
"serve-favicon": {
"version": "2.3.0",
"dependencies": {
"etag": {
"version": "1.7.0"
},
"ms": {
"version": "0.7.1"
}
}
},
"serve-index": {
"version": "1.7.2",
"dependencies": {
"accepts": {
"version": "1.2.13",
"dependencies": {
"negotiator": {
"version": "0.5.3"
}
}
},
"batch": {
"version": "0.5.2"
},
"escape-html": {
"version": "1.0.2"
},
"mime-types": {
"version": "2.1.9",
"dependencies": {
"mime-db": {
"version": "1.21.0"
}
}
}
}
},
"serve-static": {
"version": "1.10.0",
"dependencies": {
"escape-html": {
"version": "1.0.2"
}
}
},
"type-is": {
"version": "1.6.10",
"dependencies": {
"media-typer": {
"version": "0.3.0"
},
"mime-types": {
"version": "2.1.9",
"dependencies": {
"mime-db": {
"version": "1.21.0"
}
}
}
}
},
"utils-merge": {
"version": "1.0.0"
},
"vhost": {
"version": "3.0.2"
}
}
},
"parseurl": {
"version": "1.3.0"
},
"send": {
"version": "0.1.4",
"version": "0.13.0",
"dependencies": {
"debug": {
"version": "0.7.2"
"version": "2.2.0"
},
"mime": {
"version": "1.2.11"
"depd": {
"version": "1.0.1"
},
"destroy": {
"version": "1.0.3"
},
"escape-html": {
"version": "1.0.2"
},
"etag": {
"version": "1.7.0"
},
"fresh": {
"version": "0.2.0"
"version": "0.3.0"
},
"http-errors": {
"version": "1.3.1",
"dependencies": {
"inherits": {
"version": "2.0.1"
}
}
},
"mime": {
"version": "1.3.4"
},
"ms": {
"version": "0.7.1"
},
"on-finished": {
"version": "2.3.0",
"dependencies": {
"ee-first": {
"version": "1.1.1"
}
}
},
"range-parser": {
"version": "0.0.4"
"version": "1.0.3"
},
"statuses": {
"version": "1.2.1"
}
}
},

View File

@@ -3,8 +3,9 @@ Package.describe({
version: '1.2.3'
});
Npm.depends({connect: "2.9.0",
send: "0.1.4",
Npm.depends({connect: "2.30.2",
parseurl: "1.3.0",
send: "0.13.0",
useragent: "2.0.7"});
Npm.strip({

View File

@@ -8,6 +8,7 @@ var url = Npm.require("url");
var crypto = Npm.require("crypto");
var connect = Npm.require('connect');
var parseurl = Npm.require('parseurl');
var useragent = Npm.require('useragent');
var send = Npm.require('send');
@@ -326,7 +327,7 @@ WebAppInternals.staticFilesMiddleware = function (staticFiles, req, res, next) {
next();
return;
}
var pathname = connect.utils.parseUrl(req).pathname;
var pathname = parseurl(req).pathname;
try {
pathname = decodeURIComponent(pathname);
} catch (e) {
@@ -367,17 +368,9 @@ WebAppInternals.staticFilesMiddleware = function (staticFiles, req, res, next) {
// Cacheable files are files that should never change. Typically
// named by their hash (eg meteor bundled js and css files).
// We cache them ~forever (1yr).
//
// We cache non-cacheable files anyway. This isn't really correct, as users
// can change the files and changes won't propagate immediately. However, if
// we don't cache them, browsers will 'flicker' when rerendering
// images. Eventually we will probably want to rewrite URLs of static assets
// to include a query parameter to bust caches. That way we can both get
// good caching behavior and allow users to change assets without delay.
// https://github.com/meteor/meteor/issues/773
var maxAge = info.cacheable
? 1000 * 60 * 60 * 24 * 365
: 1000 * 60 * 60 * 24;
: 0;
// Set the X-SourceMap header, which current Chrome, FireFox, and Safari
// understand. (The SourceMap header is slightly more spec-correct but FF
@@ -403,14 +396,19 @@ WebAppInternals.staticFilesMiddleware = function (staticFiles, req, res, next) {
}
}
if (info.hash) {
res.setHeader('ETag', '"' + info.hash + '"');
}
if (info.content) {
res.write(info.content);
res.end();
} else {
send(req, info.absolutePath)
.maxage(maxAge)
.hidden(true) // if we specified a dotfile in the manifest, serve it
.on('error', function (err) {
send(req, info.absolutePath, {
maxage: maxAge,
dotfiles: 'allow', // if we specified a dotfile in the manifest, serve it
lastModified: false // don't set last-modified based on the file date
}).on('error', function (err) {
Log.error("Error serving static file " + err);
res.writeHead(500);
res.end();
@@ -475,6 +473,7 @@ var runWebAppServer = function () {
staticFiles[urlPrefix + getItemPathname(item.url)] = {
absolutePath: path.join(clientDir, item.path),
cacheable: item.cacheable,
hash: item.hash,
// Link from source to its map
sourceMapUrl: item.sourceMapUrl,
type: item.type
@@ -505,6 +504,7 @@ var runWebAppServer = function () {
staticFiles[path.join(urlPrefix, getItemPathname('/manifest.json'))] = {
content: JSON.stringify(program),
cacheable: true,
hash: program.version,
type: "json"
};
};
@@ -687,8 +687,19 @@ var runWebAppServer = function () {
return undefined;
}
if (request.url.query && request.url.query['meteor_dont_serve_index']) {
// When downloading files during a Cordova hot code push, we need
// to detect if a file is not available instead of inadvertently
// downloading the default index page.
// So similar to the situation above, we serve an uncached 404.
headers['Cache-Control'] = 'no-cache';
res.writeHead(404, headers);
res.end("404 Not Found");
return undefined;
}
// /packages/asdfsad ... /__cordova/dafsdf.js
var pathname = connect.utils.parseUrl(req).pathname;
var pathname = parseurl(req).pathname;
var archKey = pathname.split('/')[1];
var archKeyCleaned = 'web.' + archKey.replace(/^__/, '');