Skip to content

fix: load block stylesheets and the admin script on demand, shrink the four Tailwind block bundles - #364

Merged
arifulhoque7 merged 2 commits into
weDevsOfficial:developfrom
arifulhoque7:fix/428-429-on-demand-block-assets
Sep 24, 2026
Merged

arifulhoque7 merged 2 commits into
weDevsOfficial:developfrom
arifulhoque7:fix/428-429-on-demand-block-assets

Conversation

@arifulhoque7

@arifulhoque7 arifulhoque7 commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Closes weDevsOfficial/wedocs-pro#428
Closes weDevsOfficial/wedocs-pro#429

Two commits on top of develop, one per issue. The same fix in its Tailwind 3 form sits on the v2.5.0-based branch hotfix/2.5.0-on-demand-assets (fork), which produced the drop-in zip for the reporter; this PR is the Tailwind 4 version for the next release. Pro companion: https://github.com/weDevsOfficial/wedocs-pro/pull/431 (independent, no merge-order dependency).

Problem

Reported by the HappyAddons team for https://happyaddons.com/new-home/ (weDocs 2.5.0, Hello Elementor). On every page of a classic-theme site, with no weDocs content on it:

  • assets/js/admin-script.js + weDocsAdminScriptVars (with a nonce): register_blocks() runs on init and called wp_enqueue_script( 'wedocs-admin-script' ). Only editor-side block JS reads that object (no view.js, no render callback), and the script is the wp-admin pro-notice handler.
  • All 17 block stylesheets: every block declares style in block.json, and on classic themes core enqueues the style of every registered block on every page (wp_enqueue_registered_block_scripts_and_styles, since wp_should_load_block_assets_on_demand() is false there). 5 external files (about 786 KB) plus 12 inlined.
  • Four of those stylesheets (Breadcrumb, Sidebar, DocNavigation, QuickSearch) were 189 to 206 KB each: they carry @tailwind base/components/utilities, built with the main config whose content scans all of src/, so each one emitted every admin-app utility, the whole daisyUI component set and 29 daisyUI theme variable blocks. That CSS was also unscoped: .btn, .card, .menu, .badge, .divider, :root { color-scheme: light } and 350 other daisyUI rules were applied site-wide on every classic-theme site.

Fix

