Share this:

Technorati ReddIt Favorites

How to optimize plugin loading

Few weeks ago I have tested 35 plugins to find how they affect WordPress in terms of loading and resource usage. What can plugin author do to make plugin loading faster, to use less memory and to lower its impact on website loading? There are several things to consider.

Notice: This tutorial is primarily for plugin developers, but it can be useful reading for anyone working with WordPress to better understand how plugins load and what can be done to improve it.

Intro

Before we go on, I recommend you to take a look at the article with test results. I know that many readers were surprised by the results, considering how some high-profile plugins scored very low and ended up in the bad optimized plugins category. Optimization will take these plugins one step further, showing that author cares about used resources (most WordPress websites are on shared hosting, and resources can be very limited), and that author understands that optimization is as important as adding features and making plugin look pretty.

So, what plugin authors can do to make their plugins better, how to optimize their loading, resource usage and with that speed? Before I list recommendations for this, here is a small analysis of how plugins are loaded.

Plugins Loading

One of the early steps in the WordPress loading is to load plugins. WordPress will get the list of all active plugins and it simply use PHP include function to load main plugin file. That main plugin file can contain the plugin (for smaller plugins or widgets), or it can be used as plugin loader to initialize plugin, or it can be the mix of the two. WordPress will do this for every single page, it will always include active plugins.

Even if the plugin is small, this can be an issue. For instance, my GD Unit Converter plugin was used in the benchmark article. This plugin adds a widget on the admin dashboard, and that’s it. But, if you look at test results it was using 0.5MB on admin side and 0.4MB on the front end side. And it was doing nothing on front end side! So, I changed the main plugin file to act as a loader only. It will check if we are on admin side, and it will load another file that actually contains plugin. If we are on front end side, it will do nothing. After this optimization, on front end side plugin uses now 20KB, that is 95% memory saved. That is amazing gain, but you can’t expect such results for every plugin.

If you look at the test results again, even smallest plugins will use 0.4MB to 0.5MB. Imagine that you have 20 such plugins, and if all 20 of them save just 0.2MB, that will lower memory usage by 4MB, and will improve speed a bit. That might not look like a lot, but trust me, it will make a difference, especially for shared hosting websites.

Most plugins have a specific usage, and that requires plugin to be loaded only on some pages. In some cases you will need parts of the plugin functionalities loaded on every page. It can be very complicated to decide the need for plugin on each admin or front end page. But, you need to recognize what parts of the plugin are always needed, and what parts will be specific to some of the pages. That basic analysis will help you to decide what pieces of code go into separate files. If your plugin is only for the administration, it doesn’t need to be loaded on the front end. It is very simple to check this in the loader file and to prevent loading of the rest of the plugin.

If your plugin ads administration side pages or forms, you will need to load CSS styles or JavaScript files. Too many plugins these days are making a very big mistake of loading these files on every administration page without checking if the page belongs to the plugin. That will most likely break other plugins or change the styling for other plugins, or even WordPress. This is one of the things that must be optimized and done properly.

Files and folders organization

One of the most important things with any plugin, is organization of files and folders with code, CSS, images, JavaScript. When you make right structure for files and folders, you will make it easier to make future changes and perform maintenance.

  1. Code should be split into files according to functionalities. Many plugins don’t have that strict code separation, and they end up with large files with functions and classes thrown in. This makes later changes and maintenance harder, because code has no logical structure or order. Also, big files will use more memory, even if most of its functionality will not be used at all.

    Code Folders

    Code Folders

  2. HTML forms should be separated from files with code. These forms will be loaded only on some pages, and they will contain mostly HTML markup code (they can contain PHP code, and usually do, but only used to fill HTML elements with data), and they should be kept outside of the main plugin code.
  3. Create few folders for different files types for your plugin. Main plugin code should go in one folder, files with HTML forms should go into another folder, CSS styles and JavaScript should go in own folder and images should go in own folders. On the image on the right you can see a folder structure for one of my plugins. I like adding extra sub folders for ‘code’ and ‘forms’ depending on how many forms there are or how much code. In ‘code’ folder it is recommended to have another level of folders if you have a lot of files.
  4. If you have a lot of JavaScript or CSS files, it is good to have source versions for them as well as minified versions. This way they will be lighter on load, and you will have source versions for debugging and development.

Preparing for Optimization

To make the most of the loading process, you need to know what page are you on. Based on that you can perform different operation and load different files. Make sure you set a variable with the page file name or some other identification. On admin side, WordPress pages are identified by the file name loaded. Your own plugin pages can be identified by the ‘page’ variable from the URL request . To get the name of the file, name of the page and more, you can use this code:

