Caching SPA static assets in Grails

erichelgeson

Eric Helgeson

Posted on April 29, 2020

Caching SPA static assets in Grails

If you deploy static assets embedded in your Grails 3 or 4 apps you might notice by default they are not cached - meaning every time a user loads your site - they re-download each asset.

Grails does have a configuration to cache static assets:

application.yml

grails:
    resources:
        cachePeriod: 3600 

The problem with this is the entry point index.html is cached as well meaning users won't see updates until after the cache period has elapsed.

The solution is to add a ResourceHandler that matches index.html and sets the cachePeriod to 0

@Component // or add to resources.groovy
class SpaResolverConfig implements WebMvcConfigurer { // WebMvcConfigurerAdapter for Grails 3.x

    // Copied from the GrailsWebMvcConfigurer 
    //  - https://github.com/grails/grails-core/blob/28556c0a1a01d2958d6d3aed251dcacc2a6e38da/grails-plugin-controllers/src/main/groovy/org/grails/plugins/web/controllers/ControllersGrailsPlugin.groovy#L179-L193
    private static final String[] RESOURCE_LOCATIONS = [ "/", "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" ]

    @Override
    void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler('/static/**/index.html') // ant matcher pattern
                .addResourceLocations(RESOURCE_LOCATIONS)
                .setCachePeriod(0) // <-- no-cache
    }
}

Now css/javascript/images from the SPA are cached for 3600 seconds while the index.html file is never cached.

Note: This has no affect on assets using the asset-pipeline plugin - those are cached correctly.

Links:

💖 💪 🙅 🚩
erichelgeson
Eric Helgeson

Posted on April 29, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related