Die Konfiguration von Express und SSR-Angular, falls die JavaScript Dateien im Build schon gzip-t werden und sich im gleichen Verzeichnis wie die eigentliche JavaScript Datei befinden (Auszug aus server.ts
):
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/browser');
// Hier folgt die standard-Konfiguration von Angular + SSR, wie sie von Angular Cli automatisch erzeugt wird, ...
server.get('*.js', (req, res, next) => {
if (!existsSync(`${distFolder}${req.url}.gz`) ||
req.headers['x-no-compression'] ||
!req.header('Accept-Encoding').includes('gzip')) {
return next();
}
req.url = `${req.url}.gz`;
res.set({
'Content-Type': 'text/javascript',
'Content-Encoding': 'gzip',
'Vary': 'Accept-Encoding',
'Cache-Control': 'max-age=31536000'
});
next();
});
// ... und noch mehr Konfiguration
}
Eigentlich ist es relativ selbsterklärend: Kommt ein GET Request für eine JavaScript *.js Datei, so werden erst einmal paar Bedingungen geprüft ob die Datei ausgeliefert werden kann und falls sie zutreffen, wird die Datei mit entsprechenden Headern zurückgegeben.
- Mit
existsSync(`${distFolder}${req.url}.gz`
wird geprüft ob die gzip-te Datei existiert (existsSync aus dem "fs" modul). - Über den
Accept-Encoding
Request-Header prüfen wir, ob der Browser die gzip Compression überhaupt unterstützt (das machen aber alle modernen Browser). - Wir prüfen noch ob der Header
req.headers['x-no-compression']
gesetzt ist: x-no-compression ist zwar kein Standard-Header, der Header wird aber auch in dem express-static-gzip
Projekt verwendet und es macht auch Sinn, für den Fall des Falles eine Möglichkeit zu haben, über die man die Kompression ausschalten kann.
Noch kurz zu den Response-Headern:
- Ich denke "Content-Type" und "Content-Encoding" müssten klar sein
- Vary mit Accept-Encoding: dieser Header weist Caching-Server und Proxys an, separate Kopien der komprimierten und unkomprimierten Versionen der JavaScript-Dateien zu speichern, basierend auf dem „Accept-Encoding“-Header des Clients. Dadurch wird sichergestellt, dass der Server in Abhängigkeit von den Fähigkeit des Clients, den Inhalt zu dekomprimieren, die geeignete Version des Inhalts bereitstellt. Allerdings, soweit ich das verstehe, müssten wir bei Cache-Control den Flag public setzen. Sonst dürfen die Dateien nicht auf Proxys/Caching-Servern gespeichert werden.
- Hier bin ich mir nicht sicher (auch in Verbindung mit dem "Vary" Header) ob Cache-Control: max-age=31536000, immutable, public nicht besser wäre: Da die generierten JS-Dateien im Namen einen Cache-Breaker (oder Cache-Buster) enthalten, sollte es kein Problem sein den Header eben auf "public" und "immutable" zu setzen.