Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable image caching in development mode in Rails 3.1

In Rails 3.1 development mode (when using the asset pipeline), images served out of assets/images are served up with the response header "Cache Control: must-revalidate".

This means that Google Chrome (and seemingly only Chrome) will attempt to re-fetch images numerous times—even during a single page view. This has resulted in screwy issues with all manners of DOM manipulation via JavaScript. To name a few:

  • jQuery UI Draggable sometimes features a dramatic offset from the mouse cursor
  • Adding or removing a CSS class that references an image will flash or resize while the image request (which will always return a 304 not modified) is underway.
  • Attaching or replacing HTML nodes that contain images will trigger more image fetches which will cause the entire tree of nodes underneath them to flash stutter as Chrome waits for the 304 response for each image.

I can completely understand that to be a reasonable thing for a development server to do. I can even understand that Chrome's refusal to cache the image, even inside a single page view, is perfectly reasonable.

So, is there a way to change the Cache Control header that Rails applies to image responses in development?

Update: as suggested by a couple people, an even more interesting question is why does Chrome attempt to re-fetch the images multiple times within a pageview when no other browsers seem to? (And why isn't this causing issues for other developers?)

Update x2: I'm not going to submit this as an answer because it's just a workaround that happens to be sufficient for my purposes, but we were able to get around this issue by precompiling assets and then discarding the precomplied CSS & JS. (This will require sprockets debugging to be turned to false in development.rb.)

rake assets:precompile
cd public/assets
find . -name "*.js*" -exec rm -rf {} \;
find . -name "*.css*" -exec rm -rf {} \;
like image 295
Justin Searls Avatar asked Jan 18 '12 20:01

Justin Searls


1 Answers

The only way I've seen to manipulate the Cache-Control header for assets is by configuring static assets with:

config.serve_static_assets = true

config.static_cache_control = "public, max-age=3600"
like image 53
Mitch Kett Avatar answered Oct 23 '22 03:10

Mitch Kett