The Problem
I am going to outline why plugins and themes should never combine or bundle their external JS and CSS libraries. Not only is this against best practice but it can have several detrimental effects down the line.
First as a plugin or theme developer for WP our jobs is not to conserve bandwidth. That is not to say that we shouldn’t error check & minify our own assets, but our job is to provide specific features and functionality in an optimized but accessible way.
Unless your plugin is a caching or speed up type of plugin such as W3 total cache or similar your job isn’t to worry about the sites page load beyond optimizing your own code. You don’t need to combine and minify other libraries.
Let me give you an example.
Plugin A uses jQuery cookie & jQuery Transit and bundles them into a single js file called plugin-a.tools.min.js.
Plugin A then registers their script like this
wp_register_script( 'plugin-a-tools', plugin_dir_path( __FILE__ ) . '/js/plugin-a.tools.min.js' );
They may even minify it for good measure.
They do this under the guise that they are helping the site owner lower their page load times by doing this for them. Good intentions.
The problem comes when the site owner then installs Plugin B & Plugin C which look like this.
Plugin B uses jQuery Cookie which they include as the original or minified version of the official latest version from git. They save it under the name jquery-cookie.min.js and register it like so
wp_register_script( 'jquery-cookie', plugin_dir_path( __FILE__ ) . '/js/jquery-cookie.min.js' );
Plugin C uses both jQuery Cookie & jQuery Transit as well. Like Plugin A they include each library in a custom file plugin-c.plugins.js.
wp_register_script( 'plugin-c-plugins', plugin_dir_path( __FILE__ ) . '/js/plugin-c.plugins.js' );
You may already see where this is going but if not let me demonstrate.
When the scripts are loaded this is what gets loaded to the users browser.
- plugin-a.tools.js
- jQuery Cookie
- jQuery Transit
- jquery-cookie.min.js
- plugin-c.plugins.js
- jQuery Cookie
- jQuery Transit
You can see the obvious dilemma here. All the load time they may have saved the user they have also now just added themselves. You now end up with 3 separate copies of jQuery Cookie, and 2 copies of jQuery Transit.
This can not only have a major impact on the load times they were attempting to reduce, but will lead to major JS errors in a lot of cases because multiple instances of each plugin are available and colliding.
The Solution
As I said before our job is not to speed up loading. It is to optimize compatibility with other plugins and themes. In fact I dream of a world where my plugins are never incompatible.
Registering each library separately and keeping them up to date is both necessary and important.
This may not seem obvious at first glance reading through the WP codex, but there is a clearly visible design pattern in WordPress itself that shows this is the optimal way to do it, at least for WordPress products. Take the wp_register_script page for instance, specifically how they break up jquery ui into many parts rather than just jquery-ui. This is to minimize collisions. If it were meant to save loading they would simply load the full minified library instead as it would be one slightly larger request vs loading 30+ single files one at a time.
The solution is simple. If you need an external library in your product follow these guidelines:
Keep the library up to date.
All to often I see a plugin that is regularly updated, but has a 2 year old copy of jquery-cookie. Check often to see if there is a new version and update when necessary.
Register each as its own separate file with unique $handle.
Register each library with wp_register_script. Try to find other plugins that use the same library and see what $handle they use. If you don’t find one try to use one you think others might also use.
Be courteous to other authors
If another author contacts you about your $handle name being different than theirs, be courteous and try to find a common ground. Once found you can publish and persuade other authors to use the same handles increasing compatibility in the future. Until someone sets the standard there is none.
Leave combining & minification to the pros
Leave the combining and minification of the external library to the pros, the plugins developed specifically for that purpose. Include the libraries just as they come from their sources. If they include a minified version already feel free to use that.
Following these simple guidelines, plugins would almost never have compatibility issues caused by dependency libraries.
Plugin A, B & C would then all load without issues and there would be no more than 1 copy of jquery-transit & jquery-cookie loaded.