I finally have an understanding of how the NodeVisitor works.
As more and more in Core switches to render arrays within templates, the need for performance improvements increases again.
Fortunately I have found a great solution for a syntax that is really fast and sane at the same time:
{{ attribute(name.foo, attribute(name.foo, "key")) }}
becomes
if (isset($context["name"])) { $_name_ = $context["name"]; } else { $_name_ = null; }
echo twig_render($context, array( "#twig_reference" => TRUE, "template" => $this, "path" => array(array("name", "name"), array( "attribute", "foo"), array( "attribute", $this->getAttribute($this->getAttribute($_name_, "foo"), "key")))));
As twig_render already needs to check for instanceof TwigReference it can as well also check an arbitrary array key, but instead of getting the reference directly the context is unwrapped by following the stored path.
We also know that render arrays are likely to occur, such we check for array first and only in the case that it is no array, the normal getAttribute function is called.
Note how the code makes proper use of the property that we don't need attribute keys to return references. These use the normal Twig getAttribute function.
Note: It is important to keep getAttribute as much as possible as those are replaced by fast calls to the C extension - if it is installed.
All the new magic is at compile time and while there is still work needed to make it into a proper patch and benchmark it, I'll post some draft (non-patch) here soon.
@see http://twig.sensiolabs.org/doc/functions/attribute.html
| Comment | File | Size | Author |
|---|---|---|---|
| #28 | 1922304-28.patch | 11.3 KB | star-szr |
| #28 | interdiff.txt | 1.6 KB | star-szr |
| #26 | 1922304-26.patch | 11.32 KB | star-szr |
| #26 | interdiff.txt | 679 bytes | star-szr |
| #18 | issue-1922304-18.diff | 11.32 KB | fabianx |
Comments
Comment #1
fabianx commentedAttached a first working implementation just with Twig.
Comment #2
fabianx commentedForgot the performance tag.
Comment #3
podarokpossibly this needs more documentation - looking at code and its not clear to understand
Comment #4
fabianx commentedBumping, this is an important issue for Twig speed.
Comment #5
joelpittetThe twig syntax is not very clear on what it is doing. Maybe you could provide a more concrete example of this? Is {{ attribute(,) }} in reference to an Attribute() instance or is that just a name collision?
Comment #6
fabianx commentedYes, I will add additional information soon on how this is working.
Comment #7
mhagedon commentedCleaned this up with @fabianx
Comment #8
mhagedon commentedMoved all classes into Drupal, made a proper patch, and giving testbot a chance but will probably fail. (with @fabianx)
Comment #9
mhagedon commentedUpdated the test script to work with the Drupal functions. Can be run with drush scr.
Comment #11
mhagedon commentedWorked on this some more by myself and with @Fabianx. This patch isn't working, but uploading anyway for reference per @Fabianx. The issue we were trying is that if we make TwigReferenceNodeVisitor run after TwigNodeVisitor, it doesn't work. But it needs to run after.
Comment #12
mhagedon commentedHere's the test script.
Comment #13
mhagedon commentedHad some problems with the uploader... but this is the template referenced in the test script.
Comment #15
joelpittet@mhagedon great work on this, #11 seemed to be an interdiff instead of the diff and that's why it didn't apply also a few whitespace errors too. I am just putting this back up as your #11 patch with an interdiff from #8
Comment #16
joelpittetjust some spacing cleanup because I forgot to click Needs Review to activate the testbot... so.
Comment #18
fabianx commentedOkay, I cleaned this up from scratch, so no interdiff for this:
* This is actually working and almost ready for prime time.
* Next steps are to write more tests (once it passes test bot) then do some initial profiling.
* Code style and remove commented out code
* Enjoy!
I also attached the new test script and test htm.twig, which can be still run via:
$ drush scr test-twig-reference-node-visitor.php
It is exciting to see this work!
EDIT: I simplytest.me'ed it and it hide was working fine for node.html.twig in bartik!
Comment #19
star-szrHere's some profiling data, for a node page with 50 threaded comments. Quite a nice improvement!
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=51a944519b58c&...
http://www.lionsad.de/xhprof-kit/xhprof/xhprof_html/?run1=51a944519b58c&...
Comment #21
fabianx commented#18: issue-1922304-18.diff queued for re-testing.
Comment #23
star-szrI think this does need more work, I ran the theme tests locally and saw a bunch of errors like:
Argument 1 passed to Drupal\Core\Template\TwigNodeExpressionGetAttrReference::compile() must be an instance of Drupal\Core\Template\Twig_Compiler, instance of Twig_Compiler given, called in core/vendor/twig/twig/lib/Twig/Compiler.php on line 97 and definedFor example run 'Entity filtering theme test' under the Theme group.
Comment #24
fabianx commentedah, nice catch :)
Comment #25
star-szrTalked to Fabian, I will see if I can push this along a bit further over the next few days or so.
Comment #26
star-szrThis should help, all tests in the 'Theme' group pass now. If testbot likes it I will work on docs and coding standards.
Comment #28
star-szrUncommenting the commented out code seems to make tests pass so putting this up to see what happens.
Comment #30
star-szrI haven't been able to make any progress on this. The patch in #28 has less fails from testbot but overall the patch in #26 works better. The main issue I'm seeing with #28 is that it's rendering children it shouldn't, which leads me to think that there are elements that should be references that aren't being turned into references.
Comment #31
fabianx commentedThanks for bringing this along so far.
Comment #32
star-szrGoing to do some coding standards and other cleanup and see if I can start to understand things a bit more :)
Comment #33
star-szrUnassigning for now, unfortunately I didn't have as much time in the past few days to look at this.
Comment #34
fabianx commentedDrupalCon!
Comment #34.0
fabianx commentedUpdated issue summary.
Comment #35
star-szrThis will likely be a duplicate of #2114563: Remove TwigReference with the help of 'without' filter replacing 'show'/'hide' functions..
Comment #36
star-szrThis is a duplicate now that #2114563: Remove TwigReference with the help of 'without' filter replacing 'show'/'hide' functions. is in.