Does express.static() cache files in the memory? - node.js

In ExpressJS for NodeJS, we can do the following:
app.use(express.static(__dirname + '/public'));
to serve all the static CSS, JS, and image files. My questions are these:
1) When we do that, does Express automatically cache the files in the server's memory or does it read from the hard disk every time one of the resources is served?
2) When we do that, does Express, using ETag by default, save the resources on the client's hard disk, or on the client's memory only?

The static middleware does no server-side caching. It lets you do two methods of client-side caching: ETag and Max-Age:
If the browser sees the ETag with the page, it will cache it. The next time the browser loads the page it checks for the ETag number changes. If the file is exactly the same, and so is its ETag - the server responds with an HTTP 304("not modified") status code instead of sending all the bytes again and saves a bunch of bandwidth.
Etag is turned-on by default but you can turn it off like this:
app.use(express.static(myStaticPath, {
etag: false
}))
Max-age is will set the max-age to some amount of time so the browser will only request that resource after one day has passed.
app.use(express.static(myStaticPath, {
maxAge: '5000' // uses milliseconds per docs
}))
For more details you can read this article
By default it's on the hard-drive, but someone can use something like this

Related

Is there an expressjs middleware to compress static file on the fly and cache in memory

I have all my static files under ./static folder without compressing. Is there an out of box library which can compress files in ./static on the fly and cache the result in memory?
Edit:
The reason that I want to compress and cache in memory is for better CDN performance when CloudFlare Miss a cache. I use Traefik as my reverse proxy, which only supports cache for the enterprise version, so I'd like to do it directly in node.
Better would be to use some third party for compressing and caching. For example nginx can be used for serving and compressing static files. However if you want to keep using NodeJS, here you can view the answer: Express gzip static content.
To simplify answer in short
Express 3.0 now has compress() support:
var app = express();
// gzip
app.use(express.compress());
// static
app.use("/public", express.static(__dirname + '/public'));
// listen
app.listen(80);
EDIT for Express 4.0, compress become the separate middleware. So you have to install and import to use it:
var compress = require('compression');
app.use(compress());
As for caching you can view this blog: Does express.static() cache files in the memory?.
In short, nodeJS does not do caching for you, but client browser side does based on tags and headers you provide. If you want extra caching layer, you can look into CDN's like cloudflare which will not only cache your static files but also serve it from closest server to client

What does this immutable property in options object of express.static used for?

I am a newbie to Node and Express, trying to explore things. I was going through the Express' documentation at this link: https://expressjs.com/en/4x/api.html#express.static
Here, The description of the immutable property passed in options says:
Enable or disable the immutable directive in the Cache-Control response header. If enabled, the maxAge option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the maxAge option to check if the file has changed.
I am unable to understand this. I've understood how maxAge is used but not able to get this immutable.
When and How is this property used?
Thanks in advance for any help you are able to provide
It's used for caching resources. Immutable here implies that it won't change(mutate). If you're delivering static assets through your express routes, the browser can use it's cache instead of verifying the asset's validity when the page refreshes. The maxAge directive here sets the duration for which the asset is immutable.
This simply means less server requests when you navigate or refresh pages.
You can use it in your routes by setting the response header before sending the response or you could create a middleware to plug-in between your routes.
router.get('/assets/*', function (req, res, next) {
res.setHeader('Cache-Control', 'max-age=36000,immutable');
res.send({});
}

How does Express.js handle Cache-Control automatically?

I was going to use a 'cache buster' to add a hash to the end of static js and css files during grunt build. I don't know too much about cache control. Without doing anything Express.js was sending a 304 status code. If I modified the file then Express.js would send the new file. It seems like I don't need to do anything and it works as expected.
Do I need to implement Cache-Control? Is it already handled auto magically?
Yes, express handles cache-control automatically. It's default value is set to true. And you can just handle it by increasing/decreasing it's maxAge property value. (in milliseconds). Or you can turn this option on or off by setting cacheControl to true or false .
For more Reference you can refer : Express Documentation

Express JS - Want to cache static resources but NOT rendered HTML

I'm working on a dynamic application where we don't want to cache HTML (i.e. cart contents can change from one page refresh to the next). To that end, I'm calling middleware that sets cache-control headers to avoid caching. However, said cache-control headers also apply when fetching static resources. For obvious performance reasons, this is undesired behavior. We def want to cache static resources. My question is this... Is there a way to set diff response headers for static resources vs rendered html? I tried passing the setHeaders option to the express.static middleware, but the thread hangs, presumably because we are trying to set the same response header twice. Any help is greatly appreciated!
Edit: adding environment information -
I'm on Express 4 and Node 4.4
Edit: adding example code. This is the relevant bit from app.js that aggressively avoids caching HTML in browser.
app.use(express.static(config.static.public));
// ...Stuff
app.use(function (req, res, next) {
// Don't cache html
res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, '
+ 'max-stale=0, post-check=0, pre-check=0');
res.set('Expires', 'Fri, 31 Dec 1998 12:00:00 GMT');
next();
});
app.use(express.static("static", {maxage : 0}))
more info
Maybe clear all ready cached files in the browser before testing.

How to make browser cache assets with express.js

I want my assets to be cached by browser. So I use:
var oneDay = 86400000;
app.use(express.static('public', { maxAge: oneDay }));
So in response I see:
cache-control: public, max-age=86400000
But when assets are requested by browser it still makes request to server and usually gets 304 not modified response and only then takes version from cache.
In response I also see 'Etag' and 'Last-Modified' headers, maybe they for such behaviour? (any why I wasn't able to get read of Last-Modified header to check it.
If I understand correctly I max-age was set in response when downloading resource for the first time, then browser while the period (set by max-age) should take if from cache and not make any request to server.
What am I doing wrong?
I wonder how people serve static assets and index files in production with express.js?

Resources