{"id":187416,"date":"2014-10-31T07:48:35","date_gmt":"2014-10-31T14:48:35","guid":{"rendered":"http:\/\/css-tricks.com\/?p=187416"},"modified":"2016-03-04T16:59:08","modified_gmt":"2016-03-04T23:59:08","slug":"taking-control-cssjs-wordpress-plugins-load","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/taking-control-cssjs-wordpress-plugins-load\/","title":{"rendered":"Taking Control of the CSS\/JS that WordPress Plugins Load"},"content":{"rendered":"

The other day on ShopTalk a question we got led us down a short tangent on WordPress plugins, the resources they load, and what that would look like in a perfect world. I ended up writing up some thoughts<\/a> on it and getting some feedback. I think it came to a somewhat satisfying conclusion so I figured I write it up.<\/p>\n

<\/p>\n

How Some Plugins Work Now<\/h3>\n

Let’s take a real-world example. The WP-Polls plugin<\/a>. I think it’s a nice plugin. Does a good job with polls. I use it here on CSS-Tricks.<\/p>\n

To put those polls on your site, it needs some JavaScript to handle the functionality (i.e. voting and seeing results without a page refresh) and CSS to style the poll widget (the results bars and whatnot).<\/p>\n

The way that it adds that CSS is by injecting a stylesheet via the wp_head()<\/code> hook, putting this in the <head><\/code>:<\/p>\n

<link rel='stylesheet' id='wp-polls-css'  href='http:\/\/example.com\/wp-content\/plugins\/wp-polls\/polls-css.css?ver=2.67' type='text\/css' media='all' \/><\/code><\/pre>\n

The way it adds that JavaScript is by injecting a script via the wp_footer()<\/code> hook, putting this near the bottom of the document:<\/p>\n

<script type='text\/javascript' src='\/\/example.com\/wp-content\/plugins\/wp-polls\/polls-js.js?ver=2.67'><\/script><\/code><\/pre>\n

That makes sense. That’s what they need to do to make this plugin work. Plugin authors need to make sure their plugins are easy to use and work<\/em>.<\/p>\n

As a performance-concerned developer, I want to concatenate scripts and styles.<\/h3>\n

Now we have these two single-purpose resources being loaded on the page. When you look into web performance and how to make websites faster, some of the first advice you hear is to concatenate resources. Very good rule of thumb: the less resources a website needs to load, the faster it will be.<\/p>\n

Concatenating resources isn’t some obscure thing only the most elite websites need to worry about. It’s an every website problem. People have tackled this problem in a million ways. CSS sprites were all about concatenating image resources. Icon fonts and SVG sprites are solving that same problem. CSS preprocessors help you concatenate your stylesheets. The Rails Asset Pipeline helps you concatenate resources. There are Grunt and Gulp plugins galore that are designed for this. <\/p>\n

But we’re in WordPress land here, so we solutions for that.<\/p>\n

Should plugins themselves help?<\/h3>\n

The first idea I thought of was that plugins should allow us to dequeue anything they enqueue from UI they add to the plugin itself. Even go so far as<\/a> to provide the resources they would have loaded for you in a textarea for easy copy-and-pasting into your own system. <\/p>\n

I now think that was a little misguided. It would take a major movement in the WordPress plugins world to get this going. Even if that happened, that’s a lot of duplicate effort, and this issue can be handled more efficiently. <\/p>\n

Solution #1: Use a Plugin<\/h3>\n

The plugin MinQueue<\/a> offers a solution I like. It doesn’t do anything automatically, it allows you to configure what resources you want concatenated and in what order.<\/p>\n

With the plugin active, in the Admin Bar on the front end you’ll see a little helper link you can click.<\/p>\n

<\/figure>\n

In our demo, I know I want to concatenate our theme’s CSS and WP-Polls CSS together. So I take those names from the helper and put them into a new “queue” in the plugin settings.<\/p>\n

<\/figure>\n

Now neither of those CSS files loads individually anymore. MinQueue creates a combined (and cached) version and serves that:<\/p>\n

<link rel='stylesheet' id='minqueue-117c22aa-ebc80003-css'  href='http:\/\/example.com\/wp-content\/uploads\/minqueue-cache\/minqueue-117c22aa-ebc80003.css' type='text\/css' media='all' \/><\/code><\/pre>\n

You can create multiple “queues”, which gives you a good amount of control. For instance, perhaps a subsection of your site loads different resources, those could be combined separately if you wish, it’s not required you concatenate them with the main group.<\/p>\n

Note that this means you’ll need to enqueue<\/a> your theme’s stylesheet, but that’s pretty easy.<\/p>\n

Also note the popular W3 Total Cache does concatenation too, but I find it a bit more confusing. You add stylesheets via URL’s and it seems a bit more basic and easy to break.<\/p>\n

Solution #2: Manually dequeue assets and concatenate yourself<\/h3>\n

Plugins that add resources do it through wp_enqueue_script and wp_enqueue style. You can dig through their plugin code and find where they do that, so you can see what name they applied when they did it. Then, in your own theme’s functions.php file (or custom functionality plugin), you dequeue them.<\/p>\n

Justin Tadlock has a post about this<\/a> can you can read. Simple example of dequeuing one stylesheet:<\/p>\n

add_action('wp_print_styles', 'my_deregister_styles', 100);\r\n\r\nfunction my_deregister_styles() {\r\n  wp_deregister_style('name-of-style');\r\n}<\/code><\/pre>\n

Now it’s on you to go find that resource and concatenate it into the CSS you are still loading on the page yourself. Perhaps you’re using a CSS preprocessor and you can @import it. Perhaps you’re using a task running like Grunt can can add it to the list to files to go get and concatenate. Or go fully manual and just copy and paste it’s contents into your own stylesheet (just be aware if you do this you don’t get updates when the plugin updates).<\/p>\n

Solution #3: Use a plugin to dequeue assets and concatenate yourself<\/h3>\n

While I’m capable of digging through a plugin’s code to find instances of enqueuing resources, that doesn’t seem like a fantastic approach to me. I’d rather do it programmatically, making it easier and reducing human error.<\/p>\n

During the earlier discussions happening around this, Nate Wright<\/a> of Theme of the Crop<\/a> cooked up a brand new plugin for this called Asset Queue Manager<\/a>. It has a UI you use (from the front end) for you to easily dequeue assets.<\/p>\n

From the front end of the site, you click a link in the Admin Bar to reveal a dropdown of all the enqueued assets on that page.<\/p>\n

<\/figure>\n

There is a button for dequeuing that asset. The plugin will keep that asset dequeued until you say otherwise. Now again it’s on you to go concatenate that into your stylesheets however you wish. There is another button there that links directly to the resource, making it super easy to find. Pretty cool!<\/p>\n

Conclusion<\/h3>\n

There are plenty of ways to wrangle control of the CSS and JavaScript that WordPress plugins can load. You can and should do this, with the urgency increasing for each unconcatenated resource. <\/p>\n

How many resources files of each type OK to load? One, Two or Three.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"

The other day on ShopTalk a question we got led us down a short tangent on WordPress plugins, the resources they load, and what that would look like in a perfect world. I ended up writing up some thoughts on it and getting some feedback. I think it came to a somewhat satisfying conclusion so […]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"c2c_always_allow_admin_comments":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":18362,"url":"https:\/\/css-tricks.com\/wordpress-plugins-i-use\/","url_meta":{"origin":187416,"position":0},"title":"WordPress Plugins I Use","date":"September 19, 2012","format":false,"excerpt":"I think this is a fun and useful style of post that any WordPress blogger can do. It's always interesting to hear in what ways people are extending what WordPress can do out of the box. I'll share the ones I'm using here on CSS-Tricks then you can share yours\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":210321,"url":"https:\/\/css-tricks.com\/wordpress-plugins-we-use-3rd-edition\/","url_meta":{"origin":187416,"position":1},"title":"WordPress Plugins We Use, 3rd Edition","date":"November 4, 2015","format":false,"excerpt":"Ever wonder what's running under the hood here at CSS-Tricks? Well, it's been a while since we last shared the WordPress plugins used here on the site, and even longer since the time before that. We figure it's high time to pop the hood once again and see what's new\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":311924,"url":"https:\/\/css-tricks.com\/jamstack-news\/","url_meta":{"origin":187416,"position":2},"title":"Jamstack News!","date":"May 29, 2020","format":false,"excerpt":"I totally forgot that the Jamstack Conf was this week but thankfully they\u2019ve already published the talks on the Jamstack YouTube channel. I\u2019m really looking forward to sitting down with these over a coffee while I also check out Netlify\u2019s other big release today: Build Plugins. These are plugins that\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2020\/05\/netlify-build-plugins-1.png?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":297293,"url":"https:\/\/css-tricks.com\/wordpress-plugin-overload-give-jetpack-a-try\/","url_meta":{"origin":187416,"position":3},"title":"WordPress Plugin Overload? Give Jetpack a Try!","date":"October 15, 2019","format":false,"excerpt":"The WordPress ecosystem has a plentiful supply of plugins that offer everything from AMP to Zapier integration and so, so, so many other things in between. It's a significant contributor to what makes WordPress great because plugins can account for the needs of nearly any website. How many plugins are\u2026","rel":"","context":"In "Sponsored"","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/css-tricks.com\/wp-content\/uploads\/2019\/10\/jwtpack-blocks.jpg?fit=1200%2C600&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":243538,"url":"https:\/\/css-tricks.com\/wp-rest-api-remote-control-wordpress\/","url_meta":{"origin":187416,"position":4},"title":"The WP REST API for Remote Control WordPress","date":"July 13, 2016","format":false,"excerpt":"At my day job, we have about 1,000 sites spread across 30 WordPress multisite installs. The installs all run many of the same plugins and settings, especially at the network level. This causes a lot of wasted time for our staff: They have to manually repeat the same settings across\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":600,"url":"https:\/\/css-tricks.com\/trying-openid-and-my-other-wordpress-plugins\/","url_meta":{"origin":187416,"position":5},"title":"Trying OpenID… and My Other WordPress Plugins","date":"March 8, 2008","format":false,"excerpt":"I get the question from time to time what plugins I use on this blog. Since I just got through installing a brand new one (Open ID), I thought this might be a good time to run through the list. \u00a0 RSS \/ Feed Related FeedBurner Feed Smith I \"burn\"\u2026","rel":"","context":"In "Article"","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/187416"}],"collection":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/comments?post=187416"}],"version-history":[{"count":5,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/187416\/revisions"}],"predecessor-version":[{"id":187450,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/posts\/187416\/revisions\/187450"}],"wp:attachment":[{"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/media?parent=187416"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/categories?post=187416"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/css-tricks.com\/wp-json\/wp\/v2\/tags?post=187416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}