Parsing: Use full parser in do_blocks with nested block support#11141
Parsing: Use full parser in do_blocks with nested block support#11141
do_blocks with nested block support#11141Conversation
lib/blocks.php
Outdated
| @@ -164,11 +164,32 @@ function gutenberg_render_block( $block ) { | |||
| } | |||
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
|
encapsulated ^^ into a pr, with unit tests: |
|
Moving out of 4.2 as we have to release soon. |
35e4377 to
bff5592
Compare
do_blocks with nested block supportdo_blocks with nested block support
13cdfdd to
a5f5afb
Compare
a9d0ecc to
03ca73d
Compare
do_blocks with nested block supportdo_blocks with nested block support
|
Previous changes on this branch before the rebase… |
79e6ec5 to
16a4175
Compare
|
@aduth if you look at the failing tests you can see that we're hitting trailing-newline issues because in the existing can you help me understand what our desired end-product is so I can implement it? or, if it doesn't matter, should I update the test fixtures? if we look at the parser output we can see that these newlines end up as freeform blocks whose contents are exactly |
aba181b to
6d713cd
Compare
8e2e243 to
7309d7f
Compare
|
Upon reflection, I don't think I'll follow up with a PR after this one is merged to explore that. |
Updates
do_blocks()andgutenberg_render_block()so that we can support nested blocks inside of dynamic blocks. This replaces the use of the partial parser which extracts registered dynamic blocks with the full parser.This change will allow dynamic blocks which contain nested blocks inside of them and it will pave the way for a filtering API to structurally process blocks.
The partial parser came about at a time before the default parser was written; it was faster than the spec parser and was a tradeoff to get dynamic blocks rendering. The default parser, however, has been fast enough for a while to run on page render and so this PR exists to finally get it into the pipeline.
Status
Iteration
TheRecursiveIteratorIteratorshould provide us a way of performing the depth-first block traversal without risking a stack overflow. We keep rendered blocks on a stack and pop them off as we go.Interestingly enough I did some testing and
RecursiveIteratorIteratorwas a let-down. There's one important thing it does which is bypass thexdebug.max_nesting_levelwhich limits recursion depth whenxdebugis running; sadly it's much much slower than basic recursion.With the
RecursiveIteratorIteratorwe can continue to nest into blocks until we run out of memory but the runtime performance is exponential. With recursion we hit the same memory limit ifxdebugis disabled but hit it usually around 100 if it is. That means that for massive posts we could run into unexpected failures when debugging if we go the recursion route.What is the memory limit? In my testing back to PHP 5.6 on my local laptop it was at around 100,000 levels of nesting - this should be obviously sufficient - I can't imagine an editor showing that many levels of nesting. With the recursive version and a limit of 100 that's still almost equally viable as 100,000. I'd recommend we stick with this recursive approach then unless we get bug reports of failures when debugging, at which point we can discuss bringing back the
RecursiveIteratorIteratorversion.On the other hand I may simply have been writing the
WP_Block_Tree_Iteratorin a stupid way that was way too slow. It would be worth running an experiment where I make a custom tree iterator without using the SPL functions and see if the performance characteristics are similar.Update
After running some tests I made ended up with a basic tree iterator and it hit hard performance issues long before the recursive version. I think that the memory churning of the stacks required to track nodes in the tree is far less efficient than using the built-in argument passing in functions and closures provided by PHP with the recursive method.
In other words, I am currently unable to come close to the recursive version in terms of performance. Does this matter with small nesting? Probably not. Should we then prefer the safe version that won't break with low
max_nesting_depth? I don't know. Probably not since anything over 100 levels of nested blocks is somewhat of an insane construction.Testing and Review
The patch needs testing, but this can be hard because we don't have too many deeply-nested blocks. It's best to try with things like columns.
👉 I would greatly appreciate some help adding the appropriate deprecation messages for
get_dynamic_blocks_regex()and friends!