$_current_file = end(explode("/", $_SERVER["PHP_SELF"]));
$_current_page = isset($_GET["page"]) ?  $_GET["page"] : "";
$_doing_ajax = defined("DOING_AJAX") && DOING_AJAX;
$_doing_cron = defined("DOING_CRON") && DOING_CRON;

Based on this values you can pretty much know exactly which page is loaded, and what you need from your plugin to load. This can be executed in the main/loader plugin file. I have added two more variables to determine if the page is loaded for AJAX handling or while doing Cron job.

Optimization Recommendations

Here are some of the important recommendations you should follow:

  1. Analyze your plugin code, and decide what you need loaded on admin side, what on front end, and what on both. When you do that, you can go further and decide what you need loaded on all admin pages, and what on some of them (your plugin panels). Based on that, you will end up with many smaller files. Make some convenient naming scheme so that you can easily find files and use them in loader.
  2. Always use main plugin file as loader. Even for simple plugins, this is best solution because you will have easier time later to expand the plugin. Don’t keep any code that is used by the plugin there, only decide what parts of the plugin you need to load.
  3. Try to use classes as much as you can. Also, try to have only one class in a file, or at least put classes that depend on each other in one file. Use some logical naming convention for files, so that name gives you quick association to the class inside. PHP can help you with auto loading of files based on the required class, and you can find more info on that at the end of this tutorial.
  4. Separate all AJAX handling code into own file. When your plugin on the server-side needs to handle AJAX requests, don’t add all that into file that is always loaded. It is easy to decide if the WordPress is loading to handle AJAX request, and only then load AJAX handling file. This goes only if the AJAX is handled by the WordPress admin-ajax.php file.
  5. Always handle all AJAX calls through WordPress admin-ajax.php. This will save you a lot of headaches, and it can be used for both front end and admin side. Making your own handler file for AJAX is never good idea. If you need help with using admin-ajax.php, here is a good post in the WordPress.org Codex on using AJAX in plugins.
  6. Separate all Cron jobs handling code into own file. Similar to AJAX handling, Cron jobs executions are run in own page/thread call, and you can always determine if that is the case. If you have cron jobs in your plugin, move all its handling functions and classes into files that will be loaded only when Cron job is executed.
  7. Any other code elements that are needed for some panels only, or in some specific cases, keep in own file(s) and load them only when needed. This can be code that handles individual panels, AJAX handling, CRON handling, saving data… The better you identify what you need and make smaller files to load when needed, you will get better optimized files.
  8. Handle all plugin settings through WordPress options database table through get_option/update_option functions (or get_site_option/update_site_option for multisite network wide settings). Never save individual settings as separate options, this can create a mess and will be hard to update and maintain. Put all your settings in one or more array’s (depending on the scope of settings you have). These settings are all loaded with a single SQL query when WordPress loads, and you have them ready when your plugin loads.

PHP Auto Loading

PHP has several methods to trigger automatic loading of files, based on the required code. If you split your code into classes, you can set up autoload functions that will do loading of files based on the class name. This can be very good solution for a plugin that has many classes used as modules, or used only in some cases. It is recommended to have one class in one file. More info about this you can find here: Autoloading Classes on PHP.net. Comments on that page have some really great examples on how the auto loading works.

GD Press Tools Pro Debugger: Snapshots

GD Press Tools Pro Debugger: Snapshots

Measuring the optimization

My GD Press Tools Pro plugin can be used to debug and track WordPress loading. Tracker in this plugin has functions you can use to create snapshots that will contain used memory, hooks, SQL queries and time. You can use these functions in your code to measure how much resources some are used during different stages in the loading process. Plugin has a lot of other things to help you debug the code, find errors, track loading, track WordPress query, enqueued scripts and styles and much more.

There are some other plugins you can use to debug WordPress, but no other plugin allows tracking of the loading and the level of detail as GD Press Tools has.

Conclusion

There are many things you can do to optimize your plugin to use less memory and to load faster, and to have less impact on overall loading of WordPress. This article doesn’t cover everything and you will not be able to use all the recommendations for every plugin. But, good analysis, good code splitting and loading and tracking your optimization progress will always give you good results. Better optimized plugin is later easier to support and expand.

