PHP performance profiling
Opened this issue · 6 comments
It'd be good to have an idea of this plugin's effect on front-end performance.
This might also point out areas that we could improve. For example, if a certain function is taking too long.
Block Lab Compared To Implementing Your Own Dynamic Block
What's the PHP performance cost of using Block Lab for 1 block, compared to implementing your own dynamic block?
In the test below, there was an average cost of about 87 milliseconds to use Block Lab. For reference, this is slightly less than the cost of Gutenberg or Yoast.
Here's a Blackfire profile of Block Lab:
https://blackfire.io/profiles/e4978c69-4bf2-462e-a195-69fa81d93372/graph
This test was for the public-facing front-end, not for the block editor.
Methodology
Create 2 posts, one with a Block Lab block, and one with an equivalent dynamic block that doesn't use Block Lab
With a Block Lab block
-
Activate Twenty Nineteen. Deactivate all plugins except Block Lab, and a plugin that adds the snippets below.
-
Add the Block Lab block:
add_action(
'block_lab_add_blocks',
function() {
block_lab_add_block(
'test-hero',
array(
'title' => 'Test Hero',
'category' => 'common',
'fields' => array(
'headline' => array(
'label' => 'Headline',
'control' => 'text',
),
'copy' => array(
'label' => 'Copy',
'control' => 'textarea',
),
'url' => array(
'label' => 'URL',
'control' => 'url',
),
),
)
);
}
);
- Then, add the template for it in the theme or plugin, at
blocks/block-test-hero.php
:
<?php
/**
* Template for test-hero block.
*/
?>
<h1><?php esc_html_e( 'Testing Block Lab dynamic block', 'bl-testing' ) ?></h1>
<p><?php esc_html_e( 'Here is the headline attribute:', 'bl-testing' ) ?></p>
<p><?php echo esc_html( block_value( 'headline' ) ); ?></p>
<p><?php esc_html_e( 'And the copy attribute:', 'bl-testing' ) ?></p>
<p><?php echo esc_html( block_value( 'copy' ) ); ?></p>
<p><?php esc_html_e( 'And the url attribute:', 'bl-testing' ) ?></p>
<p><?php echo esc_html( block_value( 'url' ) ); ?></p>
- Populate the block via WP-CLI:
wp post create --post_title="With Block Lab" --post_status='publish' --post_content='<!-- wp:block-lab/test-hero {"headline":"This is an example headline", "copy":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.","url":"https://example.com/baz"} /-->'
- Go to the front-end of the post, and run 10 Blackfire profiles of the back-end performance (results below)
Without Block Lab
Using a custom dynamic block, instead of Block Lab
- Deactivate Block Lab
- Register a dynamic block, like the block above:
add_action(
'init',
function() {
register_block_type(
'bl-testing/hero',
[
'attributes' => [
'headline' => [
'type' => 'string',
],
'copy' => [
'type' => 'string',
],
'url' => [
'type' => 'string',
],
],
'render_callback' => 'bl_testing_render_dynamic_block',
]
);
}
);
/**
* The render callback function for the dynamic block.
*
* @param array $attributes The attributes to render.
*/
function bl_testing_render_dynamic_block( $attributes ) {
$attributes = wp_parse_args(
$attributes,
[
'headline' => '',
'copy' => '',
'url' => '',
]
)
?>
<h1><?php esc_html_e( 'Testing dynamic block', 'bl-testing' ) ?></h1>
<p><?php esc_html_e( 'Here is the headline attribute:', 'bl-testing' ) ?></p>
<p><?php echo esc_html( $attributes['headline'] ) ?></p>
<p><?php esc_html_e( 'And the copy attribute:', 'bl-testing' ) ?></p>
<p><?php echo esc_html( $attributes['copy'] ) ?></p>
<p><?php esc_html_e( 'And the url attribute:', 'bl-testing' ) ?></p>
<p><?php echo esc_html( $attributes['url'] ) ?></p>
<?php
}
- Populate that block with WP-CLI:
wp post create --post_title="Without Block Lab" --post_status='publish' --post_content='<!-- wp:bl-testing/hero {"headline":"This is an example headline", "copy":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.","url":"https://example.com/baz"} /-->'
- Go to the front-end of the post, and run 10 Blackfire profiles of the back-end performance
Performance Results
Milliseconds that PHP took to produce the HTML document (in 10 trials)
With Block Lab | Without Block Lab |
---|---|
274 | 183 |
269 | 173 |
254 | 173 |
267 | 172 |
256 | 173 |
267 | 184 |
254 | 174 |
264 | 174 |
253 | 173 |
265 | 172 |
Average of Trials
With Block Lab | Without Block Lab |
---|---|
262.3 | 175.1 |
Difference: 87.2 milliseconds
What does this profile test?
Only the time PHP took to generate the HTML document, not the browser parsing the document. Block Lab doesn't use JavaScript on the front-end, only in the block editor.
It would be interesting to run the same comparison, but with 10 instances of the block in the content.
It would also be interesting to run the same comparison, but without any blocks in the content (just the Block Lab plugin overhead).
Great idea! I'll work on a script for that.
Scalability
I'll also test how well Block Lab scales.
The main WP_Query usage is for the blocks added via the UI (stored in a custom post type). But this has a posts_per_page
value of 100
to minimize scaling issues.
Block Lab has a PHP API that should be used when there are more than 100 blocks needed:
block_lab_add_block(
'testing-block',
...
I'll test whether this has memory or performance issues with extreme amounts of blocks, like in the hundreds.
Performance of Block Lab When There's No Block
What's the PHP performance cost of Block Lab on the front-end of a post that doesn't have a Block Lab block?
In the test below, the average cost of Block Lab was 83.4 milliseconds, very similar to the test above with 1 block.
Here's a Blackfire profile of this:
https://blackfire.io/profiles/f7414907-bbcb-4200-8c3c-6e66e615a1a5/graph
Methodology
- Activate Twenty Nineteen
- Deactivate all plugins except Block Lab
- Create a new post with WP-CLI:
wp post create --post_title="Lorem post" --post_status='publish' --post_content='Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
- Go to the front-end, and run 10 Blackfire profiles
- Deactivate Block Lab
- Repeat step 4
Performance
Milliseconds that PHP took to produce the HTML document (in 10 trials)
With Block Lab | Without Block Lab |
---|---|
275 | 200 |
278 | 189 |
274 | 190 |
261 | 196 |
284 | 188 |
275 | 187 |
282 | 200 |
277 | 189 |
278 | 188 |
264 | 187 |
Average of Trials
With Block Lab | Without Block Lab |
---|---|
274.8 | 191.4 |
Difference: 83.4 milliseconds
The test above might show some chances for improvement.
For example maybe Block_Post::register_controls() could only run on the front-end when Loader::render_block_template() runs.
If there's no Block Lab block on the front-end, there shouldn't be a need to register block controls.