Skip to main content
Adzbyte
TutorialsWordPress

Load WordPress Block Assets Only When Needed

Adrian Saycon
Adrian Saycon
September 18, 20264 min read
Load WordPress Block Assets Only When Needed

The cleanest way to load custom block assets only when needed is to declare them in block.json and let WordPress enqueue them in the correct context. Separate editor-only code, shared styles, front-end styles, and interactive front-end scripts instead of attaching everything to wp_enqueue_scripts. This tutorial refactors a testimonial block so ordinary pages no longer download its CSS or JavaScript, while the editor still receives the files required to edit it. The result is less unused code without fragile content scanning or manual page rules.

Map each asset to its real audience

Before changing code, classify every file:

  • editorScript: block registration and editor UI only.
  • editorStyle: editor-only presentation.
  • style: shared styles used in the editor and front end.
  • viewStyle: front-end-only styles.
  • viewScript or viewScriptModule: front-end behavior.
  • script: JavaScript genuinely required in both contexts.

Most blocks need fewer global assets than their first implementation suggests. A static block often needs no front-end JavaScript at all. Conversely, an interactive control should not rely on an editor bundle that never loads for visitors. Make this classification before choosing filenames; it is an architectural decision, not only a build configuration.

Declare files in block.json

Point metadata at compiled files with the file: prefix. A build tool such as @wordpress/scripts can generate dependency metadata for JavaScript entry points.

{
  "$schema": "https://schemas.wp.org/trunk/block.json",
  "apiVersion": 3,
  "name": "adz/testimonial",
  "title": "Testimonial",
  "category": "text",
  "editorScript": "file:./index.js",
  "editorStyle": "file:./index.css",
  "style": "file:./style-index.css",
  "viewScript": "file:./view.js",
  "supports": { "html": false }
}

If the testimonial has no interaction, delete viewScript. Do not retain an empty bundle merely because the scaffold created one.

Register the block on the server

Registering metadata in PHP gives WordPress the information it needs to manage dependencies and contexts.

add_action( 'init', function () {
    register_block_type( __DIR__ . '/build/testimonial' );
} );

Register paths from the plugin directory, not from a URL and not by assuming the process’s working directory. Confirm the built block.json and referenced files are included in the release artifact.

Remove competing global enqueues

Legacy code often loads the same files globally:

// Remove this after metadata owns the assets.
add_action( 'wp_enqueue_scripts', function () {
    wp_enqueue_style( 'adz-testimonial' );
    wp_enqueue_script( 'adz-testimonial-view' );
} );

Having both systems active can create duplicate requests, conflicting versions, or a false test result in which the block seems fine only because the global fallback remains. Search handles and filenames across the plugin before deleting the hook.

Understand the theme dependency

On-demand block styles depend partly on the theme and core configuration. Modern block themes and sites using separate core block assets get the best granularity. Some classic-theme setups combine or globally load styles for compatibility. Treat metadata as the correct declaration, then verify actual network behavior on the target site rather than promising one request pattern everywhere.

For dynamic blocks, WordPress can detect the rendered block during page generation. For reusable patterns, templates, and widgets, test the actual placement because detection can differ from a simple post-content example.

Guard conditional custom enqueues carefully

Sometimes a third-party library cannot be represented cleanly as a local metadata file. The block render callback can enqueue it only when rendering, then return markup.

function adz_render_map_block( $attributes ) {
    wp_enqueue_script(
        'adz-map-library',
        plugins_url( 'assets/map.js', __FILE__ ),
        array(),
        '1.2.0',
        true
    );

    return sprintf(
        '<div %s></div>',
        get_block_wrapper_attributes()
    );
}

This is preferable to scanning only the_content with has_block(), which can miss template blocks, widgets, nested content, or programmatically rendered blocks. Still, local, metadata-declared assets are easier to audit and package.

Measure before and after

  1. Choose one page containing the block and one page without it.
  2. Record CSS and JavaScript requests, transferred bytes, and coverage before the change.
  3. Clear page, object, CDN, and browser caches.
  4. Confirm the editor loads its UI and shared styles.
  5. Confirm the block page loads the declared front-end assets once.
  6. Confirm the control page does not load block-only assets.
  7. Test logged-in, logged-out, minified, and production-cache paths.

A Lighthouse score alone cannot prove conditional loading. Use the browser network panel or an automated assertion against request URLs.

Handle dependencies and cache versions

Do not manually guess WordPress package dependencies. Use generated .asset.php files where the build system supports them. When registering custom handles, use a plugin version or file hash so deployments do not leave visitors with mismatched cached assets. Avoid filemtime() as the permanent production version if release artifacts can have inconsistent timestamps across servers.

Third-party scripts deserve an additional review. Confirm whether the library is needed for every instance, whether several blocks can share one registered handle, and whether loading it creates consent or privacy obligations. Register a single stable handle with explicit dependencies, then enqueue that handle from the block context. Copying the same library into several block bundles increases bytes and makes security updates harder to track.

Let metadata describe the architecture

Good asset loading begins with an honest description of where each file runs. block.json makes that architecture inspectable by WordPress, build tools, and future maintainers. Remove unused bundles, separate editor and view code, and test a page that does not contain the block. The official block metadata reference documents each asset property; performance comes from using the narrowest appropriate one and verifying the result on the real theme.

Photo by Lukas Blazek on Pexels.

Adrian Saycon

Written by

Adrian Saycon

A developer with a passion for emerging technologies, Adrian Saycon focuses on transforming the latest tech trends into great, functional products.

Discussion (0)

Sign in to join the discussion

No comments yet. Be the first to share your thoughts.

Latest Articles

From the Blog

View all articles