Problem/Motivation

When an image style is edited, the old, stale images are visible for up to 2 weeks (the default expires header).

To reproduce:

  • Install drupal
  • Create an article node with attached image
  • Add a "desaturate" effect to the "medium" image style
  • Return to the home page

Expected result: a desaturated image.
Actual result: the original image.

The problem can be observed without any proxies or caches, but is particularly troublesome when an HTTP cache is in use. Some services like CloudFront don't support directory purges, so it's difficult to invalidate the old images.

The issue is also an obstacle to raising the default expires value (YSlow's definition of "far future" is up to ten years).

Proposed resolution

Add a query string in image_style_url().

The current patch uses a timestamp of when the style was saved, but an alternative would be a hash of the style's config data.

The advantage of the timestamp is no extra CPU work is needed to compute a hash. A hash would be more merge-friendly for VCS, since it doesn't need to be stored in the yml file.

Remaining tasks

patch needs review

User interface changes

N/A

API changes

N/A

Original report by drupaljoe

I am displaying some images with theme('image_style').

Even if the image is changed, it is being cached on browsers and they are forced to hit CTRL-F5 for it to update. Is Drupal core doing anything to counter this? (e.g. timestamps after the image filename)

CommentFileSizeAuthor
#7 1514760.patch6.17 KBgrendzy
#5 1514760.patch2.04 KBgrendzy
#3 1514760.patch2.06 KBgrendzy

Comments

fenda’s picture

So it looks like this isn't in core. I'm adding REQUEST_TIME to the end of the image path to force a browser cache refresh.

However, for example, image.png?123 is writing as image.png%3F123 in DOM.
Any ideas how to fix the question mark being encoded?

grendzy’s picture

Title: Image style browser cache » Image style URLs should change when settings are updated
Version: 7.9 » 8.x-dev
Category: support » bug

It should be possible to hash the effects settings, and add that as a query string:

drupal_hash_base64(serialize($style['effects']));

image_styles() uses a static cache so calls to image_style_load() (needed to get the effects settings I think) would not be expected to add extra database overhead.

Considering that Drupal automatically purges the directory when the form at admin/config/media/image-styles/edit/%style is submitted, it seems clear the intention is to update existing files so I think the caching problem is a bug.

grendzy’s picture

Status: Active » Needs review
StatusFileSize
new2.06 KB

Status: Needs review » Needs work

The last submitted patch, 1514760.patch, failed testing.

grendzy’s picture

Status: Needs work » Needs review
StatusFileSize
new2.04 KB

Status: Needs review » Needs work

The last submitted patch, 1514760.patch, failed testing.

grendzy’s picture

Status: Needs work » Needs review
StatusFileSize
new6.17 KB
grendzy’s picture

Title: Image style URLs should change when settings are updated » Add a query string to Image Style URLs to prevent stale data when settings are updated
Issue tags: +Performance, +WPO

Clarifying the title slightly: The path component of the URL wouldn't change with this patch, so old links (even with a stale query string) keep working.

grendzy’s picture

Issue summary: View changes

add template

grendzy’s picture

Issue summary: View changes

far-future

grendzy’s picture

Issue summary: View changes

typo

anavarre queued 7: 1514760.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 7: 1514760.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

steven jones’s picture

We already have a query string that works as a cache buster on image derivatives: the itok security token in the URL, so this could be expanded to add in a hash of the config of the image style.

steven jones’s picture

Some thoughts:

  • At the moment, as a 'workaround' if you change an image style then you might want to rename the image style before deploy. That will ensure that all the URLs change
  • Drupal core is making a big assumption:
    • Nothing will cache downstream of the web server hosting the Drupal site, or anything that does will revalidate the requested URL.

    However, a lot of web servers will allow client browsers to cache static assets like images for a decent length of time, without revalidation and a lot of CDNs, Varnish etc will be configured to cache based on the URL with a long cache expiration time.

  • We can add a cache buster to generated image style URLs or indeed build it into the itok token, ideally this would cause the URL to change when:
    • The image style config is changed.
    • The image style is flushed for all images.
    • If an individual file in the derivate style is flushed (ideally this would only bust the cache of this single image)

    A cache buster could be as simple as a monotonically increasing integer that's incremented on the above events, and simply added to the URL generated. The last event in the list above would cause a lot of unnecessary cache busting on a site where derivative flushing was common, and thus high cache misrates on downstream caches etc. But that might be acceptable for most sites.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

krzysztof domański’s picture

Status: Needs work » Closed (duplicate)
Related issues: +#2313539: Allow cache busting string in theme_image