Skip to content

Commit c60c833

Browse files
authored
ui: improve dev-server caching and compresison (#5468)
Make the dev-server more friendly to remote cases where there is latency between client and server. Add if-modifidied-since caching and gzip content encoding.
1 parent a22fdf7 commit c60c833

File tree

1 file changed

+48
-12
lines changed

1 file changed

+48
-12
lines changed

ui/build.js

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const crypto = require('crypto');
7171
const fs = require('fs');
7272
const http = require('http');
7373
const path = require('path');
74+
const zlib = require('zlib');
7475
const pjoin = path.join;
7576

7677
const ROOT_DIR = path.dirname(__dirname); // The repo root.
@@ -715,6 +716,29 @@ function startServer() {
715716
return;
716717
}
717718

719+
let stat;
720+
try {
721+
stat = fs.statSync(absPath);
722+
} catch (statErr) {
723+
res.writeHead(404);
724+
res.end(JSON.stringify(statErr));
725+
return;
726+
}
727+
728+
// Truncate to second precision: HTTP dates have 1s resolution, so the
729+
// sub-millisecond part of mtime would cause a permanent mismatch.
730+
const mtimeSec = Math.floor(stat.mtime.getTime() / 1000) * 1000;
731+
const mtimeStr = new Date(mtimeSec).toUTCString();
732+
733+
// Return 304 if the browser's cached copy is still fresh.
734+
const ifModifiedSince = req.headers['if-modified-since'];
735+
if (ifModifiedSince !== undefined &&
736+
new Date(ifModifiedSince).getTime() >= mtimeSec) {
737+
res.writeHead(304);
738+
res.end();
739+
return;
740+
}
741+
718742
fs.readFile(absPath, function(err, data) {
719743
if (err) {
720744
res.writeHead(404);
@@ -730,25 +754,37 @@ function startServer() {
730754
};
731755
const ext = uri.split('.').pop();
732756
const cType = mimeMap[ext] || 'octect/stream';
733-
const head = {
734-
'Content-Type': cType,
735-
'Content-Length': data.length,
736-
'Last-Modified': fs.statSync(absPath).mtime.toUTCString(),
737-
'Cache-Control': 'no-cache',
757+
const acceptsGzip =
758+
(req.headers['accept-encoding'] || '').includes('gzip');
759+
const finalize = (body) => {
760+
const head = {
761+
'Content-Type': cType,
762+
'Content-Length': body.length,
763+
'Last-Modified': mtimeStr,
764+
'Cache-Control': 'no-cache',
765+
};
766+
if (acceptsGzip) head['Content-Encoding'] = 'gzip';
767+
if (cfg.crossOriginIsolation) {
768+
head['Cross-Origin-Opener-Policy'] = 'same-origin';
769+
head['Cross-Origin-Embedder-Policy'] = 'require-corp';
770+
}
771+
res.writeHead(200, head);
772+
res.write(body);
773+
res.end();
738774
};
739-
if (cfg.crossOriginIsolation) {
740-
head['Cross-Origin-Opener-Policy'] = 'same-origin';
741-
head['Cross-Origin-Embedder-Policy'] = 'require-corp';
775+
if (acceptsGzip) {
776+
zlib.gzip(data, (gzErr, compressed) => {
777+
finalize(gzErr ? data : compressed);
778+
});
779+
} else {
780+
finalize(data);
742781
}
743-
res.writeHead(200, head);
744-
res.write(data);
745-
res.end();
746782
});
747783
});
748784

749785
let port = cfg.httpServerListenPort ?? DEFAULT_PORT;
750786
let retryCount = 0;
751-
787+
752788
// Pick the next free port starting at 10000
753789
server.on('error', (e) => {
754790
if (e.code === 'EADDRINUSE') {

0 commit comments

Comments
 (0)