This is somewhat of a followup from #1240138: Adopt PSR-0 namespace convention for core framework classes and #1239644: Define basic conventions for converting things into classes, but those two are more about standards/code style whereas this is a performance issue regardless of what we do there.

Problem/Motivation

If we move Drupal to classes, we'll be able to autoload a lot more code than we currently do. It's great to be able to lazy load code that is very rarely used, but it's also bad to lazy load code that is needed all the time, since that always comes at a cost. This issue is about balancing those trade-offs.

First, though, an analogy:

Let's say you have a house party. Some house parties have 1,000 guests all over the house and a huge garden, sometimes it's a couple of people over for beers or food.

Currently, although with a few exceptions, Drupal acts mainly like it is going to have a massive house party with 1,000 guests over. So it opens two or three different doors, puts out the bunting, then spins around in a circle all night trying to greet everyone as they come in.

This works great if you are having 1,000 people over. However it looks really stupid if only ten people show up and they all arrive at different times. This is front loading everything.

On the other hand, if you move to lazy loading everything - i.e. sitting on the couch with beer in hand, going up to the door and back again every time the door rings, you are never going to even manage to open the door 1,000 times before the party is over.

Proposed resolution

Core can't tell whether it's going to have 1,000 people over or 10. Neither for the kind of sites that we build with it, nor for any one request (which might be a callback returning a robots.txt file or a cached HTML page or a JSON representation of a node, or might be rendering a complex user profile with loads of blocks).

However we do know that certain systems are likely to be used on every request, currently that process is handled by bootstrap.inc, and then common.inc. We also know that some systems are never going to be used on every request (or shouldn't be), for this we have .install files, .admin.inc and .pages.inc as well as a class autoloader.

I do not have firm ideas on this yet, but here's a rough suggestion on how we might want to organise this in terms of classes:

  1. We should allow for the inclusion of classes directly at the very earliest layers of bootstrap. i.e. sites.php or settings.php could do
    require_once DRUPAL_ROOT . '/sites/all/bootstrap.php';
    

    This could do one of the following:

    • simply require 'foo/bar/baz.php'; so that the autoloader doesn't kick in for that class.
    • actually contain the code for a bunch of classes, compiled from elsewhere. Some kind of code compilation (to reduce file i/o) has been mulled over for a while.

    Symfony also appears to take this approach (see vendor/bundles/Sensio/Bundle/DistributionBundle/Resources/bin/build_bootstrap.php).

  2. There are certain interfaces, factories and possibly abstract classes that are going to be required to serve anything from Drupal, or nearly anything. For example it's likely that the CMI initiative will introduce a configuration interface or interfaces, and then the level 1 and 2 stores will be implementations of those interfaces. Similarly the cache system ships with an interface that isn't optional, along with implementations that don't necessarily have to be used.

    I don't think we should hard code /any/ specific implementations into bootstrap.inc - since if a site replaces them with something else it is pointless to load that code every request. However factories and interfaces we definitely could if they are for very low-level systems.

    Or we could defer all of this to a generated bootstrap file per #1.

  3. There is also trying to figure out what we need on runtime and then cache based on that. My gut feeling on that is that unless the 'cache' is something we can do require DRUPAL_ROOT . '/cache.php'; then it might not be a net win.

Remaining tasks

Discussion, some benchmarks of the PSR-0 autoloader with a load of dummy classes vs. having the same classes all in one file with different APC configurations would help to figure out how important this is.

User interface changes

None.

API changes

Not sure yet.

Related issues

#1663404: Use Composer's defined namespaces to ease maintenance

Comments

Anonymous’s picture

subscribe.

i like the idea of contrib module that compiles a configurable list of 'class-per-file' code into a single file.

catch’s picture

That's my preference at the moment as well, as long as we have a mechanism to include that file without hacking core and before the list is actually needed (and sites.php or settings.php already exists as that mechanism too, although their names aren't quite right for it).

franz’s picture

subscribe

jherencia’s picture

Subscribing...

Crell’s picture

Subscribing, no time to respond yet but thank you catch for starting this conversation (and for the amusing analogy).

Crell’s picture

Issue summary: View changes

Updated issue summary.

catch’s picture

Issue summary: View changes

fixing some typos

sun’s picture

Fixed the formatting a bit, hope I understood the arguments/options separation correctly.

On options 1) and 3), a generated or post-compiled cache, I've troubles to think of where and how this post/pre-compiled cache would be stored and how it's going to be accessed and found in very early bootstrap. I think it at least the cache idea depends on too much context information to work. If I understand it correctly, the idea of a generated bundle would involve a file stat on, say, includes/bootstrap-compiled.inc on every bootstrap, which wouldn't exist in the repo, but would be auto-generated by the d.o packager.

