After updating the plugin on a site I noticed a performance decrease by 2-3 seconds.
$ wp profile stage --fields=stage,time,cache_ratio
+------------+---------+-------------+
| stage | time | cache_ratio |
+------------+---------+-------------+
| bootstrap | 1.0175s | 88.3% |
| main_query | 0.025s | 90.74% |
| template | 4.3431s | 93.54% |
+------------+---------+-------------+
| total (3) | 5.3856s | 90.86% |
+------------+---------+-------------+
vs.
$ wp profile stage --fields=stage,time,cache_ratio --skip-plugins=gutenberg
+------------+---------+-------------+
| stage | time | cache_ratio |
+------------+---------+-------------+
| bootstrap | 1.0935s | 88.09% |
| main_query | 0.0206s | 90.74% |
| template | 0.3426s | 93.54% |
+------------+---------+-------------+
| total (3) | 1.4567s | 90.79% |
+------------+---------+-------------+
Checking further
wp profile stage template --fields=hook,time,cache_ratio
+--------------------------+---------+-------------+
| hook | time | cache_ratio |
+--------------------------+---------+-------------+
| template_redirect:before | 0.001s | |
| template_redirect | 0.0239s | 98.46% |
| template_include:before | 0.0008s | 100% |
| template_include | 0s | |
| wp_head:before | 0.0028s | 100% |
| wp_head | 0.0904s | 98.31% |
| loop_start:before | 0.0287s | 93.58% |
| loop_start | 0s | |
| loop_end:before | 3.1046s | 91.02% |
| loop_end | 0s | |
| wp_footer:before | 0.0607s | 92.7% |
| wp_footer | 0.0017s | 100% |
| wp_footer:after | 0.0002s | |
+--------------------------+---------+-------------+
| total (13) | 3.315s | 96.76% |
+--------------------------+---------+-------------+
So I removed the filter on the_content and the load was back to normal. I also reverted the do_blocks() function to the previous version and the load was still normal. But once the PEG version is in use the page load increases by ~3 seconds.
_Will investigate further to get the exact cause for this._
Sounds like it would be a good idea to bail early when there are absolutely no blocks in a post, e.g. by doing a simple strpos() or regex search.
Looks like it just gets slower the more content you have. You can test with http://www.loremipsum.de/index_e.html. I started with 5 paragraphs and increased the content by 5 more paragraphs for each test.
358 words: 0.062175989151001s
921 words: 0.33092999458313s
1438 words: 0.77467513084412s
1793 words: 1.1339340209961s
This was foreseen as almost unavoidable. The grammar is both designed to be above-all easy to read and implement (so that more-performant versions can be built from it) and also built for JS consumption. PHP is a pretty bad platform on which to generate the parser due to the ways that the semantics of function calling and closures work. Instead we should prefer a hand-written parser that implements the necessary parts of the grammar for the server side.
I suspect some of the performance problems here are more related to #1611. I will look into a fix using the existing setup and I am confident that we can achieve a reasonable result here.
PHP is a pretty bad platform on which to generate the parser due to the ways that the semantics of function calling and closures work.
There are no closures in the generated parser - I've removed them from the code because they are not supported on PHP 5.2.
I am also skeptical that function calling semantics are the problem. Can you elaborate on that?
Instead we should prefer a hand-written parser that implements the necessary parts of the grammar for the server side.
It is mandatory that client and server parsing behave the same way. I see two ways to achieve this:
We also having the similar issue of the slow parser cause php maximum execution timeout.
And since the parser use filter the_content, it cause very slow post indexing to Elasticsearch using ElasticPress plugin.
I'm using the Gutenberg v0.3.0 and use Gutenberg Demo content.
I'll implement a fix for this in time for this week's release.