22 Responses to “How to optimize plugin loading”

  1. pestaa | January 11, 2012 at 22:29

    Horrible advice, sorry.

    #1 – Make your main file a loader? Really? Now you have two problems. If a functionality fits one file, it should go into one file. There’s no excuse “but it’ll grow”. When it does, add more files.

    #2 – Use classes everywhere and put them in separate files? How is that even a performance advice? If your stuff’s mental model is best represented as a class, then by all means use a class. If not, it’s just stupid complexity.

    Sorry again, I stopped reading the article at this point.

    I’ll tell you the holy grail of performance advice for all kinds of software right here, right now, for free: do NOT query the database unless you absolutely positively must have to.

    Nothing else matters in 99% of the cases.

    • MillaN | January 11, 2012 at 22:33

      I am developing in PHP for more than 10 years and some 4-5 in WP, and all things I have written here are always been helpful, so I decided to share it. These are just advices, take it or leave it, no one forces anyone to do it this way.

    • Dean Hall | January 13, 2012 at 05:58

      I think pestaa is missing the point, but I’m not sure MillaN made it well. The general idea of your post, I think, is this: “Load selectively” or “Don’t load unnecessary code”.

      Certainly database queries can be extremely expensive both in I/O on the database (often on the same server) and in execution time, but on most web server environments running PHP, the general principle of “load selectively” or “don’t load unnecessary code” is still very important, especially on systems not running FCGI with an opcode cache (e.g., mod_php on Apache)—or even then, when the opcode cache is maxed out on memory, which is likely to be the case on many shared hosts.

      We’re talking about the PHP interpreter re-interpreting code for every request to WordPress, which might be as low as a few but could be as high as millions of times a day. Some of these users may be running a caching plugin, but most won’t. As plugin authors, we can’t ignore any use case and have to attempt to optimize for the worst cases, many of which are unfortunately common.

      Selective code-loading for those thousands or millions of requests a day can make a HUGE difference in the number of simultaneous requests the web server can serve, the speed at which it serves them, disk I/O, RAM usage, etc. And so it can mean the difference between getting kicked off your shared host or not—or between staying on a 512MB cloud server and paying a lot more for multiple servers and load-balancing. These decisions really do affect people’s lives. Most people have no idea how to track these problems down; our plugins shouldn’t contribute to their headaches.

      • MillaN | January 13, 2012 at 10:33

        Thanks for the comment Dean. Many tech users are neglecting the fact that most users of WordPress are on shared hosting where every MB counts. As you say, let at least have plugins that we can be sure of to not cause problems with the server by using too much of its resources.

      • pestaa | January 13, 2012 at 11:37

        Dean, WP is already pulling in tons of PHP and making several DB queries for each request that hits the backend, so “loading selectively” in a plugin is just makeup on a pig.

        If you need scalability, you need to decrease the amount of system calls, yes. But if I need to choose between a plugin that saves 3, or a caching extension that saves 300, I’m not going to hesitate.

        Not knowing bytecode caches is no excuse and it is not the plugin’s author’s responsibility to account for that. If you need to scale to millions of rpm, a shared hosting will choke anyway.

        Furthermore, a plugin is not installed/activated unless it needs to be plugged in, so why make the case worse and spread out the code in multiple files, “just for optimization’s sake”?

        Also let me add that if a site reaches that scale by anything but accident won’t use my or your plugin.

        • Dean Hall | January 13, 2012 at 15:48

          All software has an audience, and the WordPress audience is vast. WordPress is popular because it’s a free tool that makes publishing easy for millions without any particular technical knowledge except using a web browser. That’s the audience most plugin authors write for, and those authors are who this article is for.

          That includes users on shared hosting, small VPSs, large VPSs, dedicated servers, load-balanced environments, and perhaps even globally load-balanced environments. Focusing mostly on the most common context, shared hosting, is a smart move—but assuming that just because a WordPress blog is popular that it won’t be using your plugin is a mistake too. (I manage servers for several sites like this.) Assuming your plugin will only be run by technical users on servers with ample resources is silly.

          > [A] plugin is not installed/activated unless it needs to be plugged in[.]

          MillaN wrote: “One of the early steps in the WordPress loading is to load plugins. WordPress will get the list of all active plugins and it simply use PHP include function to load main plugin file.” I believe he’s absolutely correct here. *All* activated plugins get loaded for *every* request, even admin requests. (Please correct me if I’m wrong, folks.)

          • MillaN | January 13, 2012 at 16:17

            Yes, all plugins that are activated on the Plugins panel are loaded for each request, including AJAX and CRON loading modes. They are all loaded before the theme. How they will affect the WordPress is up to the plugin and its developer. That is way optimization is very important step, make sure that even users running website on cheap shared hosting servers can use it and not fear that they will run out (what limited) resources they have.

  2. Julian Knight | January 17, 2012 at 10:43

    Thanks for this MillaN, very useful.

    One small issue with your example PHP code though – you should be using single quotes not double. Double quotes force PHP to evaluate the text for contained variables. Small point but as this article is about efficiency, the example code should also be efficient!

    Regards, Julian.

    • MillaN | January 17, 2012 at 10:47

      Thanks for pointing this out. To be honest, I use mixed quotes in my code and I should make changes when I notice this.

  3. rilwis | March 24, 2012 at 18:34

    I haven’t known about this great article until today. Very smart! I’ll apply these techniques in my plugins. Thanks for sharing.

  4. abdussamad | January 2, 2013 at 20:26

    About number 8, from what I understand WordPress loads all options using this SQL:

    SELECT option_name, option_value FROM $wpdb->options WHERE autoload = ‘yes’

    (You can find it in wp-includes/options.php )

    So it’s just one query. Basically it’s a case of choosing between:

    1. Multiple options stored in separate rows – return more rows

    2. Serialized options stored in less number of rows – return fewer but larger rows

    Does returning more rows vs. larger rows result in higher memory usage? I don’t think so. How could it! I bet the difference is negligible.

    OTOH, storing options in separate rows is natural if you are coding in an OOP way. The options framework I coded does that. It also has an autoloader and uses separate class files.

    • MillaN | January 3, 2013 at 11:03

      Hello,

      With any query, you need to limit data returned to minimize memory usage. With this table and values in it, it is not that critical, but I know of different cases, where plugins would store large amount of data, resulting in increase memory usage when page loads. And it has not difference if plugin creates one ow for all its settings as array, or hundred rows for individual settings. First solution is better, since it keeps table looking neater since less records are used, and you can see what each plugin uses, and in case when you need to remove plugin, you can find its records easier. And it minimizes the possibility of two plugins using same name for option name.

      Milan

