Problem/Motivation
This is probably a twig issue and not Drupal, however, there appears to be a significant page load performance issues (especially on admin entity create/edit forms such as node forms) introduced after upgrading from twig/twig 3.14.0 to 3.14.2. This is more noticeable on hosting platforms such as Acquia.
Steps to reproduce
- Upgrade to twig to 3.14.2
- Open a node create or edit form
- or reload an existing page
- observe slow load times, over 30 seconds in some cases
Proposed resolution
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #51 | 3487031-10.2.x.patch | 5.5 KB | longwave |
| #34 | After Edit speed.png | 143.77 KB | sagarmohite0031 |
| #34 | After admin speed.png | 134.95 KB | sagarmohite0031 |
| #34 | Before speed.png | 143.01 KB | sagarmohite0031 |
| #26 | 2024-11-14_10-33.png | 83.87 KB | tuutti |
Issue fork drupal-3487031
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:
- 3487031-performance-degraded-after
changes, plain diff MR !10177
Comments
Comment #2
gravelpot commented@themodularlab, could you elaborate on "This is more noticeable on hosting platforms such as Acquia?"
We are hosted on Pantheon, and right now our limited testing doesn't show any noticeable difference on loading the node edit form on the same site running Twig 3.14.0 and 3.14.2.
Can you describe the testing you've done to indicate that it is _more_ noticeable on Acquia, to see if we can replicate on Pantheon?
Is there something specific you suspect about Acquia's architecture versus other platforms where you haven't seen this performance hit?
Comment #3
themodularlab@gravelpot
We haven't done any official performance testing but rather this is something observed by myself and my clients. Prior to updating to 3.14.2, page load times were pretty normal. After 3.14.2, our page load for a node edit form can be well over 30 seconds. We are building a new site so there is very little content at this point. As a test, I downgraded back to 3.14.0 and page load times returned to normal.
There may be some server settings in place on our Acquia env that could be partially contributing to this but also the performance and page load times return to normal when downgrading back to 3.14.0.
Based on this part of the 3.14.2 patch, it looks like they're recursing through everything even before trying to render it?
Comment #4
themodularlabComment #5
themodularlabComment #6
ericgsmith commentedI have not noticed the degradation other than locally. When xdebug is enabled it's unusable in places, pages like the permission page fail to load (timeout). On environments without xdebug I didn't notice a difference but have not profiled or measured it.
Comment #7
gravelpot commented@themodularlab
I guess what I was really getting at was this -- since you said that it seems "more noticeable" on Acquia, that implied to me that there were other hosting environments where it seemed less noticeable to you. Is that actually the case?
Comment #8
themodularlab@gravelpot,
I have only personally observed on a local env and via Acquia. I have seen others reporting similar issues but unsure of what hosting they are using.
Comment #9
cilefen commentedIndeed the next step is to profile to find the exact cause.
Comment #10
cilefen commentedTo keep our eyes on the changes: https://github.com/twigphp/Twig/compare/v3.14.0..v3.14.2
Comment #11
larowlanSo the difference for twig between these versions is it now loops over any array and checks if any objects inside it are safe to convert to string
But in Drupal we don't do any object specific 'is safe to convert to string' checks because our sandbox policy permits anything that has a __toString method
We can't override the method in the sandbox extension because it's final, so I think we need to propose a PR to symfony for an escape hatch
Comment #12
ericgsmith commentedI checked the logs locally - loading the permissions page on a project (10.3.6) with lots of contributed modules and 8 roles (and with env var
XDBEUG_MODE: "off") does show a big difference in response time.First run on twig 3.14.0
After a drush cr:
"duration":4.943, "cpu_user":42.08,"cpu_system":5.26,"cpu_total":47.34,"memory_peak":135180288Subsequent load with a warmed cache:
"duration":1.550,"cpu_user":86.44,"cpu_system":5.81,"cpu_total":92.25,"memory_peak":107917312After updating to twig 3.14.2
After a drush cr:
"duration":14.603,"cpu_user":83.95,"cpu_system":1.78,"cpu_total":85.73,"memory_peak":135180288Subsequent load with a warmed cache:
"duration":11.857,"cpu_user":97.83,"cpu_system":1.18,"cpu_total":99.01,"memory_peak":107917312Comment #13
ghost of drupal pastY'all seriously need to consider adding the composer patches plugin and start patching out the final brainrot from upstream.
Comment #14
catch10 second+ response times up from 1+ second is critical. Do we know if there's already an upstream issue to track this?
Comment #15
longwaveI don't see anything at https://github.com/twigphp/Twig/issues, we would probably need to create sample code that demonstrates the issue.
Comment #16
mkalkbrennerWe have some big and complex entity forms in our backend systems. Since the lastest security updates, the loading time of a very important form increased from 1.5 seconds to more than 50 seconds. Way more than factor 10.
Running
composer require twig/twig:"3.14.0 as 3.14.2"reduced the loading time to 1.5 seconds again!Comment #17
fjgarlin commentedFrom https://github.com/twigphp/Twig/compare/v3.14.0..v3.14.2
I guess the method
ensureToStringAllowedForArraymight be the culprit (it's a loop and it's recursive) as some Drupal objects are definitely quite big. They tried to fix infinite recursion in 3.14.2, but the fact that objects are traversed might cause the performance issue.Comment #19
larowlanI've opened an MR that shows a possible approach. When we're using our default sandbox policy, we don't need to check to string on any objects, they're all allowed, so can sidestep it altogether.
Haven't tested this and haven't linted either, but see if it helps
Comment #20
larowlanCode in the MR is working, site looks as normal and
\Twig\Extension\SandboxExtension::ensureToStringAllowedis no longer running. Couple of random fails that I've rerunComment #21
ericgsmith commented🙌 🙌 🙌
Quick test with same project I mentioned in #12 - using twig 3.14.2 and the patch from MR10177 at commit 67bbb312 which applied cleanly to 10.3.6
After drush cr
"duration":4.683,"cpu_user":47.20,"cpu_system":5.98,"cpu_total":53.18,"memory_peak":137277440(original 3.14.0 duration was 4.943 so back to normal)
Subsequent load with a warmed cache:
"duration":1.559,"cpu_user":86.62,"cpu_system":7.70,"cpu_total":94.32,"memory_peak":107917312(original 3.14.0 duration was 1.550 so back to normal)
Only did the comparison a couple of times with slight variance in times but certainly appears to resolve the performance issue with no noticeable side effects.
Have not done a thorough code review but good to me - thanks Lee!
Comment #22
themodularlabApplying the patch from MR10177 on 10.3.8 is also showing improvements for me. I have only tested locally but will be pushing to a dev environment soon so I can report back later. But so far so good!
Comment #23
mstrelan commentedI suspect the fails in the pipeline are random fails, but I'm not seeing the button to retry.
Comment #24
larowlanRerunning the fails, the last build was green, so confident they're random
Comment #25
larowlanMR is green
Comment #26
tuutti commentedWe've seen a degraded performance (~20%) on our testing environment since Twig 3.14.2 update as well.
I applied this patch and the performance graphs went back to similar levels as before.
Without patch:
/node/{node}/edittook 2.04sec on average,template.rendertook 482-720ms/admin/people/permissionstook 9.1sec on average,template.rendertook 8190-8280msWith patch:
/node/{node}/edittook 982ms on average,template.rendertook 121-330ms/admin/people/permissionstook 2.42sec on average,template.rendertook 1402-1503msComment #27
catchThis looks very nifty. I left one small comment on the MR.
Comment #28
stopopol commented+1
Comment #29
andypostComment #33
alexpottI've addressed the review feedback and created the follow-up #3488584: Simplify RemoveCheckToStringNodeVisitor when Twig 4.0 is released
Comment #34
sagarmohite0031 commentedHello,
Tested and verified with drupal 11.
MR applied successfully its working as expected.
Check attachments
Comment #35
rhovlandCan confirm this fixes the issue in Drupal 10.3.9. While I wasn't seeing any performance impacts in most areas of my site the permissions page was completely broken and hit the server timeout whenever I tried to load it. Applying this MR as a patch restores the performance.
Comment #36
timohuismanThis patch contains a snapshot of MR10177 so it can be safely used with composer-patches.
Comment #37
spokje- Code changes makes sense (and are quite ingenious IMHO)
- Seems to work according to the "profiling" comments in here.
Would love to RTBC, the only thing keeping me from doing so is the last commit, which introduced the setting
twig_sandbox_allowed_methodsto overrule the predefined list of allowed methods.I think if we introduce a new setting, a commented example should be in
web/sites/default/default.settings.phpwith some comments about what it does.Then again: n=1, your mileage/opinion may vary, yada yada
Comment #38
longwave@spokje this was already a "hidden" setting, just it's used in two places instead of one now. I think documenting it could be done in a followup.
Comment #39
spokjeThanks @longwave, pulling the trigger
Comment #40
rossb89 commentedJust another update in regards to performance here (without patch!)
Testing out the 10.3.9 update which includes the 3.14.2 update locally on ddev with a m4 mac mini, loading up the permissions page on a project with a relatively large amount of contrib modules + permissions took about 6 seconds.
The site is hosted on Pantheon and on pantheon, a dev environment before the update was applied was also taking about 6 seconds to load the permissions page.
On a multidev environment with the 10.3.9 update including the twig update, the permissions page now takes 30+ seconds to load.
This wasn't immediately obvious that there was an actual performance issue here (locally) as ddev &/ m4 chip was masking it... but it's very much an issue with the site hosted in Pantheon :)
Comment #41
herved commentedTested this on our project at /admin/people/permissions, using network tab:
In practice, I did not notice any performance degradation at first. Probably because the form has to be very complex, and the browser itself (UI performance) has to keep up anyway for example for this permission page. But there seems to be quite an impact indeed on a pure PHP performance. This may also behave worse on different environments as others stated.
I also ran the same tests with xhprof and the results are telling, it goes from 3s to 46s to load the page, with a very high wall time on
Twig\Extension\SandboxExtension::ensureToStringAllowed.So +1, looks like it fixes it, thank you!
Comment #48
catchLooks good. Committed/pushed to 11.x and cherry-picked back through to 10.3.x, thanks!
Comment #50
_pratik_The commit in #42 would work for 10.2.10 also ?
Comment #51
longwavePlease try the attached patch if you have upgraded Twig in 3.14.2 and are seeing the performance regression.
Comment #53
longwaveWe have released Drupal 11.0.9, 10.3.10 and 10.2.12 today which includes this fix, and therefore avoids having to make the choice between staying on an insecure version of Twig or suffering from performance issues.
Comment #54
steven jones commented@longwave at al thanks very much! We appreciate the effort to do an extra release so we can have our sites both secure and speedy.
Comment #55
roger.bertran commentedWe are using the Drupal 10.3.10 and the performance issues are still happening, we are also using Entity browser and after adding 4 or 5 paragraphs it freezes and makes impossible to work.
Comment #56
alexpott@roger.bertran have you confirmed that downgrading twig to 3.14.0 makes the performance issue go away? Have you confirmed that your issue is caused by this?
Comment #57
roger.bertran commented@alexpott after downgrading to twig 3.14.0 the performance issue remains. We've seen that the performance starts to decrease when we work with the entity browser or autocomplete widgets, if we don't interact with these widgets we have no trouble.
Comment #58
alexpott@roger.bertran then your issue is unrelated to this specific issue. You need to open a new issue with steps to reproduce and ideally some profiling of your codebase so you can determine where the performance problem is coming from.
Comment #59
roger.bertran commented@alexpott ok, my bad, thanks for your support!