3

I use webpack-compression-plugin ta compress all my static files and hml files beforehand to gzip and brotli format. If browser supports it I use brotli, if not gzip and last option is original file. So I would have something like this for example after bundling.

bundle.js bundle.js.gz bundle.js.br 

On server I use express-static-gzip to serve static files and everything is working fine. All my client static assets are compressd and served like that.

import expressStaticGzip from 'express-static-gzip' const app: Express = new Express() process.env.PWD = process.cwd() app.set('view engine', 'ejs') app.set('views', path.join(process.env.PWD + '/src/server/views')) app.use(expressStaticGzip(path.join(process.env.PWD + '/src/dist'), {indexFromEmptyFile: false, enableBrotli: true, maxAge: '1y'})) app.use((req, res, next) => { res.set('Cache-Control', 'no-cache') return next() }) /* Use server side rendering for first load */ app.use(appRenderer) // Routes app.get('*', (req, res) => { res.render('index') }) app.listen(PORT, () => { console.log(` Express server is up on port ${PORT} Production environment `) }) 

The problem I have is with my html file, root. Although I also have gzip and br version of it, it is not served like that. I make it by bundling server side code. Express compression module doesn't work and I also want static compression. I am not using nginx. enter image description here

5
  • Did you happen to find the solution? Otherwise, I'm using stackoverflow.com/a/15323082/3241111 This works for me. Don't know, how to use it FOR JUST .html and not for .js and .css bcoz I don't want server to compress js and css for SSR on each request Commented Jul 16, 2017 at 19:19
  • 1
    I didn't find easy solution but I did find one. I used Nginx. With Nginx I can use gzip_static module to serve precompressed static files and regular gzip dynamic mode that compresses just html file on the fly. Commented Jul 16, 2017 at 19:32
  • That's nice. Do you compress images as well? Commented Jul 16, 2017 at 19:48
  • No, not images. I compress every image before I use it with pthotoshop save for web feature and TinyPNG online so images are already compressed and it is not recomended to gzip them. Commented Jul 16, 2017 at 20:04
  • Ah ok... that makes sense.. to compress images before hand using tinypng but when I compress one of my images(51kb) using tinypng, it goes down by just 1.5kB but lighthouse complains for the original image(51kb) to be compressed upto 25% :P I checked content-type in request header, which accepts gzip format.. May be I need to read more on this :) Also check answer below in 2 min... I got something working.. Commented Jul 16, 2017 at 20:09

1 Answer 1

1

With the help of this plugin and as was suggested here I got it working

My code: Ensure that you've pre-gzipped .js and .css files

const checkForHTML = req => { const url = req.url.split('.'); const extension = url[url.length -1]; if (['/'].indexOf(extension) > -1) { return true; //compress only .html files sent from server } return false; }; var compress = require('compression'); app.use(compress({filter: checkForHTML})); const encodeResToGzip = contentType => (req, res, next) => { req.url = req.url + '.gz'; res.set('Content-Encoding', 'gzip'); res.set('Content-Type', contentType); next(); }; app.get("*.js", encodeResToGzip('text/javascript')); app.get("*.css", encodeResToGzip('text/css')); 

I wanted compression to happen only for .html because I'm using .ejs template, so need to compress .html on runtime. Compressing static files(js/css) using express compression isn't good idea because it will do it on every request and those are static files. Or else, cache your results as suggested here

Other solution using nginx, as you posted in your comments also seems nice.

Sign up to request clarification or add additional context in comments.

4 Comments

I'll be sure to try your solution also next time I have a chance. I also forgat to tell that there is a plugin brotli-compression-plugin. Brotli is a new standard instead of gzip. Everything should work the same. You have three files .js, .js.gz and .js.br and browser uses it in order from last to first. You can also serve it with Nginx.I think this is the best way for me. I have .ejs template, bundle, vendor, styles... and every static file is generated with chunkhash and it has Cache header set for 1 year. CONTINUE =>
Html file has no-cache header so browser contacts it on every load but it caches everything else. If there is a change among static files browser will know since it will contacts html. This way it will download only the file that is changed and use everything else from cache. Not using precompressed gzip but on the fly is beneficial in this case.
me too using .ejs and having chunkhash cached css-js for 1 year. Not caching index.html.. I don't know how to provide offline support in this case... Also, "Not using precompressed gzip but on the fly..." Meaning, in which case? I'm having precached css-js which gives me 200(from disk cached) and not 304(Not Modified) which means, precompressed is fine @Igor-Vuk
I was talking about .html. All my static files are also giving 200 except .html that gives 304. You can use CDN for offline support.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.