Trackbacks/Pingbacks

  1. Tweet-Parade (no.1 Jan 2012) | gonzoblog.nl - January 7, 2012

    [...] How to optimize plugin loading - So, what plugin authors can do to make their plugins better, how to optimize their loading, resource usage and with that speed? Before I list recommendations for this, here is a small analysis of how plugins are loaded. [...]

  2. WordPress Plugins – Pros and Cons | Homestead Host - January 11, 2012

    [...] dev4press site also has a tutorial for optimizing plugins which has some excellent information for the intermediate to advanced WP [...]

  3. How to optimize your WordPress plugins | WPCandy - January 11, 2012

    [...] You are here: Home > Links > How to optimize your WordPress plugins PermalinkHow to optimize your WordPress pluginsBy Ryan Imel 1 min agoJanuary 11, 20120 var addthis_product='wpp-262';var [...]

  4. How to optimize your WordPress plugins « WordPress.io - January 12, 2012

    [...] In a good followup to the post I linked up here last week, Milan Petrovic has outlined some ways that plugin developers can better optimize their work. In particular I like how he stresses that plugins should check to see where the user is, and avoid [...]

  5. A Free wordpress newsletter » How to optimize your WordPress plugins - January 12, 2012

    [...] a good followup to the post I linked up here last week, Milan Petrovic has outlined some ways that plugin developers can better optimize their work. In particular I like how he stresses that plugins should check to see where the user is, and avoid [...]

  6. wp-coder.net » How to optimize your WordPress plugins - January 12, 2012

    [...] a good followup to the post I linked up here last week, Milan Petrovic has outlined some ways that plugin developers can better optimize their work. In particular I like how he stresses that plugins should check to see where the user is, and avoid [...]

  7. Useful WordPress Tools, Themes And Plugins : Express Master - June 9, 2012

    [...] How to optimize plugin loading This tutorial is primarily for plugin developers, but it can also be useful reading for anyone working with WordPress, to help them better understand how plugins load, and what can be done to improve them. [...]

  8. Useful WordPress Tools, Themes And Plugins | Deutschland Design - July 14, 2012

    [...] How to optimize plugin loading This tutorial is primarily for plugin developers, but it can also be useful reading for anyone working with WordPress, to help them better understand how plugins load, and what can be done to improve them. [...]

  9. The Impact Plugins Have On WordPress Loading Times | WordPress News - August 24, 2012

    [...] some additional reading on how to optimize plugin loading, please see this tutorial by [...]

  10. Necessary WordPress Tools, Themes And Plugins | WordPress Planet - October 4, 2012

    [...] How to optimize plugin loading [...]

Leave a Reply

Follow us on Twitter

Date Archives

Social Networks

Google Plus Profile Subscribe to RSS feed LinkedIn Profile Follow me on Pinterest Watch our Youtube Videos Find us on Flickr

Feedburner Feedburner updates

Sign up to receive news from this website to your email.

Recent Blog Posts

Dev4Press on YouTube

Share This

Technorati ReddIt Favorites