I fully agree with 2) - no idea what the actual I/O and performance impact of a require[_once] call is, and whether this question isn't rather micro-optimization (shaving off 1ms or less), but ideally, I think we should cleanly separate the interfaces and just load those files hard-coded.

catch’s picture

I'm not talking about a d.o packager, but rather a drush script or similar.

So you list the files you want to frontload on your site, generate that script, then require it from settings.php (so it can live in sites/all/libraries or wherever).

With that approach, as long as we have an executable PHP file required in early bootstrap (sites.php and settings.php are both extremely early), core doesn't need to provide any other infrastructure at all.

Core would still need to be able to front-load enough files to bootstrap to the point of requiring settings.php or similar, but that's going to be a tiny number.

require_once() can have a lot of impact if you are on NFS3 or some other kind of networked file storage like AWS, and not all installs can afford to put apc.stat = 0, but benchmarks would help yeah.

plach’s picture

subscribe

andypost’s picture

As I posted once here about measures on loading includes
the most quick method is loading a one big file from apc\eacc\xcache (22x) removing a require_once() then autoloading classes (x2) on base

ref: russian source http://dklab.ru/chicken/nablas/49.html#list3

EDIT: one big file make a whole system faster in 10 times! - means slowness of requiring a file
autoload vs require_one - 2 times faster

lsmith77’s picture

Actually the ClassLoader component gives you a lot of flexibility in how to autoload code. Note the default UniversalClassLoader does a lot of disk i/o to determine which file to include. This can be cached as is done for example in the ApcUniversalClassLoader or can be avoided by generating a static class map via the MapClassLoader:
https://github.com/symfony/ClassLoader

The bootstrap generation is just an optional add-on. Note that in case a user has APC with stat=0 there is no reason to bootstrap at all. So make sure you make it easy to choose the autoloading strategy.

Crell’s picture

lsmith: Interesting. So is deciding which of those autoloaders to use entirely the client's job (vis, Drupal's glue code)? It looks like they are not mutually exclusive, so we could conceivably use the (Apc)UniversalClassLoader for PSR-0-compliant code and the MapClassLoader for the current registry, where we'd just build an array (we already have that) and toss it in there. True?

andypost: For those classes/interfaces we "know" will be needed on every or nearly every page, I agree that front-loading them makes sense. The big question for me is how we define "know". Is that something core devs should decide on once, something we should allow high-end site admins to decide based on their own profiling, or something we should build Drupal to figure out and self-optimize? The latter would be the best if we could do it well, but I don't know if we can do it well.

Precompiling is something that only would work with options 1 and 2, but fortunately is compatible with the other solutions being discussed. If we are going to expect site admins to build that list themselves, however, we'll need to develop a good way for them to figure out what they should precompile. Otherwise it's a feature that will be used by Acquia, Examiner.com, Sony BMG, and pretty much no one else. :-)

catch’s picture

(note when I mention 'settings.php' in this post, I mean any PHP executable file that is included in the very low levels of bootstrap).

andypost: For those classes/interfaces we "know" will be needed on every or nearly every page, I agree that front-loading them makes sense. The big question for me is how we define "know". Is that something core devs should decide on once, something we should allow high-end site admins to decide based on their own profiling, or something we should build Drupal to figure out and self-optimize? The latter would be the best if we could do it well, but I don't know if we can do it well.

IMO there's more than one right answer to this.

