How to support Lazy Loading Assets in a WordPress Theme?

I’m using the create-block module provided in Gutenberg Core to build my custom blocks within a plugin. It works great, but I’m struggling to figure out how to conditionally load the assets on the frontend only if the block is present. I found a work around by enqueuing the frontend styles during the ‘render_callback’ function, but if I go this route I have to disregard the blocks.json file and enqueue everything manually. I would like the benefits of registering the block via the metadata file…like server-side registration, etc.

In the documentation here. It says that when themes support lazy loading assets, the enqueuing is optimized out of the box. The next sentence says frontend CSS and Javascript assets…will only be enqueued when the block is present on the page, resulting in reduced page sizes.

enter image description here

When I use the default code (below) that is created after running npx @wordpress/create-block Then the blocks styles are enqueued in the head of every page. Even if the block isn’t present. See screenshot below of my page loading with both CSS files while only one block is present:

enter image description here

Here is the default code that comes with the create-block package:

function mx_blocks_plugin_block_one_block_init() {
    register_block_type_from_metadata( __DIR__ );
}
add_action( 'init', 'mx_blocks_plugin_block_one_block_init' );

If I understand the documentation correctly, register_block_type_from_metadata() uses the block.json file to register the block serverside.

Here is the PHP code I’m currently using to enqueue the styles “only if the block is on the page”:

function mx_hero_image_block_init() {
    /* Automatically load dependencies and version */
    $asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');

    /* Main Block Script */
    wp_register_script(
        'mx-hero-image-main-script',
        plugins_url( 'build/index.js', __FILE__ ),
        $asset_file['dependencies'],
        $asset_file['version']
    );

    /* Frontend Styles */
    wp_register_style (
        'mx-hero-image-frontend-css',
        plugins_url( './build/style-index.css', __FILE__ ),
        null,
        $asset_file['version']
    );

    /* Editor Styles */
    wp_register_style (
        'mx-hero-image-editor-css',
        plugins_url( 'build/index.css', __FILE__ ),
        null,
        $asset_file['version']
    );

    register_block_type( 'mx/hero-image', array(
        /* Enqueue Main Script and Editor Styles */
        'editor_script' => 'mx-hero-image-main-script',
        //'editor_style' => 'mx-hero-image-editor-css',
        /* Enqueue frontend styles in the footer if the block is present on the page */
        'render_callback' => function( $attribs, $content ) {
            wp_enqueue_style( 'mx-hero-image-frontend-css' );
            return $content;
        }
    ) );
}
add_action( 'init', 'mx_hero_image_block_init' );

When enqueuing the scripts manually, this makes the blocks.json file irrelevant and I have to add the block metadata like the title, icon, category and attributes directly to the registerBlockType function in the index.js file. Based on the current documentation that I linked to above, there is supposed to be a way using register_block_type_from_metadata() function to still take advantage of lazy loading assets only if they are on the page.

I’ve been googling lazy loading assets for WordPress, but the articles I come across suggest the use of a plugin and most of the documentation is in regards to lazy loading images.

Is there a way for me to add support to lazy load my assets in my custom theme? If so what’s the best approach? Is there any issue loading the blocks via a plugin rather than in the theme itself?

Any help would be greatly appreciated!

0

Leave a Comment