hackgvl / hackgreenville-com

HackGreenville's Website
https://hackgreenville.com
MIT License
16 stars 15 forks source link

CloudFlare Caching on App Pages, CSS, JS, and Binary Content Files #277

Open allella opened 2 weeks ago

allella commented 2 weeks ago

We have CloudFlare now in the mix for the HG domain.

This is not a big priority, but it may help as we consider new hosting for HG.

@bogdankharchenko mentioned we'd want to set some Etags in the Laravel middleware for the public-facing pages so CloudFlare has a cache invalidation method to know how / when to refresh the caching from the origin server.

For JS / CSS files, I see we have hash values worked into the paths that I suspect change automatically in the application HTML.

/livewire/livewire.min.js?id=44144c23
/build/assets/app-4ed993c7.js

Though, there are also some JS files that don't appear to have caching invalidation hashes, like /vendors/fullcalendar/packages/core/main.min.js and a couple other FullCalendar.

We could set Etags at the web host (Apache / Nginx) level, but we'd prefer for the application to handle such things so we're not dependent on server-level configuration that would break if we move hosts or servers.

For binary files, like images, it seems some of the theme images may have caching tags worked into the files, like /build/assets/hackgreenville-banner-7f39bbf1.jpg

However, there are a number of other content images, like on the homepage, which don't have hash values in the path.

For images, PDFs, and such that are content, and not part of the asset / build / theming, would we want / need to move those to dedicated block-level storage (like S3) and rely on E-tags in the response headers from the block storage host side that are set when new files are pushed up? Or, is there another way to do this for images that are more content / database related and not part of the CSS / JS building?

image

bogdankharchenko commented 2 weeks ago

JS, CCSS + Images are automatically cached by cloudflare, we only need to resolve the App Pages being cached.

We could use this package: https://github.com/spatie/laravel-responsecache

allella commented 2 weeks ago

@bogdankharchenko the questions is more about cache invalidation.

If we have images or other binary files that don't have Etags, then Cloudflare wouldn't know how / when to pull a new copy. This can be resolved by adding Etags or other headers at the server level for such files, but I know we've been talking about making the app less dependent on the server config.

Using block storage like S3 allows for setting Etags and If-Modified-Since at the service level. So, it would be possible to change values when files are pushed or changed at block storage, which would inform Cloudflare when to invalidate it's caching.

allella commented 2 weeks ago

The JS, CSS, and theme images likely aren't the issue here, since the build system puts unique hash values on the URLs or filenames as they change.

So, the main question is for other app photos that are part of the content. These images, PDFs, or similar binary files will rarely be updated, but it is a situation that would cause certain unexpected results of someone were to update a binary file and Cloudflare keeps on holding an old copy because it's not being informed to bust the cache on specific files without Etags or If-Modified-Since headers.

Again, this is pretty easy to turn on at the server level, so we could start with it, but there are other options, like the block storage angle. I was mainly wondering if Laravel or some other part of the build system was smart enough to deal with this binary file case.

allella commented 2 weeks ago

Along these lines, I see how the favicon in the View blade files using an asset() method, which doesn't seem to do anything. <link rel="shortcut icon" href="{{asset('favicon.png')}}?1"/>

Then, there are other assets, like CSS and JS files, using a @vite feature, which adds a cache invalidating hash to the URL.

@vite(['resources/css/app.css', 'resources/sass/app.scss', 'resources/js/app.js'])

Is that asset() an artifact of older code?

Also, there are some other photos referenced in the templates that aren't using the asset(), so they aren't getting unique hash suffixes in their URLs.

This is not a priority, but I was hoping to at least understand what direction we might go to make most / all of the theme images assets, if that's the "right way".

image