I think core devs can decide once that the interfaces to read configuration, for caching, probably HTTP libraries etc. should all be front loaded - there are likely to be maybe a dozen (or few dozen) interfaces and/or classes in this category that would make for a sane default. Even if some of these are not used on a tiny percentage of requests, the overhead of front loading is minimal especially compared to what we do now. Especially if we don't include pluggable classes - just interfaces and maybe classes that aren't pluggable (since pluggable classes may never be loaded on some sites so it doesn't make sense to require them to be loaded).

Say 50 classes/interfaces are needed to 'bootstrap' Drupal and 50 are used on the rest of the request. If core can provide a sane, optional default for the first 50, that's pretty good for sites run by people who are not ever going to consider this issue.

However, there are definitely sites that are going to want to handle the other 50 without hacking core (and I've done a bit of work related to all three of the Drupal installs you mentioned..). So I'm considering something like:

/includes/bootstrap_classes_default.php

(either a list of require statements or actually compiled via the packaging script).

Then a line in settings.php (either commented out or commentable out) that requires that file.

That way you get some front loading for free, or nearly for free via commenting it out, the concept of front loading the classes is documented in core, and we can do all that without any complex logic in core itself.

If core does not hard code it's own list of bootstrap classes within the bootstrap process, then nothing stops people using a different list of classes they've compiled themselves.

For Drupal figuring out and self-optimizing, I don't think we can do that in such a way that it's performant given what Drupal ships with by default (i.e. our default caching is in the database). By the time we've pulled a list of classes out of the database, foreached over it in a loop and required some files, that's probably not going to be much of a net win compared to just eating the file i/o.

We could definitely have a system that does all this, but then allows you to write that out to a file that gets required by settings.php, that way you can take a small performance hit while building the list, but then can swap that out for just requiring a static PHP file later.

@lsmith, thanks for the references to ApcUniversalClassLoader and MapClassLoader, will have a look.

lsmith77’s picture

@Crell: yes its all quite flexible and yes the idea is that you can stack them. Drupal can come with sensible defaults, but people could tweak things quite a bit to their particular needs and setup. Also the good news is that the code is quite simple which means for an experienced developers it should be very easy to fully understand the implications of each of the class loaders and it should also be easy to add new implementations in case they are necessary.

sdboyer’s picture

I'm pretty strongly in favor of a generated bootstrap file. drush-generated, sure, and/or via a script that ships with core. Something similar to Symfony2's build_bootstrap.php. Primarily because if we start down that path, even just focusing on rolling in base, low-level classes/interfaces initially, then we've opened up a pattern that can be followed for cases where it makes sense to generate BIG bootstrap caches.

I do actually think there's value to at least attempting some self-optimization, at least for this small subset of low-level systems. The classic example is the database - if we know there's just one database driver we need, then let's compile that whole driver in and ignore the others. Really, anything that is a) pluggable and b) requires at least 1 implementation for Drupal to run is a good candidate - surpassed only by the non-pluggable classes we always need. Of course, this a self-optimizing approach would be most transparently useful if the bootstrap cache file is written by webserver. Yick. To that end...

For Drupal figuring out and self-optimizing, I don't think we can do that in such a way that it's performant given what Drupal ships with by default (i.e. our default caching is in the database). By the time we've pulled a list of classes out of the database, foreached over it in a loop and required some files, that's probably not going to be much of a net win compared to just eating the file i/o.

Why would we need to pull classes from the db? Only reason I can see to do that is as part of a one-time operation used to translate self-learned data about class usage into a bootstrap file. Once the file is written, it's included directly, we never hit the db, and we immediately see the benefits since any cached class never triggers autoload at all.

It actually seems worthwhile that we might try to detect the presence of an opcode cache (not hard) and then adjust the default strategy accordingly.

I'm circumspect about how much folks would really *need* to tweak the built-in choices we make - especially if, instead of focusing on a single monolithic bootstrap file, we consider maybe having a couple bootstrap cache files: the base interfaces & classes, but then a bigger one, too. We could have hard-coded logic in core that generates the base one, maybe even in a way that'll work well for both opcode caches and not, and then leave the other one more configurable.

catch’s picture

Of course, this a self-optimizing approach would be most transparently useful if the bootstrap cache file is written by webserver. Yick. To that end...

Yeah that's all I meant in terms of self-optimizing not necessarily being a net-win - there will need to be an explicit 'write back to the file' thing happen. So in terms of core shipping with self-optimization switched on it could be tricky to figure that out how the write back happens (I mean the update manager could do the file write for people with no drush, but that is going to be a fun UI...). Without writing back to a file, then we are just stashing a big array of filenames somewhere and pulling it out every request, which is more or less what we have now with system file list etc. and makes me sad.

I like the idea of two files, one hard-coded and one more flexible, that gives us a nice starting point without locking people in.

Anonymous’s picture

i really don't want to see us try to build a UI-based solution to this. i'd prefer we ship with the hard-coded every-request file sam mentioned, and also maybe some secondary hardcoded files, like one for mysql, one for pgsql etc.

contrib can and will innovate from there. in fact, we should prolly role a D7 version...

maybe this just boils down to some lines in default.settings.php:

/**
 * Drupal class bootstrap files.
 *
 * Drupal uses a class autoloader, which makes it easier to develop and
 * allows us to only load the classes we need for a given request. This
 * comes at a small performance cost.
 *
 * To boost performance, you can uncomment the following line to always
 * load low level system classes on every request.
 *
 * Another paragraph about generating a custom bootstrap file and loading
 * it in the same way.
 *
 * Also, maybe we have some canned second-level ones, such as one for each
 * database backend we ship in core?
 */
// require_once DRUPAL_ROOT . '/bootstrap_system.php';

// require_once DRUPAL_ROOT . '/bootstrap_mysql.php';
// require_once DRUPAL_ROOT . '/bootstrap_pgsql.php';
catch’s picture

Yeah this feels like all we need to me as well, as well as a script to pass filenames into to be compiled, and not much else for core.

I know it's pseudocode but just require should be fine here no?

Anonymous’s picture

yes, yes it would. some habits die hard.

dixon_’s picture

I'm all in favor of including a solid class loader in core (i.e. ClassLoader from Symfony). That would simplify a lot. But I don't think we should over complicate it for most low level systems, as mentioned many times in this thread.

I really like the idea of the every-request hard-coded file that one can edit. I don't think we need a script in core to generate it, but if Drush will support that, that's awesome.

Crell’s picture

We would want it generated so that it can be easily regenerated after an update, even if it's a hard-coded list. Otherwise your generated file will be out of sync with the rest of core, and mysterious bugs may arise.

sdboyer’s picture

Err...I'm half there with you. Halfway between, because I'm NOT a fan of UI, but I'm also not a fan of hard-coded (assuming that hard-coded means we're saying that we'd literally write & commit a bootstrap file into Git). Ignoring momentarily the concerns over webserver writeability, why is this anything other than a new cache bin that must be file-backed? We build a string at runtime, it happens to be interpretable php, and we dump it to disk.

If you look at symfony's build_bootstrap.php, it's *really* not tough to dynamically build a namespace-sensitive bootstrap file for a set of classes; they've really solved that problem for us. We could source that set of classes from anywhere we want. I disagree with @Crell that the issue is the file going out of sync - if you update core and we had a hard-coded file, then we'd of course update the hard-coded bootstrap file as well.

Crell’s picture

I think that's a miscommunication. I meant a hard-coded list of classes/files to built into a pre-load file. I wouldn't want to tell site admins to build that file by copying and pasting the files they want to preload by hand. That would be, um, bad. :-) But a simple "drush update-prebuild" command (or whatever) that you run after doing a core update would be fine. I think the level of expertise necessary to safely build such a file is higher than the level to be running Drush anyway, and that avoids all of the GUI-and-webserver-file-writing evil we want to avoid.

A file-dedicated cache would, I think, make sense only if we have some form of self-learning system that can optimize itself over time. That would be wicked cool if we could write it, but I'm quite sure that it's a lot more challenging than it sounds. :-)

