Problem/Motivation

I've noticed that the admin/config page takes a lot of time to load on a large project with a lot of contributed modules enabled. The reason for this turned out to be the check for the status report errors that is done every time on page load in SystemController's overview() method. For me this status check doesn't make sense on this page, which is the front gate for all configuration pages and is supposed load fast (rendering only links). Moreover, there is a dedicated page for that check.

Proposed resolution

If there is no strong reason this check to be executed there on every page load, I would prefer to not have it at all there.

Some stats with and without this check:
Page load (with status check) - 11 sec
Page load (without status check) - 0.8 sec

Issue fork drupal-3336621

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

yivanov created an issue. See original summary.

yivanov’s picture

Component: syslog.module » system.module
yivanov’s picture

cilefen’s picture

Version: 9.4.x-dev » 9.5.x-dev
Status: Active » Needs review
Issue tags: +Performance
catch’s picture

The idea of this is to alert system admins to problems when they might not be looking for them - however, agreed it's very expensive to do this every time you're browsing to this page. I also wonder if people actually follow the link vs. just doing what they're trying to do.

Tagging for product manager and usability review, since removing the warning altogether seems like a decision for them.

If we can't completely remove it, I wonder if we could put it behind flood control instead, so that it only runs every 24 hours or similar? That way if there's a persistent warning on the status report, you'll get alerted to it within a day, but you don't get the performance hit every time you visit the page.

Another possibility might be to check this on cron once every 24 hours (again using flood control or a timestamp to avoid running it too often), set a value if it's OK, and then we could look for that and skip the check if so. If it's not OK, then run the check as we currently do (to avoid showing an error if things have been fixed in-between).

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

Think also a test case could benefit in showing the issue. Though not sure how to simulate a large site and if it's testing load time.

ambient.impact’s picture

If the status check is indeed the culprit, that would also explain why admin/reports/status also takes a good few seconds to load for me on sites that also have this slow loading issue on admin/config. I think a fast loading UI should be the priority on both routes, and have the status check done asynchronously with the results displayed from cache if possible. Doing the checks on cron can be part of the solution, but there will be places where getting that info updated (such as on admin/reports/status) on command will be necessary, so an ideal solution would be if it can be run as a batch operation or something similar that shows progress like checking for updates does.

As for how to replicate this in a test, one way might be create a whole bunch of test modules that add additional \hook_requirements() implementations that do file system checks or other things that might introduce a bit of overhead. Short of just pulling in a bunch of existing contrib modules for the test, that's how I'd try to accomplish it. If that doesn't work, it might be good to take an inventory of the modules in use on sites that are experiencing this, and then figure out what checks they're doing that might be a performance issue, to replicate those in a test. Or even better, just implement a single \hook_requirements() in a test module that does sleep() for a few seconds.

Edit: after looking into this a bit, the site that's experiencing the worst delays also has an issue with a rather slow SMTP server, and we use the SMTP module, which itself does a test of the SMTP connection every time its \hook_requirements() is invoked, very likely exacerbating the issue.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

hoebekewim’s picture

Confirming this patch has a huge improvement on complex websites when visiting the configurations screen. In my project it went from a 10 second pageload to a 1 second pageload. This is what Drupal should be capable of, running complex content management systems, which work fast in day to day content and configuration manipulations.
I agree that this should not run on the configuration screen, but only on a dedicated page as the report status or by implementing a cronjob task as suggested inside this thread.

catch’s picture

Another option on top of #5 would be to put this in a lazy builder, then at least with bigpipe it won't block the page from loading.

yuvania’s picture

I've tested the provided patch and observed a significant improvement in the load times for the admin/config page. This change greatly enhances the usability of the configuration page in larger projects.

I agree with the suggestion to run these checks less frequently, such as through a cron job or lazy loading, to ensure we still catch potential issues without affecting performance. Implementing this would provide a balanced approach to maintain site health without compromising speed.

hablat’s picture

This issue is exacerbated by https://www.drupal.org/project/drupal/issues/312395 for sites with many node content. As the call for
$this->systemManager->checkRequirements()
Eventually leads to calling the following hook in the search module
search_requirements($phase) on search.install
Which then subsequently calls the method
indexStatus() on core/modules/node/src/Plugin/Search/NodeSearch
That runs the long sql query that causes the noted issue on #312395.

For us this is site breaking because the sql query hangs/takes too long which eventually leads to timeout and us being unable to access the /admin/config page. This usually triggers after a cache clear.

The patch here helps us get around this issue. But I think maybe better to fix the performance issue caused by #312395 if we want to keep the check.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

saidatom made their first commit to this issue’s fork.

saidatom’s picture

Status: Needs work » Needs review
claudiu.cristea’s picture

Status: Needs review » Needs work

The approach from MR is not a solution as the state var only resets if you visit the Status report page. If we continue on this path of caching we need to reset somehow.

I see 2 options:

  1. The cron solution mentioned by @catch in #5
  2. Completely removing this feature on /admin/config

I'm in favor of the 2nd. I see this concern in #5

The idea of this is to alert system admins to problems when they might not be looking for them (...)

But the same can happen if admins are not visiting /admin/config ar all.

lauriii’s picture

We should keep alerting admins to status report problems proactively rather than removing the feature entirely. The value is that it surfaces issues when people aren't looking for them. Ideally this could be surfaced in other places like the Dashboard in Drupal CMS.

Given that, the cron approach seems like the right path: run the check on cron with a 24h flood, and display the cached result on /admin/config. That way we get the alert without the performance hit on every page load.

We should also add a kill switch in settings.php so sites with known expensive hook_requirements() implementations can opt out entirely if needed.

claudiu.cristea’s picture

Thank you, @lauriii

I like the killswitch idea.

To expand #18...

  • Run only one hook implementation per cron to not keep the one cron run to busy. But still keep the 24h limitation.
  • For each check store also the current time when was finished.
  • On /admin/reports/status show the date/time when each check was performed
  • [from #7] On the same page place a button "Check now". When pressed the whole process will run in batch ops and the progress will be shown in a normal process bar
claudiu.cristea’s picture

This Slack discussion is relevant https://drupal.slack.com/archives/C079NQPQUEN/p1773914603844989. IS should be updated accordingly

catch’s picture

Title: Slow admin/config page load » Running hook_requirements() on all admin pages is very expensive

Not quite an issue summary update, but a title update to make this easier to find.

Also closely related is #3588490: Don't reset the extension lists in system requirements - this is disrupting the bootstrap cache bin for all users whenever anyone visits an admin page too.