 Yes, so good morning everyone, sorry for running late. I wanted to start with some funny jokes and some stuff to warm you up, but I will just skip all these anecdotes to just head directly to the content, because I suppose that we will probably need to shorten it a bit. So the bootstrap process of WordPress is something that is very important for every website, but very few people really know what is going on behind the scenes. So I want to take you through an overview of what the different components are and what the possibilities you have to interact with them and change them. Although warning first, whatever you do when directly working with the bootstrap process, this is all at your own risk, and it's very possible that you'll be breaking your sites. So in general overview, what is bootstrapping? It's the code to prepare the environment to make it ready for the more abstract code to run. It's not part of the actual logic. It's more like an abstraction of the particularities of a specific environment of a specific object platform. So if you imagine the environment as something that can easily change, that can take all sorts of strange shapes, you want your logic to always stay as clean as possible, and that's where the bootstrap comes in. It's basically an adapter that fits whatever environment you try to run your clean logic in so that you don't need to mess up the logic itself. The logic in this case is the WordPress core, the WordPress web application. So what we have as a general execution flow is someone does an HTTP request to your website which first launches this bootstrap process and the bootstrap process prepares the environment so that then the core and the plugins and the theme, they can run in a known environment where they don't need to take care of windows differences of server configurations and so forth, and then they produce an HTTP response. The order of loading files is a very simplified version of it. This is for front-end request. So for every request you're doing, you have an entry point. This is the index.php file. Very generally, the index file on the web server is the first file that is being launched when you don't enter the address of a particular file but just over folder. So in this case, we have the entry point, the index.php, which starts to load the WordPress environment, starting by reading all the configuration, preparing the settings. Then WordPress libraries load it, which enables the function wp to be called after that. And this ends in loading the template loader, which is responsible for the actual theming. So running the wp function does not reduce any output. That's all part of the theme only. On the back-end request, when you log in into your dashboard, it's a very similar structure, but we have a different entry point. You can enter the folder wp-admin, which will then call the index file in that folder. We have a separate file that prepares the environment for the administration interface. Then we again load the WordPress library, which is the exact same thing as we had with the front-end request. And then in this case, we don't call the wp function but the wp dashboard function to generate the dashboard and to specific pages you currently need. The wp load is used for front-end requests as well as for back-end requests. So that might point to the fact that it's a very important part of loading WordPress, and it can be skipped for different entry points. So here we have a quick overview of what the wp load actually does. It loads the configuration first. It's the wp-config file that most of you probably know where you can prepare your database settings, where you can set constants for enabling debugging or for setting up your cache and so forth. Then it loads a wp-settings file. This is responsible for setting up the entire environment in which the core code will load. Then the plugin API is being loaded. This is loaded very early on so that as soon as possible the actions and the filters are available so that you can run plugin code or theme code as soon as possible. Then the database is set up. This is loaded through the wp-db file, and it might contain an optional override in the db file, which I'll come to later. This sets up the database abstraction layer that WordPress offers. Then we have the cache, which is a similar abstraction layer for all the caching parts of WordPress, and it also contains an optional override. After these are set up, it continues to try to load multi-sites. So you can set constants in your configuration file to tell it that you're currently running on a multi-site and if WordPress notices this, it will try to examine the URL that you've actually typed and deduce the network and the site that the code should run from. We have the localization that is then loaded and prepared, which is responsible for allowing you to translate the strings that your site might contain. You also have the regional settings in that subsystem, which contains information about how you want your time strings to be formatted, how you want your weekdays to be called, and so on. After this has been loaded, it first checks if the WordPress installation that you're currently running on is actually defined to be installed or whether there's still some parts missing. Because all of this is basically just running code, but after this step it would need to actually connect to the database and start interacting with your actual content. For this to be possible, the installation needs to be properly completed. So if this has not been done, it will run the WP Not Installed function, which triggers what is commonly known as the famous five-minute installation procedure of WordPress to help you go through the steps that you need to complete the installation of WordPress. After this step, it's basically a very long list of require calls that load all of the different function files, all of the different classes that WordPress needs, and it contains a conditional that only loads the multi-site code if we are also working on a multi-site. So let's try to go more into detail. First of all, WordPress is heavily relying on constants. These constants can come in two forms. They are constants that are just defined to keep track of an information for WordPress itself, but you can't directly change as a user. These are meant to be read only, and then there are constants that WordPress only defines to a default value if they haven't been defined before. So this allows you, in your config file, for example, to provide overrides to the defaults that WordPress would normally use. A very known case for this is the WP Debug constant. WordPress will default it to false, but if you add a WP Debug equals true to your config file, WordPress will just leave it as true and not bother to set a default, which would be technically impossible. There's quite a few of these constants, and I started mapping all of these out in a GitHub repository where you can find the link on the bottom of the slide. Most of the links in the slides are live, so I will hand out the link to the slides later on, so you can also click on the links. This is still a work in progress, so the list might not be complete yet, but the goal is to have this be as complete a reference as possible because I did not find one Korean source of documentation for the bootstrapping component. Then, as a next family of elements that WordPress uses, we have global variables. Global variables are what WordPress generally uses to share information across subsystems. If you would work with objects, these would be the shared objects. Here, it's global variables. Some of these heavily depend on the context in which WordPress is currently in. For example, you have information about the current user, which only makes sense if a user is logged in, and which changes for each user, but there's also information that just tries to give you a convenient access to some shared object like the WPDB global that gives you shared access to the database abstraction layer. Again, this is a huge list. I'm also trying to document all of these out, which is also work in progress, and you can also find this in the same GitHub repository. A quick note, this is not a type or that you see at the bottom of the slide where coincide is the currently active WP network and current block is the currently active WP site. When you work with a lot of the bootstrap components, it contains all sorts of historical baggage and has grown organically, and at some points design decisions were being changed, and this has led to features like this, where when you're talking about the global variables, you always talk about sites and blocks, and when you're using the actual objects that represent them now in the more modern code, the objects are called networks and sites. You will notice this across the slides that there's always this small discrepancy. So the plugin API initialization is run early, as I said, so that as soon as possible the actions and filters are enabled because WordPress uses them itself as well. There's a class declaration that is being loaded for a class WP hook, a hook is the generalized form that represents both filters and actions, and this class is an object representing both of these elements. When the plugin API is getting initialized, it assumes that some code might prior to the loading of the plugin API already manually add filters to the global that contains the filters, so first of all it goes through that global, and for every filter it finds, it makes sure that the filter is in the correct state and is represented by a WP hook class. Some hooks are run so early that it is not possible for plugins to actually use them. These are only meant to be used for non-web run times. This means that, for example, if you load the code through the command line or you run running tests, you don't pass through the normal HTTP rep request flow that WordPress was built for. So these hooks are only available to allow injection points for these non-web run times. After this step, there's a huge list of default filters being loaded from one file. If you're curious, feel free to look into that file. It's quite interesting to see how much functionality gets added through this plugin API. I did a quick check and for version 4.8, it was 447 hooks that were being added just through this default filters file, which is actually quite a lot. Then we have pluggable functionality that is parts of WordPress that you can replace as a whole. So we have two types of pluggable functionality. There's the drop-ins, which are files you can drop in specific locations and when these files are present, they replace or enhance an existing subsystem. There's drop-ins for the database, for the cache. There's also drop-ins for the multi-site to completely redefine how the multi-site loading is done and they work by just dropping that file into the correct place and they will always be active at that point. Then there's pluggable functions. I want enumerate all of them now. They are all in the file pluggable.php in the wp-includes folder. There's quite a lot of functions in there and they are built in such a way that when this function is already defined, when WordPress loads its pluggable file, then the pluggable file will just skip these. So every function that you define from this set of functions before the pluggable file is being loaded will allow you to use your own version. So let's go through the database subsystem quickly. There's a database abstraction layer in WordPress, which is commonly called WPDB. It has a direct dependence on MySQL. It does not work out of the box with a different type of database. It is an abstraction, but it is a leaky abstraction that means that although you don't directly talk to MySQL, all of the functions and methods are built in such a way that they directly map the functionality of MySQL. So if you would have a drastically different database, then the abstraction would probably not make a lot of sense anymore. Then there's the drop-in that you can use, db.php file, where you can provide any custom database implementation. To provide a custom database implementation, you drop that file into the content folder, and you need to set the global WPDB to your own instance of whatever database object you want to use. And when your WPDB object returns, has an IsMySQL property that returns true, then the compatibility checks, they are simply skipped. So this allows you, for example, to provide a completely different database into implementation, where the normal checks that WordPress does, where it tells you that you need runtime of MySQL, so and so, at that version, where that would not make any sense because you actually don't need it because you're running with different database, this allows you to skip that check. The WPDB class is also loaded, so you can either completely replace it or extend it as needed. Here's a custom database implementation that was pretty much the best I could come up with that was able to fit into a slide. It's very easy to provide a custom database implementation. It's basically just a db.php file that will set the WPDB global variable to some instance of an object. That's the only requirement. There's some alternative database implementations that you can use that provide additional functionality beyond what WordPress can normally offer, with HyperDB probably being the best known because it allows you to use multiple databases so that they can act as one. The caching drop-in that allows you to replace the caching system, so you can replace the WP cache functions if they have been defined. WordPress will not redefine them. The caching system is built so that these WP cache functions are used across most of the database requests that WordPress does. If you replace these, WordPress will use whatever caching implementation you need for its own internal calls as well. If then later you do a normal query to get a list of posts, this will be cached to your custom caching implementation. There's two drop-ins. It's the object cache and the advanced cache. The object cache is a replacement for the WP cache functions. These are only loaded on demand. You don't have any initialization function or so. If you need to have more control of the entire caching setup, you can use the advanced cache which is basically a file that's being included where you can directly use functionality during the load process. To provide custom cache implementation, it's the same thing again as with the database implementation. You produce a file with the right name in the right location. It needs to set the WP object cache global variable to a custom instance and it needs to provide WP cache functions. The advanced cache can then be used to allow further customizations. Here we have a silly example of a custom caching implementation. We need the object cache file that contains all the WP cache functions. Then we can have a class that we will use to provide an instance that we set into the WP object cache global variable. The localization setup is then done. It's the next subsystem that's being loaded. There's first a set of the constant WP langdier that is being set to let WordPress know where it can find language files. Then it loads the MO class, which is an extension of a get text reader implementation. This is responsible for the actual loading of the file format of the translation files. Then it loads the default text domain. The default text domain is meant to be used for WordPress internal use only, so it's basically all the text strings that come shipped with WordPress core. When you produce a plugin, you'll probably want to use a different text domain then. Then it sets up the WP locale global variable where you have your weekday settings and so forth. It also initializes the WP locale switcher, which lets you switch the locale through code so that you can provide a language switcher or whatever mechanism you need. The translations are stored in an array. It's a globally available L10N, which is an abbreviation of localization. When you want to fetch a translation, it looks in that array to find the text domain, which is the key that is being used in the L10N variable. If this is not found, it tries to load that text domain on demand. If it can still load it, it will use the no op translations just to avoid trying to load again and again, so it's basically translations that just do nothing. It's just a placeholder. For multi-site identification and loading, we first run the MS blocks file, which contains all the functionality of the multi-site subsystem. Then in MS settings, the environment is being set up. Then we have the MS load file, which mirrors the WP load file, which contains the actual code that multi-site needs to run. Then there's the default constants that are being loaded for multi-site. Finally, there's the sunrise drop-in that is being checked for. If the sunrise drop-in is available and the sunrise constant has been set to true, then it will load the sunrise file. The multi-site identification pretty much runs off the URL. It first extracts the domain from the HTTP host. It extracts the path from the request. Then if the domain coincide and path coincide are defined, it will use these. If they aren't, then it will first check if it is dealing with a subfolder install. It tries to identify the network first and then define the path that is being used inside of that network to define the site. If it's not a subfolder install, it needs to treat the domain as a whole to get the network and the site both. It will at most use the first segment of the path to help it identify the actual location. In case of failure, you'll have the MS network not found and MS site not found actions that are being triggered so that you can provide some custom error handling in that case. The sunrise drop-in is loaded if the constant sunrise is set. It allows control over the multi-site setup mechanism so it basically provides an injection point where you can just set a completely custom way of finding out from whatever URL you got to define what are the networks and sites that we're currently dealing with. This allows you to, for example, use domain mapping where there's no sub-domain or subfolder install but it's basically just a random collection of separate domains. The sunrise file allows you to do your manual mapping to achieve this. If in your sunrise file you set the coincide and coincide block global variables to some value, this will completely deactivate the entire procedure on the previous slide where it tries to guess all sorts of things. So just setting this in the sunrise file will completely skip this step and it just assumes that whatever you provided is the correct one. For sunrise drop-in, you need to define the sunrise constant in wp-config and then have sunrise file in the content folder where you return the coincide and the current block as the corresponding instances of a wp-network or wp-site class. They both have named constructor get instance which takes an id and that id is the id used in the database of the multi-site installation. So you can use whatever mechanism you need to define the id and then get an instance and return this through this mechanism. The bootstrap process needs to be as lean as possible. I did some quick checking with an empty site. I found out that the template loader file which starts with the actual theming process with the skinning comes at about 50% of the performance impact. So that means that on an empty site 50% of the code that is being run is part of the bootstrapping process approximately. That's of course an oversimplification but I just wanted to get a quick feel of how heavy it is. The bootstrap process is pretty much very obscure and less and sparsely documented. So I have started a feature project where I want to first work on knowing as much as possible about the current process and then start work on doing improvements and refactoring the different pieces that might need refactoring with several goals that I want to always the project to be held accountable for. We're currently in the first phase of this project which is the discovery which these slides and the talk here and the GitHub repository that I've linked to are all poured of and I would welcome anyone trying to get to know more about the bootstrap process or who knows more about the bootstrap process to drop by in the GitHub repository and help document what is currently going on in there. So next steps if you want to know more about this the WP core bootstrap GitHub repository is where all the stuff is happening for this feature project so please look in there and I'm happy for anyone that wants to contribute. There's a WordPress Slack channel in the makewordpress.org a team that's called core bootstrap where I should be always available and where I try to post updates whenever the feature project gets new news to communicate and yeah the GitHub organization also contains other repositories and will slowly be the place where the where the entire project is built up until the merge proposal. Thank you.