Skip to content
This repository has been archived by the owner on Nov 6, 2022. It is now read-only.

PHP performance profiling #485

Open
kienstra opened this issue Nov 28, 2019 · 6 comments
Open

PHP performance profiling #485

kienstra opened this issue Nov 28, 2019 · 6 comments

Comments

@kienstra
Copy link
Collaborator

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.

@kienstra
Copy link
Collaborator Author

kienstra commented Dec 2, 2019

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

  1. Activate Twenty Nineteen. Deactivate all plugins except Block Lab, and a plugin that adds the snippets below.

  2. 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',
					),
				),
			)
		);
	}
);
  1. 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>
  1. 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"} /-->'
  1. Go to the front-end of the post, and run 10 Blackfire profiles of the back-end performance (results below)

block-lab-dynamic-block

Without Block Lab

Using a custom dynamic block, instead of Block Lab

  1. Deactivate Block Lab
  2. 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
}
  1. 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"} /-->'
  1. 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.

@lukecarbis
Copy link
Member

lukecarbis commented Dec 2, 2019

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).

@kienstra
Copy link
Collaborator Author

kienstra commented Dec 2, 2019

Great idea! I'll work on a script for that.

@kienstra
Copy link
Collaborator Author

kienstra commented Dec 2, 2019

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.

blocks-via-ui

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.

@kienstra
Copy link
Collaborator Author

kienstra commented Dec 2, 2019

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

  1. Activate Twenty Nineteen
  2. Deactivate all plugins except Block Lab
  3. 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.'
  1. Go to the front-end, and run 10 Blackfire profiles
  2. Deactivate Block Lab
  3. Repeat step 4

front-end-post

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

@kienstra
Copy link
Collaborator Author

kienstra commented Dec 2, 2019

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants