Reputation: 21
I'm developing web application on App Engine(nodejs10 as runtime, Node as server, and React as frontend).
For better performance indicated by Lighthouse, I am trying to make every response compressed in gzip. Currently gzip compression worked for API response, but does not for script tag.
In server.js, I've introduced compression module, and that worked. Every internal api call response is gzipped.
import compression from 'compression';
.
.
app.use(
compression({
threshold: 1,
level: 9,
memLevel: 1,
}),
);
.
.
Gzip file is locally generated and located in same place as raw Javascript files. Here's in webpack.config.js.
new CompressionPlugin({
test: /\.(css)|(js)$/,
compressionOptions: {
level: 9,
},
}),
In html, I'm trying to load frontend files.
I suppose App Engine handles the rest if content can be encoded or not according to accepting-encoding
and user-agent
.
Here's the problem. Every static files remain unzipped.
<body>
<script type="text/javascript" src="/assets/client.js" charSet="utf-8" />
<script type="text/javascript" src="/assets/vendors.chunk.js" charSet="utf-8" />
</body>
Request headers
:authority: myApplicaation
:method: GET
:path: /assets/client.js
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: ja,en-US;q=0.9,en;q=0.8
cache-control: no-cache
cookie: _ga=GA1.2.1338918906.1558605919; __stripe_mid=1091f2c2-d01d-4386-871b-ee420a840bd5; _gcl_au=1.1.2059850586.1566453250; _gid=GA1.2.969451871.1566667214; connect.sid=s%3AIINmpsd-30ad8TF5z7oCBDo4h1jIxgRQ.XxT3L7%2F8H2tVcS4COIrpy7SxCp746FnIKNjthLW1P8Q; __stripe_sid=edda0dd4-1fbf-4da9-bcdc-9dccab9bdf4e; _gat_UA-125249076-1=1
pragma: no-cache
referer: https://tripper.world/
sec-fetch-mode: no-cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1
Response headers
accept-ranges: bytes
age: 371502
cache-control: public, max-age=5184000
content-length: 1417405
content-type: application/javascript; charset=UTF-8
date: Sat, 24 Aug 2019 03:47:28 GMT
etag: W/"15a0bd-16cb7e22578"
last-modified: Thu, 22 Aug 2019 05:52:27 GMT
server: Google Frontend
status: 200
x-cloud-trace-context: 6304083a50ed3fa42285e3e229af07a8
x-powered-by: Express
Is there any way to make static files gzipped? If my any assumption are wrong, please point them out.
I appreciate your helps in advance, Thanks.
**********Additional information**********
static file's served via express static.
app.use(
express.static(path.resolve(__dirname, 'public'), {
maxAge: '60d',
}),
);
app.standard.yaml
runtime: nodejs10
instance_class: F2
automatic_scaling:
target_cpu_utilization: 0.65
min_instances: 0
max_instances: 1
beta_settings:
cloud_sql_instances: 'xxxxxx-xxxxxx:asia-northeast1:xxxxxx-postgres'
handlers:
- url: /.*
script: auto
Upvotes: 1
Views: 2807
Reputation: 5276
Try serving your static assets via GAE's static_dir
handler in app.yaml
handlers:
- url: /assets
static_dir: path/to/assets/folder
- url: /.*
script: auto
and google should automatically gzip it based on the request headers it receives
Upvotes: 0
Reputation: 724
Try in your Express application something like (I haven't tested):
const path = require('path')
const setStaticHeaders = (res, assetPath) => {
const assetExtension = path.extname(assetPath);
// Only apply to assets Webpack compressed
if (['.js', '.css'].includes(assetExtension)) {
res.setHeader('Content-Encoding', 'gzip');
}
}
app.use(
express.static(path.resolve(__dirname, 'public'), {
maxAge: '60d',
setHeaders: setStaticHeaders
}),
);
Webpack is GZipping your assets but not setting the correct response header. You also only want to apply that header for the actual assets that Webpack Gzipped, in case there are other non-compressed assets in your assets folder (which there might not be).
It looks like App Engine will automatically GZip static assets for you. So you could also remove the GZip in the Webpack config and just serve the files using App Engine.
Upvotes: 1