catch’s picture

Hmm I think we're talking at cross purposes a bit, I'll try to summarize:

For those sites that are not going to be pre-building their own lists of classes, nor installing something fancy from contrib to do it, it probably makes sense to include a 'best effort' bootstrap file (ideally containing the actual classes instead of a tonne of require statements) with core. There will definitely be several classes we can put into that file, and that will remove some overhead from low-level bootstrap.

This file probably should not be in git since that could get out of sync, but we could include the list of classes to use in git, then have the packaging script build it (requires some d.o infra changes). This means that sites installed from git don't get the file, which is fine (they could run the script to build it if they want, or do their own thing).

We want to allow for people to do something more advanced for this, so that means making the require of that bootstrap file optional - i.e. have it happen from settings.php or $editable_file_required_at_very_lowest_levels _of_bootstrap, not somewhere like current includes/bootstrap.inc so people don't have to hack core.

We can probably ship core with something that takes a list of classes and generates a file from them (which might be the Symfony bootstrap generator or similar) - that can then be used via drush or directly. Like sdboyer says this is a fairly trivial thing to write (as opposed to actually compiling the list) so would not require too much work or maintenance. This will allow sites to build custom bootstrap files, or for contrib projects to do it too. Those can be included from the same place as the bootstrap file we ship with - either replacing it or in addition to it.

We should assume for now that anyone who wants to go beyond the defaults we ship with can also use drush (or if someone tries to build a contrib project to do this that doesn't require drush, it's their problem to solve web-writable PHP files).

Things that seem outstanding to me:

- do we want to complile classes into a file (easy with PSR-0) or just make a long list of require statements, or support both from core. My view is we only want to compile classes into a file in core since even sites with APC enabled very rarely use apc.stat = 0. Sites that do use apc.stat = 0 will not suffer from using a file with the actual classes in it.

