Caching headers on Amplify served content

0

My static site has a lot of pretty large images, but it seems that some browsers that aren't very aggressive about caching (Safari/Mobile Safari) are redownloading them on every single page load. It looks like this is due to the Cache-Control header that's being set on every response forcing no caching:

Cache-Control: public, must-revalidate, max-age=0

Is there a reason for this? I can't find anything within the Amplify console to configure the CDN, and I guess we can't see Amplify site stuff in the CloudFront or other consoles. Given that my site is entirely Jekyll-generated static stuff, I don't see how we could affect any of this from our code side.

Here's an example full set of response headers for one of the bigger images:

Response
:status: 200
Content-Type: image/jpeg
Age: 23745
Via: 1.1 5f96bc4a22f6baa91bf4a4bb246e4ff9.cloudfront.net (CloudFront), 1.1 77aa002baa7dabd52aea1d477a796cac.cloudfront.net (CloudFront)
Cache-Control: public, must-revalidate, max-age=0
Date: Thu, 11 Jul 2019 10:46:54 GMT
Content-Length: 6637216
Accept-Ranges: bytes
ETag: "95ffb7b18006c7fd8083acec30e9dd36"
Last-Modified: Fri, 07 Jun 2019 13:31:51 GMT
x-amz-cf-id: l85xjUdP13NEKmw2LfVC-cup0TP7DiGljqaf3rgqp5XKHDJmk4kFow==
x-cache: Miss from cloudfront
Server: AmazonS3
x-amz-cf-pop: IAD79-C2, BOS50-C1
pettazz
asked 5 years ago2338 views
7 Answers
0

This header on every response also seems potentially problematic?

x-cache: Miss from cloudfront
pettazz
answered 5 years ago
0

I'm seeing the same issue. Currently, I'm testing setting the "cache" option in my Amplify Console -> Build Settings to point to the src/static/media/* path. Will report back if that works!

Edit: nope, that didn't do it.

More info:
Using a CRA-based app, with Amplify CLI. No hosting set up through the CLI though -- strictly just managing hosting via the Amplify Console.

I thought I was so close with the Build Settings step...

Hope someone can clarify how CloudFront is set up for Amplify Console apps.

Edited by: warren-dev on Jul 16, 2019 10:26 AM

Final edit:

I get it! The Cloudfront setting is a feature, not a bug :) I was registering my service-worker.js incorrectly. Now that the service-worker.js is registered, it caches my assets just fine -- disregarding the CloudFront cache-control commands for those assets. Easy!

Edited by: warren-dev on Jul 16, 2019 1:51 PM

answered 5 years ago
0

Unfortunately, I'm not using the framework, just hooking my Jekyll repo directly up in the console so the setup is even more opaque to me.

pettazz
answered 5 years ago
0
answered 5 years ago
0

So the 0 ttl cache headers are on purpose, forcing the browser to always redownload every resource? That seems like it would be fine for smaller content, but given the fact that I have a lot of large images, it just makes every page load extremely heavy since none of them are ever cached locally. Chrome seems to handle this fine since it's sort of ignoring the cache headers anyway, but Safari/Mobile Safari are following the rules exactly and every page load takes a long time to fill in the image content.

Is there a way to change the cache invalidation settings, to say leave this as-is for most content but allow browser caching on specific paths (/assets/images/big_content/**)? Understanding that there may be some lag time between the deploy and ttl expiration for that particular content, I would take that over not allowing any browser caching at all.

pettazz
answered 5 years ago
0

For other's whom may need this in the future, the Amplify Console Customer Headers feature can be used to set headers, in order to let browser cache specific paths.
https://docs.aws.amazon.com/amplify/latest/userguide/custom-headers.html

answered 5 years ago
0

I went ahead and added these customHeaders to build settings file in my project (from the Amplify Console > App settings > Build Settings. (NOTE: my project is set up to add content hashes to all of these static assets, so caching them permantently is what I want.)

frontend:
  phases: …
  artifacts: …
  customHeaders:
    # cache static assets!
    # js
    - pattern: '**/*.js'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    # css
    - pattern: '**/*.css'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    # images
    - pattern: '**/*.gif'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    - pattern: '**/*.jpg'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    - pattern: '**/*.png'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    - pattern: '**/*.svg'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    # videos
    - pattern: '**/*.mp4'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]
    - pattern: '**/*.webm'
      headers: [ { key: 'Cache-Control', value: 'public,max-age=31536000,immutable' } ]

Questions:

  1. Is there a simpler way to have the pattern match—is this standard glob syntax? Can I just do: ''**/*.{js,css,gif,jpg,png,svg,mp4,webm}''
  2. Is there something I can do to also get my HTML pages to 304? I’m seeing both etag and if-modified-since request headers matching the response headers, but every time there’s the response headers server: AmazonS3; status: 200; x-cache: Miss from cloudfront
PeterFP
answered 5 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions