问题
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 {} \;
回答1:
http://code.google.com/p/chromium/issues/detail?id=102706
This seems to be a documented issue with chrome. I'm suffering from the same problem: 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.
回答2:
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"
回答3:
Sprockets is either going to send caching headers or force revalidation (see the source).
I can see no publicly available options to change this behavior.
To modify this I think you will have to monkey patch Sprockets.
Possibly of greater interest is why Chrome is behaving in that way?
回答4:
You dont need to compile assets into public/assets and remove *js *css to cache images
you can cache image in rack, https://github.com/mvj3/rack_image_assets_cache_control
来源:https://stackoverflow.com/questions/8916813/enable-image-caching-in-development-mode-in-rails-3-1