WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 3 months ago

#28557 closed enhancement (wontfix)

Add Theme/Plugin-Version to URL not the WP-Version

Reported by: Drivingralle Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Script Loader Keywords: 2nd-opinion
Focuses: template Cc:

Description

If a theme- or plugin-developer doesn't provide the argument for the version number while using any enqueue-function (wp_enqueue_style, wp_enqueue_script) WP adds it's own version number to the URLs.

This leads to the problem:
A theme is updated, adding new styles including some changes to the generated HTML. If WP is not updated at the same time, browser and proxies will not re-download the file. This can break layouts because of the lack of updated stylesheet.
The same goes for plugins.
And if WP is updated all scripts and styles are re-downloaded. Which is not required.

I would like to see the following behavior:
If the version argument is set, use it.

No Argument, use the fallback:

  • Styles/scripts enqueued by the theme get the version number of the theme.
  • Styles/scripts enqueued by a plugin get the version number of the plugin.
  • Files enqueued by/from core should still use the core version (e.g. jQuery).

I use this code in my themes. So there is a variable for the theme version.

// Save same data about the theme into a variable
$my_theme_data = wp_get_theme();

// Enqueue a CSS style file
wp_enqueue_style(
    'child_style',
    get_stylesheet_directory_uri() . '/style.css',
    array(),
    $my_theme_data->Version
);

To solve:

  • how to detect if theme, plugin or core is enqueuing the file
  • how to get the version number of a plugin
  • what to do if a plugin and a theme or two plugins are enqueued with the same handle

Aside thought on it:
Adding the version of WP and the theme to the stylesheet-url or maybe a hash of it. Woldn't solve it for plugins ...

Attachments (1)

28557.diff (1.1 KB) - added by Kau-Boy 2 years ago.

Download all attachments as: .zip

Change History (8)

#1 @johnbillion
3 years ago

  • Component changed from Media to Script Loader
  • Keywords 2nd-opinion added

I agree that this should be the case, but I suspect we'll have to leave it as it is currently because there is a certain overhead to determining the plugin or theme version number (by reading and parsing the header section of the plugin or theme).

If someone wants to do some benchmarks on the actual overhead of calling get_plugin_data() (for multiple plugins) and get_theme_data() on each page load then that would be a good place to start.

#2 follow-ups: @SergeyBiryukov
3 years ago

Instead of making a simple fallback more complicate, I think we should educate theme and plugin developers to always provide the version argument.

#3 in reply to: ↑ 2 @jdgrimes
3 years ago

Replying to SergeyBiryukov:

Instead of making a simple fallback more complicate, I think we should educate theme and plugin developers to always provide the version argument.

We could even go so far as giving a notice when it is not supplied.

Replying to johnbillion:

If someone wants to do some benchmarks on the actual overhead of calling get_plugin_data() (for multiple plugins) and get_theme_data() on each page load then that would be a good place to start.

Running it for three plugins I got times ranging from 0.0017 to 0.0025 seconds. This is with the Blackbox profiler showing total times from 1.5-3.3 seconds. Running this locally, with maybe 10-15 plugins installed.

#4 in reply to: ↑ 2 @Kopepasah
3 years ago

Replying to SergeyBiryukov:

Instead of making a simple fallback more complicate, I think we should educate theme and plugin developers to always provide the version argument.

I second this motion. Lately I've been following the practice of using dates for CSS and JavaScript files I've created and maintain. For other, external libraries I've used the version of that particular library.

I think educating theme and plugin developers is solution that will not cause unnecessary overhead.

#5 @Kau-Boy
2 years ago

  • Keywords has-patch added

A very basic solution to this issue, I used in another project is to use the file/folder change time as a unix timestamp as an alternative parameter. In unix systems, as soon as any file within a folder changes, the function filemtime() for that folder would update. So using this on a folder as wp-content would maybe invalidate the cache more ofter than necessary, but it will invalidate the cache for any change on a CSS or JS file, as soon as any file has changed.

Attached to this ticket, you may find a simple patch for that idea, keeping the WP version for Windows systems.

(Unforunately the wp_enqueue_script() function does take the URL and not the file path, as otherwise it would be quite simple to just check every invidiual file.)

Worked on at #wceu :)

@Kau-Boy
2 years ago

#6 @hinnerk
22 months ago

Thank's @Drivingralle for figuring that out!
@Drivingralle's approach is using wp_get_theme() which is using the cached 'Version' of a WP_Theme object that might be created in every page call, anyway. @johnbillion is mentioning get_theme_data() having a performance issue - but get_theme_data() is deprecated, anyway.
Anything that I misunderstand regarding any performance issue using wp_get_theme()?

#7 @dd32
3 months ago

  • Keywords has-patch removed
  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

Calling filemtime() multiple times on each pageload isn't an option, nor can you rely upon it being a cascading timestamp update (not all filesystems do).

IMHO it's up to the plugin or theme to specify the version parameter here for cache-busting. The main issue is performance - not just of how to get the data, but determining that a resource is being enqueued by a specific plugin or theme.

If you run into a problem caused by this, tell the plugin or theme author that they should bump the cache busters on their enqueued resources during updates - that's what the parameter is for.

Note: See TracTickets for help on using tickets.