- do we want core to ship with a self-optimizing autoloader that can write back to a bootstrap file. IMO even if we do want this at some point, we should punt on it for some time, since the low level infrastructure requirements for something like that are the same for the more simple/manual versions already discussed.

Crell’s picture

If we make the packaging script build the preload file, I suppose I can deal with that. I'm just concerned about people who DO patch core (or contrib if that ever gets integrated) getting their code out of sync. Although I suppose if you are patching core then you should be able to use a rebuild command from scripts or Drush...

So I'm overall OK with #23, I suppose. For the outstanding questions, the advantage of just a require-list file is that the real code still lives in only one place and is not duplicated; that is, there's nothing to get out of sync. The disadvantage is, as catch notes, it does nothing for disk IO, just avoiding the autoload lookup time. I can go either way here, I guess.

For the second, I would love to have a self-learning system but we'd have to build all of the other stuff above first anyway for that to work, so we should punt on that for now and revisit it in, oh, a year or so when we have enough code and experience to figure out if it's even possible. :-)

podarok’s picture

subscribe

@andypost - thanks for the link

podarok’s picture

RobLoach’s picture

Status: Active » Fixed

PSR-0 autoloading works for core (core/lib/Drupal) and modules (modules/[modulename]/lib/Drupal/[modulename]). Setting this to fixed.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

David_Rothstein’s picture

Status: Closed (fixed) » Active

I don't understand why this issue was closed. Yes, we have an autoloader, but the proposal being discussed here is that there are times we should not be using it.

I just did some very quick-and-dirty benchmarking and found that on a cached page request, Drupal 8 seems to be spending less than 1 msec in UniversalClassLoader::findFile(). That's small, but it's a couple percent of the total time spent on the request so it's not totally negligible either. On the other hand, if you're using ApcUniversalClassLoader that would presumably be even smaller.

However, when I looked at the time spent in UniversalClassLoader::loadClass() (i.e. including the time to "require" files, not just find them) that was more like 25-30% of the total request for a cached page, so definitely non-negligible. And as @catch pointed out above, this is still an issue even for people using APC (at least with most APC configurations).

I think what this suggests is that if this issue is worth doing at all, it's worth going all the way (and actually compiling the classes into a single file). Someone should double check my numbers though; for one thing, I ran this on an encrypted drive and I wonder if that totally messes up benchmarking for things like require() statements.

Crell’s picture

It probably did mess it up, but that conclusion is consistent with what I've heard from elsewhere in the PHP community. Compiled files seem to be the preference.

RobLoach’s picture

Somewhat unrelated to what you're proposing here, but dependency injection containers can be dumped to PHP/XML/etc files so that class mappings and object definitions can be compiled and loaded very quickly. That would mean replacing the bootstrap entirely with a compiled dependency injection container.

Crell’s picture

That's a bit different than what's being discussed here. The idea is that you'd (for instance) concat all of /lib into one massive file that gets loaded when Drupal bootstraps. Hell for non-APC hosts, but considerably faster for APC hosts since the class loader then never actually fires (or does so far far less than it otherwise would).

Crell’s picture

Issue summary: View changes

Updated issue summary.

RobLoach’s picture

Status: Active » Closed (works as designed)

I'd consider this both rather outdated and fixed.

catch’s picture

Status: Closed (works as designed) » Active

It's neither fixed nor outdated. We can't even swap out the classloader at the moment.

catch’s picture

Couple of ideas.

1. an APC classloader that uses a single entry in APC (which could then be written out to a file classmap if desired). Symfony's APC classloader takes 2ms on a vanilla install on my local according to XHProf, so it'd only save around 1ms.

2. Bypass APC entirely and use PHPStorage to build up a classmap over time.

3. Same as #2 but write out something that directly requires files so autoload doesn't kick in for them at all.

There's also Damien's idea of the stream wrapper which if it worked would end up similar-ish to #3 without the file in-between.

donquixote’s picture

If we go with the Krautoload patch for PSR-4, this could be a follow-up:
Introduce a statistics decorator to fine-tune front loading. (github)

catch’s picture

I think we need to do #2023325: Add interface for classloader so it can be cleanly swapped before we change the classloader.

catch’s picture

Issue summary: View changes

added related issues

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andypost’s picture

bradjones1’s picture

Version: 8.9.x-dev » 9.1.x-dev

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

andypost’s picture

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

andypost’s picture

There's JIT since PHP 8.0 and it needs adoption too

Berdir’s picture

Status: Active » Closed (outdated)

I think I got a crosspost earlier when trying to reference the preload issue in #47. Closing this.