Needs work
Project:
Drupal core
Version:
main
Component:
theme system
Priority:
Major
Category:
Task
Assigned:
Issue tags:
Reporter:
Created:
15 Apr 2015 at 13:21 UTC
Updated:
5 Jun 2023 at 13:20 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
wim leersAt least major, since #2429617-36: Make D8 2x as fast: Dynamic Page Cache: context-dependent page caching (for *all* users!) showed it to take >4% after the SmartCache patch is applied, roughly ~1% with HEAD.
Comment #2
mr.baileysComment #3
mr.baileysFirst attempt, everything seems to work when testing manually, but the tests still need to be converted so will fail. Uploading the patch to get feedback on approach. Probably needs some polishing.
Initial numbers on performance impact:
=== 8.0.x..2471657 compared (552fb1c82db64..552fb30e6fe9a):
ct : 53,018|52,755|-263|-0.5%
wt : 185,132|183,287|-1,845|-1.0%
mu : 18,538,776|18,527,664|-11,112|-0.1%
pmu : 18,698,432|18,687,480|-10,952|-0.1%
---
ct = function calls, wt = wall time, cpu = cpu time used, mu = memory usage, pmu = peak memory usage
Comment #4
wim leersGreat job! Now to @dawehner for a review.
Comment #5
dawehnerIt is looking great in general!
Is that a c&p?
I think its wrong to use route match + route, but instead we should go back to route name + route
Now that we are doing that on route compile time, we no longer have to check it on runtime. Let's get rid of the applies() call.
Comment #7
mr.baileysComment #8
mr.baileysComment #9
mr.baileysTests still need to be converted. Since we transformed from having all logic in the ThemeNegotiators to splitting the logic up in three different locations ((a) container compiling, (b) route rebuilding and (c) theme negotiator) it might make sense to convert the current Theme Negotiator test from a Unit test to a Web Test?
New performance statistics:
=== 8.0.x..2471657 compared (5530c03d7e613..5530c300bd097):
ct : 53,018|52,752|-266|-0.5%
wt : 185,591|184,057|-1,534|-0.8%
mu : 18,537,112|18,525,848|-11,264|-0.1%
pmu : 18,696,824|18,685,744|-11,080|-0.1%
Comment #11
mr.baileysUnassigning since converting the tests from Unit tests to KernelTestBase has proven a bit too difficult for me...
Comment #13
mr.baileysI started out converting the ThemeNegotiatorTest from a UnitTest to a KernelTest. However, AFAICT, all test cases covered currently by ThemeNegotiatorTest are already covered by existing WebTestCases except for theme access checking.
The only thing not already explicitly covered is the theme access checking done in determineActiveTheme in the ThemeNegotiator, so I added an additional test case for that to ThemeTest.
Comment #14
mr.baileysComment #16
wim leersSounds good, great research!
Comment #17
fabianx commentedPatch looks great already, just 2 test fails.
I like the approach of setting the theme negotiators in a onRouteAlter() and checking the applies() part.
That is really good thinking.
Comment #18
wim leers1000 auth requests (
$ ab -n 1000 -c 1 -g ab.tsv -C SESS3d5f1d095f03cbeab065f280e5c42801=mK-rDsC8XPuc1zGUOsKOFDa5s8PvRVVB89XlO99pABk http://tres/)(Reusing data from https://groups.drupal.org/node/464283#comment-1100578.)
Comment #19
mr.baileysThe 2 remaining test failures were due to incorrect theme negotiation logic on route '<none>'. Tests should now pass.
Comment #20
fabianx commentedSo this runs all theme negotiators for all routes?
How often is this done?
Is there some kind of caching for the routes when the router is rebuild?
How long does that take in cold cache?
This if looks wrong ...
Why would we apply the determineActiveTheme if negotiators are stored on the route?
What if there are several?
I see this tries to optimize for the case that there is only one in which case we know it is matching, but for that it should check for count($r_t_n_ids) == 1.
Comment #21
mr.baileysThanks for the review Fabianx
Regarding #1:
I'm happy to profile impact of this patch on cold cache requests if someone can tell me how to properly test this (I have xprof and xhprof-kit already up-and-running, just need to know how this is usually tested/benchmarked for D8 core).
Regarding #2:
There are two possible scenarios when determineActiveTheme() is called: either (a) the theme negotiators that apply to the route have been stored on the route in \Drupal\Core\EventSubscriber\ThemeNegotiatorSubscriber::onRouteAlter(), in which case the service ids stored on the route are used, or (b) there are no theme negotiators stored on the route, in which case we need to evaluate the full set of available theme negotiators.
In scenario a), we just need to cycle through the services stored on the route until the determineActiveTheme for that negotiator returns a theme. However, in scenario b), we need to first test if the negotiator applies to the route by calling applies() (contrary to the route-stored negotiators, where this step happened earlier). Only if the negotiator applies, we should call determineActiveTheme().
Hence
if ($route_theme_negotiator_ids || $negotiator->applies($route_match->getRouteName(), $route))means "determine the active theme for this negotiator, but if it was not stored on the route, make sure it applies first".Comment #22
fabianx commented#21
1: Thanks for explanation, so we should maybe add a threshold on the route collection OR just rely on sites to remove the subscriber from services if number of routes is too high?
2. Thanks, again makes perfect sense now. I missed that they are sorted ...
-------------------------
Who sorts this negotiators now?
I think this is missing now ...
--
Do we use addArgument elsewhere?
It seems way underdocumented as you cannot see there is another parameter from the core.services.yml.
I think its more logical to have a dedicated setNegotiatorServiceIds() function ...
But I might be wrong.
Probably just a arsort thats needed, then using array_keys ...
EDIT: Found it, see below ...
Not sure we can do this API change this late, but need to at least document the API change.
Ahhh, here we are doing the sorting, okay ...
That makes sense.
So in case someone removes the subscriber this is exactly the old behavior?
Nice!
Lets keep that fully, this can still test the case when no negotiators are set at all on routes (as I have too many on my site and don't want the optimization).
Comment #23
joelpittet@mr.baileys are @Fabianx's notes doable and is this doable for RC or should we postpone till 8.1.x?
Comment #24
wim leersI don't see this happening now (between RC4 and 8.0.0). But maybe it can be done in 8.0.1? If there's no API change whatsoever, it's possible.
Comment #25
dawehnerYeah, especially if with contrib it might be actually a performance issue, we should reconsider doing that.
On the other hand, it all comes down to
a) What we define as feature
b) How strict we want to be with semv
Comment #38
joachim commentedPotentially clashes with #2292217: ThemeNegotiator::determineActiveTheme() should not require a RouteMatch to be passed in.