mirror of https://github.com/zulip/zulip.git
static: Pre-compress with zopfli, for better compression.
Zopfli[^1] performs very good, but time-intensive, zlib compression. It is hence only suitable for pre-compressing objects, not on-the-fly compression. Use a webpack plugin to write pre-compressed versions of JS and CSS assets using Zopfli, and configure nginx to serve those assets when `Accept-Encoding: gzip` is provided. This reduces the size of the JS and CSS assets on initial pageload from 1422872 bytes to 1108267 bytes, or about a 22% savings. [^1]: https://github.com/google/zopfli
This commit is contained in:
parent
b89d47a147
commit
2840e68548
|
@ -8,6 +8,7 @@
|
||||||
"@babel/register": "^7.6.2",
|
"@babel/register": "^7.6.2",
|
||||||
"@fontsource-variable/open-sans": "^5.0.9",
|
"@fontsource-variable/open-sans": "^5.0.9",
|
||||||
"@formatjs/intl": "^2.0.0",
|
"@formatjs/intl": "^2.0.0",
|
||||||
|
"@gfx/zopfli": "^1.0.15",
|
||||||
"@giphy/js-components": "^5.13.0",
|
"@giphy/js-components": "^5.13.0",
|
||||||
"@giphy/js-fetch-api": "^5.6.0",
|
"@giphy/js-fetch-api": "^5.6.0",
|
||||||
"@koa/bodyparser": "^5.0.0",
|
"@koa/bodyparser": "^5.0.0",
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
"clean-css": "^5.1.0",
|
"clean-css": "^5.1.0",
|
||||||
"clipboard": "^2.0.4",
|
"clipboard": "^2.0.4",
|
||||||
"colord": "^2.9.3",
|
"colord": "^2.9.3",
|
||||||
|
"compression-webpack-plugin": "^11.1.0",
|
||||||
"core-js": "^3.37.0",
|
"core-js": "^3.37.0",
|
||||||
"css-loader": "^7.1.1",
|
"css-loader": "^7.1.1",
|
||||||
"css-minimizer-webpack-plugin": "^7.0.0",
|
"css-minimizer-webpack-plugin": "^7.0.0",
|
||||||
|
|
|
@ -37,6 +37,9 @@ importers:
|
||||||
'@formatjs/intl':
|
'@formatjs/intl':
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.10.4(typescript@5.5.2)
|
version: 2.10.4(typescript@5.5.2)
|
||||||
|
'@gfx/zopfli':
|
||||||
|
specifier: ^1.0.15
|
||||||
|
version: 1.0.15
|
||||||
'@giphy/js-components':
|
'@giphy/js-components':
|
||||||
specifier: ^5.13.0
|
specifier: ^5.13.0
|
||||||
version: 5.13.0(@babel/core@7.24.9)
|
version: 5.13.0(@babel/core@7.24.9)
|
||||||
|
@ -88,6 +91,9 @@ importers:
|
||||||
colord:
|
colord:
|
||||||
specifier: ^2.9.3
|
specifier: ^2.9.3
|
||||||
version: 2.9.3
|
version: 2.9.3
|
||||||
|
compression-webpack-plugin:
|
||||||
|
specifier: ^11.1.0
|
||||||
|
version: 11.1.0(webpack@5.93.0(webpack-cli@5.1.4))
|
||||||
core-js:
|
core-js:
|
||||||
specifier: ^3.37.0
|
specifier: ^3.37.0
|
||||||
version: 3.37.1
|
version: 3.37.1
|
||||||
|
@ -1785,6 +1791,10 @@ packages:
|
||||||
'@gar/promisify@1.1.3':
|
'@gar/promisify@1.1.3':
|
||||||
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
||||||
|
|
||||||
|
'@gfx/zopfli@1.0.15':
|
||||||
|
resolution: {integrity: sha512-7mBgpi7UD82fsff5ThQKet0uBTl4BYerQuc+/qA1ELTwWEiIedRTcD3JgiUu9wwZ2kytW8JOb165rSdAt8PfcQ==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
|
||||||
'@giphy/js-analytics@5.0.0':
|
'@giphy/js-analytics@5.0.0':
|
||||||
resolution: {integrity: sha512-jBZG6OqyMWB6meLi8Sz3iLplXYnhkbj+DJhS4ChmRX8Y6UA7i5dbbsUN/So1s7tTjhZOvu0rxA6rWJE73S1FvQ==}
|
resolution: {integrity: sha512-jBZG6OqyMWB6meLi8Sz3iLplXYnhkbj+DJhS4ChmRX8Y6UA7i5dbbsUN/So1s7tTjhZOvu0rxA6rWJE73S1FvQ==}
|
||||||
|
|
||||||
|
@ -3555,6 +3565,12 @@ packages:
|
||||||
resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
|
resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
|
|
||||||
|
compression-webpack-plugin@11.1.0:
|
||||||
|
resolution: {integrity: sha512-zDOQYp10+upzLxW+VRSjEpRRwBXJdsb5lBMlRxx1g8hckIFBpe3DTI0en2w7h+beuq89576RVzfiXrkdPGrHhA==}
|
||||||
|
engines: {node: '>= 18.12.0'}
|
||||||
|
peerDependencies:
|
||||||
|
webpack: ^5.1.0
|
||||||
|
|
||||||
compression@1.7.4:
|
compression@1.7.4:
|
||||||
resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
|
resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
@ -10709,6 +10725,10 @@ snapshots:
|
||||||
|
|
||||||
'@gar/promisify@1.1.3': {}
|
'@gar/promisify@1.1.3': {}
|
||||||
|
|
||||||
|
'@gfx/zopfli@1.0.15':
|
||||||
|
dependencies:
|
||||||
|
base64-js: 1.5.1
|
||||||
|
|
||||||
'@giphy/js-analytics@5.0.0':
|
'@giphy/js-analytics@5.0.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@giphy/js-types': 5.1.0
|
'@giphy/js-types': 5.1.0
|
||||||
|
@ -12793,6 +12813,12 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db: 1.53.0
|
mime-db: 1.53.0
|
||||||
|
|
||||||
|
compression-webpack-plugin@11.1.0(webpack@5.93.0(webpack-cli@5.1.4)):
|
||||||
|
dependencies:
|
||||||
|
schema-utils: 4.2.0
|
||||||
|
serialize-javascript: 6.0.2
|
||||||
|
webpack: 5.93.0(webpack-cli@5.1.4)
|
||||||
|
|
||||||
compression@1.7.4:
|
compression@1.7.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
accepts: 1.3.8
|
accepts: 1.3.8
|
||||||
|
|
|
@ -9,6 +9,7 @@ error_page 502 503 504 /static/webpack-bundles/5xx.html;
|
||||||
# Serve static files directly
|
# Serve static files directly
|
||||||
location /static/ {
|
location /static/ {
|
||||||
alias /home/zulip/prod-static/;
|
alias /home/zulip/prod-static/;
|
||||||
|
gzip_static on;
|
||||||
include /etc/nginx/zulip-include/headers;
|
include /etc/nginx/zulip-include/headers;
|
||||||
add_header Access-Control-Allow-Origin *;
|
add_header Access-Control-Allow-Origin *;
|
||||||
add_header Timing-Allow-Origin *;
|
add_header Timing-Allow-Origin *;
|
||||||
|
|
|
@ -50,4 +50,4 @@ API_FEATURE_LEVEL = 280 # Last bumped for can_create_web_public_channel_group
|
||||||
# historical commits sharing the same major version, in which case a
|
# historical commits sharing the same major version, in which case a
|
||||||
# minor version bump suffices.
|
# minor version bump suffices.
|
||||||
|
|
||||||
PROVISION_VERSION = (290, 0) # bumped 2024-08-12 for upgrading starlight to latest version.
|
PROVISION_VERSION = (290, 1) # bumped 2024-08-12 to add zopfli compression
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
|
import type {ZopfliOptions} from "@gfx/zopfli";
|
||||||
|
import {gzip} from "@gfx/zopfli";
|
||||||
|
import CompressionPlugin from "compression-webpack-plugin";
|
||||||
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
|
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
|
||||||
import HtmlWebpackPlugin from "html-webpack-plugin";
|
import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||||
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
||||||
|
@ -218,6 +221,11 @@ const config = (
|
||||||
chunks: ["error-styles"],
|
chunks: ["error-styles"],
|
||||||
publicPath: production ? "/static/webpack-bundles/" : "/webpack/",
|
publicPath: production ? "/static/webpack-bundles/" : "/webpack/",
|
||||||
}),
|
}),
|
||||||
|
new CompressionPlugin<ZopfliOptions>({
|
||||||
|
// Use zopfli to write pre-compressed versions of text files
|
||||||
|
test: /\.(js|css|html)$/,
|
||||||
|
algorithm: gzip,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
devServer: {
|
devServer: {
|
||||||
client: {
|
client: {
|
||||||
|
|
Loading…
Reference in New Issue