Problem/Motivation

Anonymous user, frontpage, without page_cache (entire request time 94ms).

In there we spend 1ms in theme_get_setting(), which does quite a lot:

Function Name Calls Calls% Incl. Wall Time
(microsec)
IWall% Incl.
MemUse
(bytes)
IMemUse% Incl.
PeakMemUse
(bytes)
IPeakMemUse%
Current Function
theme_get_setting 8 9.4% 1,138 1.2% 175,496 1.1% 173,384 1.0%
Exclusive Metrics for Current Function 121 10.6% 6,840 3.9% 3,368 1.9%
Parent functions
system_page_attachments 3 37.5% 1,036 91.0% 174,120 99.2% 173,384 100.0%
template_preprocess_page 3 37.5% 61 5.4% 736 0.4% 0 0.0%
_bartik_process_page 2 25.0% 41 3.6% 640 0.4% 0 0.0%
Child functions
file_create_url 2 2.9% 568 49.9% 118,088 67.3% 110,760 63.9%
Drupal::config 2 2.9% 195 17.1% 10,608 6.0% 38,376 22.1%
Drupal\Core\Config\ConfigBase::get 14 20.0% 120 10.5% 8,552 4.9% 2,376 1.4%
spl_autoload_call 1 1.4% 40 3.5% 10,896 6.2% 11,144 6.4%
Drupal\Core\Config\ConfigBase::setData 1 1.4% 33 2.9% 6,432 3.7% 0 0.0%
Drupal::theme 8 11.4% 18 1.6% 632 0.4% 584 0.3%
Drupal\Core\Config\ConfigBase::set 2 2.9% 16 1.4% 4,648 2.6% 3,936 2.3%
drupal_static 8 11.4% 9 0.8% 944 0.5% 944 0.5%
file_exists 1 1.4% 6 0.5% 624 0.4% 0 0.0%
Drupal\Core\Config\Config::get 2 2.9% 4 0.4% 648 0.4% 0 0.0%
Drupal\Core\Extension\Extension::getPath 2 2.9% 4 0.4% 864 0.5% 0 0.0%
Drupal::service 1 1.4% 3 0.3% 632 0.4% 0 0.0%
_system_default_theme_features 1 1.4% 1 0.1% 1,816 1.0% 0 0.0%
Drupal\Core\Theme\ActiveTheme::getName 8 11.4% 0 0.0% 656 0.4% 656 0.4%
Drupal\Core\Extension\ThemeHandler::listInfo 1 1.4% 0 0.0% 664 0.4% 0 0.0%
Drupal\Core\Theme\ThemeSettings::__construct 1 1.4% 0 0.0% 664 0.4% 576 0.3%
in_array 7 10.0% 0 0.0% 624 0.4% 0 0.0%
Drupal\Core\Theme\ThemeManager::getActiveTheme 8 11.4% 0 0.0% 664 0.4% 664 0.4%

Proposed resolution

Try to cache the theme settings not in the request but between requests. One really good place could be the cache entry for the active theme object.
In case we would store it there, we would avoid the call to $themes = \Drupal::service('theme_handler')->listInfo(); in there.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

@effulgentsia and myself talked about that and we agreed it would be worth try to cache this information.
In an ideal world file_create_url() would have the cacheablity metadata so the generated URL can be cached. For normal URls we rely on higher level render caching, but for this case, we could not.

claudiu.cristea’s picture

Status: Active » Needs review
FileSize
5.48 KB

The changes are few lines but the patch footprint is bigger because of indentation increase.

Status: Needs review » Needs work

The last submitted patch, 2: theme_get_setting-2531958-2.patch, failed testing.

claudiu.cristea’s picture

Well, this is weird. Those tests are passing locally.

claudiu.cristea’s picture

Status: Needs work » Needs review
FileSize
0 bytes

Status: Needs review » Needs work

The last submitted patch, 5: theme_get_setting-2531958-5.patch, failed testing.

claudiu.cristea’s picture

Status: Needs work » Needs review
FileSize
9.86 KB

Oops. Sorry!

lauriii’s picture

Issue tags: +needs profiling
dawehner’s picture

Status: Needs review » Needs work
+++ b/core/modules/system/src/EventSubscriber/ThemeSettingsSubscriber.php
@@ -0,0 +1,106 @@
+      }
+
+      list($theme, ) = explode('.', $config_key, 2);
+      $this->cacheBin->delete('theme_settings.' . $theme);

This is wrong. Use cache tags and be done.

Should we include the language at least in the caching? What do we do with config overrides? Things aren't simple sadly.

Wim Leers’s picture

Issue summary: View changes
FileSize
18.45 KB
18.74 KB

I'm afraid this is a dead end also :(

Tested with 1000 requests to /contact, as the anon users, with page cache off.

Before
Requests per second:    14.11 [#/sec] (mean)
Time per request:       70.888 [ms] (mean)
Time per request:       70.888 [ms] (mean, across all concurrent requests)
Transfer rate:          195.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    68   71   1.2     71      76
Waiting:       60   64   1.2     63      69
Total:         68   71   1.2     71      76

Percentage of the requests served within a certain time (ms)
  50%     71
  66%     71
  75%     71
  80%     72
  90%     72
  95%     73
  98%     74
  99%     75
 100%     76 (longest request)
After
Requests per second:    14.07 [#/sec] (mean)
Time per request:       71.094 [ms] (mean)
Time per request:       71.094 [ms] (mean, across all concurrent requests)
Transfer rate:          195.02 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:    64   71   1.4     71      79
Waiting:       59   64   1.3     64      72
Total:         64   71   1.4     71      79

Percentage of the requests served within a certain time (ms)
  50%     71
  66%     71
  75%     72
  80%     72
  90%     73
  95%     74
  98%     74
  99%     75
 100%     79 (longest request)

dawehner’s picture

It would be great to profile both issues at the same time.

claudiu.cristea’s picture

@dawehner,

+ $this->cacheBin->delete('theme_settings.' . $theme);
This is wrong. Use cache tags and be done.

+++ b/core/modules/system/src/EventSubscriber/ThemeSettingsSubscriber.php
@@ -0,0 +1,106 @@
+    else {
+      // Check if the config key is theme settings key. Exit if not.
+      $keys = array_map(function ($theme) {
+        return "$theme.settings";
+      }, array_keys($this->themeHandler->listInfo()));
+      if (!in_array($config_key, $keys)) {
+        return;
+      }
+
+      list($theme, ) = explode('.', $config_key, 2);
+      $this->cacheBin->delete('theme_settings.' . $theme);
+    }

I'm using here ->listInfo() and maybe this is slowing the whole stuff (?) I can drop the check of theme name and invalidate by tag. The cons is that we'll remove also other theme cache (and the global settings). Opinions?

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.

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

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

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

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

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

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.