#428, commit 1

  • wedocs.php: the front-end enqueue of wedocs-admin-script is removed. Assets::admin_enqueue() already enqueues it on every admin screen (block editor included), so weDocsAdminScriptVars stays available to the block editor.
  • includes/Assets.php: dequeue_block_styles_when_unused() runs on enqueue_block_assets at priority 20 (right after core's global enqueue) and removes the wedocs/* block styles unless the request can render a weDocs block: is_singular( 'docs' ), docs archive, doc_tag, the configured docs home page, or a singular post whose content contains <!-- wp:wedocs/. Block themes and WP 6.8+ sites that already load block assets on demand are untouched (nothing is enqueued globally there). A block placed anywhere else still gets its stylesheet from WP_Block::render() (it enqueues style_handles at render time). Filter wedocs_request_can_render_blocks for layouts the plugin cannot detect.

#429, commit 2

  • On develop (Tailwind 4) the four stylesheets build to 631 KB each (they were 190-206 KB on 2.5.0): Tailwind 4 scans the whole project for class names, so every utility the admin app uses lands in every block stylesheet, and each file also registers daisyUI (complete component set + theme variables, unscoped).
  • Each of the four files now carries @source not exclusions that keep the scan to the block sources and the front-end templates. (source(none) + @source is the tidier form, but with it Tailwind 4 drops the important scope from the JS config and the utilities lose their .wedocs-document prefix; measured, so the exclusion list is used instead.)
  • tailwind.blocks.config.js: same important scope and class-based dark mode as tailwind.config.js, content limited to src/blocks/** and the front-end templates.
  • daisyUI is no longer registered in these four files. No block markup, front-end or editor, uses a daisyUI component or theme colour (checked every className in src/blocks and templates; the only daisyUI class anywhere is the legacy [wedocs] listing's <hr class="divider">, which has its own rule in frontend.css).

Sizes on develop: Breadcrumb 631 KB to 33 KB, Sidebar 633 to 35, DocNavigation 632 to 34, QuickSearch 630 to 32. Every other build output is unchanged apart from asset version hashes. A class-set diff of old vs new CSS against every class token in src/blocks and templates shows nothing lost that any block markup uses.

Test evidence

Fresh site, WordPress 7.1, tested on Hello Elementor (classic) and Twenty Twenty-Four (block theme). Fixtures: plain page, single post, single doc (parent and child), a page with DocsGrid + QuickSearch blocks, the [wedocs] docs home page, the legacy single-doc template switched on.

#428 (2.5.0 package + the two PHP files, Hello Elementor):

page before after
plain page / single post 7 weDocs requests (5 block CSS, admin-script, store) 0 from this plugin (only Pro's assistant bundle, tracked in wedocs-pro#430)
page with DocsGrid + QuickSearch 10 9 (admin-script gone), blocks styled
single doc 10 9
[wedocs] docs home 10 9

Twenty Twenty-Four: plain page loads nothing before and after; single doc loads the same stylesheets before and after. Full-page screenshots before and after, pixel compared: single doc, DocsGrid page, docs home, plain page on both themes, legacy single-doc template on Hello Elementor: all identical (legacy template: anti-aliasing noise only, max pixel delta 19/255). Block editor: weDocsAdminScriptVars still present. Zero console errors on every fixture page.

#429 (develop build, unscoped vs scoped, Twenty Twenty-Four, composer deps installed with PHP 7.4): single doc (parent and child), DocsGrid + QuickSearch page, docs home page, and the quick search modal opened with a query and results: all five screenshots pixel-identical between the 631 KB and the 33 KB stylesheets. Block editor renders the blocks, weDocsAdminScriptVars present, no console errors. The same modal comparison on the 2.5.0 build (Tailwind 3 form of the fix) is pixel-identical too.

Two visible deltas, both on the legacy [wedocs] listing on classic themes, both the pre-2.2.7 look coming back rather than regressions: <hr class="divider"> renders as the plain rule frontend.css defines (daisyUI's flex divider no longer overrides it), and the always-visible scrollbar track of the .inside list (legacy overflow-y: scroll) is painted in the browser's default scheme because the unscoped :root { color-scheme: light } leak is gone. On block themes the listing already looked like this.

Must keep working (checked)

Single docs on classic (theme template, legacy template) and block themes; docs archive and docs home page; DocsGrid / QuickSearch placed on a normal page; blocks in the block editor (PRO badge logic reads weDocsAdminScriptVars); Elementor widgets (register-only, untouched); [wedocs] and [wedocs_faq] shortcodes; wp-admin pro-notice dismiss.

Drop-in build for the reporter

wedocs-2.5.0-on-demand-assets.zip: the wp.org 2.5.0 package with exactly 10 files replaced (wedocs.php, includes/Assets.php, and style-index.css + style-index-rtl.css for the four blocks, built from hotfix/2.5.0-on-demand-assets where the local npm run build reproduces the wp.org package byte for byte), verified with diff -rq, version unchanged.

https://claude.ai/code/session_019KGP9sp935QBeu32pGt5WY

Two things loaded on every front-end request of a classic-theme site,
whether or not the page had anything from weDocs on it:

- register_blocks() ran on `init` and enqueued `wedocs-admin-script`
  (plus `weDocsAdminScriptVars` with a nonce). Only editor-side block code
  reads that object; no view script or render callback does, and the
  script itself is the wp-admin pro-notice handler. admin_enqueue()
  already enqueues it on every admin screen, block editor included, so
  the front-end copy is dropped.
- Every block declares a `style` in block.json, and on classic themes
  WordPress enqueues the style of every registered block on every page
  (wp_enqueue_registered_block_scripts_and_styles). That put all 17
  weDocs block stylesheets on every page: about 786 KB external plus
  38 KB inlined on a page with no weDocs content.

Assets::dequeue_block_styles_when_unused() now runs right after core's
global enqueue and removes the weDocs block styles unless the request can
render a weDocs block: the docs post type (single, archive, tag), the
configured docs home page, or a singular post whose content contains a
`<!-- wp:wedocs/` block. Everything else is untouched, and a block placed
anywhere else still gets its stylesheet from the render-time enqueue in
WP_Block::render(). Block themes and WP 6.8+ sites that already load
block assets on demand are left alone. A `wedocs_request_can_render_blocks`
filter covers layouts the plugin cannot detect.

Verified on Hello Elementor and Twenty Twenty-Four: plain pages and posts
now load nothing from weDocs; single docs, the docs home page and a page
holding DocsGrid + QuickSearch load the same stylesheets as before and
render pixel-identical; the quick search modal works; the block editor
still has weDocsAdminScriptVars.

Part of weDevsOfficial/wedocs-pro#428

Claude-Session: https://claude.ai/code/session_019KGP9sp935QBeu32pGt5WY
…ocks

Breadcrumb, Sidebar, DocNavigation and QuickSearch are the only blocks
whose stylesheet carries Tailwind utilities. On develop each of them
built to 630 KB: Tailwind 4 scans the whole project for class names, so
every utility the admin app uses landed in every block stylesheet, and
each one also registered daisyUI, which added the complete component set
and its theme variables, unscoped (`.btn`, `.card`, `.menu`, `.badge`,
`.divider`, `:root { color-scheme }` applied site-wide on every
classic-theme site).

- `@source not` exclusions in the four stylesheets keep the scan to the
  block sources and the front-end templates. `source(none)` + `@source`
  would be the tidier form, but with it Tailwind 4 drops the `important`
  scope from the JS config and the utilities lose their
  `.wedocs-document` prefix, so the exclusion list is used instead.
- tailwind.blocks.config.js carries the same `important` scope and
  class-based dark mode as tailwind.config.js, with `content` limited to
  the block sources and front-end templates.
- daisyUI is no longer registered in these four files: no block markup,
  front-end or editor, uses a daisyUI component or theme colour (checked
  against every className in src/blocks and templates).

Result on develop: 631 KB -> 33 KB, 633 -> 35, 632 -> 34, 630 -> 32.
Every other build output is unchanged apart from the asset version
hashes. A class-set diff of old vs new against every class token in
src/blocks and templates shows nothing lost that any block markup uses.

Verified on Twenty Twenty-Four with a develop build: single doc (parent
and child), a DocsGrid + QuickSearch page, the docs home page and the
quick search modal with results render pixel-identical to the unscoped
build; the block editor still renders the blocks and has
weDocsAdminScriptVars.

The same fix, in its Tailwind 3 form, is on the 2.5.0-based
hotfix/2.5.0-on-demand-assets branch, which produced the drop-in zip
for the reporter.

Closes weDevsOfficial/wedocs-pro#429

Claude-Session: https://claude.ai/code/session_019KGP9sp935QBeu32pGt5WY
@arifulhoque7
arifulhoque7 force-pushed the fix/428-429-on-demand-block-assets branch from 9930995 to 7ef3cf4 Compare September 14, 2026 06:41
@arifulhoque7
arifulhoque7 merged commit 6abef97 into weDevsOfficial:develop Sep 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant