[theme-reviewers] How the files included in the theme functions.php file are loaded?

Otto otto at ottodestruct.com
Sat Feb 26 19:26:29 UTC 2011


On Sat, Feb 26, 2011 at 12:39 PM, Satish Gandham <satish.iitg at gmail.com> wrote:
> How are the files included in the themes functions.php file loaded.
>
> Like, some of the files are required only for the backend (admin), so are
> those files called for when generating the page for regular visitors?
>
> For example, I have this code
>
> //Required to show the page navigation.
> require_once ( INCLUDES. '/wp-pagenavi.php' );      // Add's wp page nav
> support, script by Lester Chann
>
> // Required only for the backend.
> require_once (ADMIN. '/admin-header.php');         //Header of options page
> require_once (ADMIN. '/admin-core.php');           // Work horse for SWIFT
> admin options.
>
> Should i use some conditional tags while loading the files?

Theme functions.php files are loaded on every page load of any kind,
period. So yes, they are loaded for the front end too.

However, how to optimize PHP in this manner is actually less than
obvious. It helps to understand what's going on when PHP runs a
request.

- First, the PHP file is loaded from disk into memory. This takes some IO time.
- Second, the PHP is parsed into opcodes. This happens for the entire
file, period. Even the bits that aren't going to be used.
- Third, the opcodes are executed by the interpreter, in order. This
is where things get tricky.

Each of these steps has overhead. An include has a little more
overhead, because when you include a file from PHP code, the opcode
execution has to stop and it has to go back and load that new file,
parse it, and then start executing it. This incurs a little bit of
overhead. Not much, but some.

So the question of whether it's better to have all the code in one
file or in separate files conditionally is tricky depending on whether
the overhead from loading and parsing those included files is higher
than the overhead of the include itself.

Some people might think that this is faster:

if ( i_need_something() ) {
  include 'what-i-need.php';
}

This has the overhead of the i_need_something() check, but presumably
I don't need it every time. The problem with this is that it assumes a
naive implementation. A lot of high-performance PHP setups use
opcode-caching, and this is a cache-buster.

In opcode-caching, I avoid the overhead of steps 1 and 2 by caching
the resulting parsed opcodes in persistent memory somewhere. So when
the include happens, instead of going to disk and getting the file and
parsing it, I just refer to my in-memory cache.

Problem is that opcode-caches cache the entire request, start to
finish. If there's a conditional around an include like this, the
opcode-cache may not have it from the last execution. The path
followed is now not the same every time. So for anybody using an
opcode-cache, just including everything is far, far faster, since the
whole of the thing will be cached in memory as one block, which can
simply be executed start to finish.

Other systems like Facebook's HipHop compiler (which converts PHP into
C++ for compiling into raw machine code) can't cope with conditional
includes. They're converting the code directly, and if the code
execution path changes dynamically like this, then there's no way for
C++ to emulate that properly.

TL,DR: Optimization ain't as simple as it seems. Turns out that the
best thing to do is usually to just include everything and not worry
about it. Leave optimization to purpose-built systems like
opcode-caches, and write your code to be as clear and simple as
possible for those systems to act most effectively. If somebody needs
to make your code run faster, they'll turn to one of those systems,
and having to rewrite your code to remove your premature optimizations
is a PITA.

-Otto


More information about the theme-reviewers mailing list