Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exploration on how to refactor per-block styles #25118

Closed
wants to merge 46 commits into from

Conversation

aristath
Copy link
Member

@aristath aristath commented Sep 7, 2020

Description

This is an exploration on how we can make the styles loading more efficient for Gutenberg blocks.
With full-site-editing in the horizon, all styles will basically be block styles.
Currently WordPress prints a monolithic stylesheet containing all styles for all blocks - regardless of whether these are actually used in a page or not.
The goal of this PR is to identify issues and find solutions.

For the purposes of this exploration we add a new WP_Block_Styles class.

It implements 4 new ways to add block styles:

  • inline - Prints styles inline.
  • inline_link - Adds a <link rel="stylesheet"> inline.
  • inject - Injects the style in <head> via JS.
  • footer - Adds styles to the footer.

All 4 methods are hooked in render_block so styles for a block are only added when a block is actually used on a page. All of these block-styles additions only get triggered the 1st time a block-type is encountered.
Each method has its pros and cons, and serves a different purpose.
Each block can have multiple styles, and the way these are loaded can be independent.

Block-styles are filterable, so for example if we want to add a new style for the core/cover block which will add some styles in the footer, we can add something like this:

add_filter( 'block_styles', function( $block_styles ) {
    $block_styles['core/cover'][] = [
        'handle' => 'my-theme-cover-block-styles',
        'src'    => get_template_directory_uri() .  '/styles/blocks/cover.css',
        'ver'    => '1.0',
        'media'  => 'all',
        'method' => 'footer',
        'path'   => get_template_directory() . '/styles/blocks/cover.css',
    ];
    return $block_styles;
} );

The arguments in that array are similar to what we use in wp_enqueue_style(), with a few additions/tweaks. So we have:

  • handle (string): The handle. It's used to add an id to the element added.
  • src (string): The URL of our styles.
  • ver (string): The version of our styles.
  • media (string, optional): all|screen|print. Can also be a media-query. Defaults to all.
  • method (string): inline|inline_link|inject|footer.
  • path (string): This is only really needed if we want to print styles with the inline method.
  • There is no dependencies argument like wp_enqueue_style has, it doesn't make sense to have it in this implementation.

Plugins & themes can add/modify the array of styles available for each block-type, and how these get loaded. If a style is extremely small (like for example the paragraph styles), they can be added inline. Other styles (like the cover block) could be added in the footer or injected via JS since they are not critical in most cases, while the column styles will be better inline since they are small & adding them in the footer could cause a layout shift if they get loaded later.

Overall, this gives plugin authors, theme-authors and most of all site-owners the ability to control what gets loaded, when it gets loaded, and the overall performance boost for visitors is significant.

This implementation is hidden behind a split-block-styles theme-support.

How to test

To test the different modes of operation, you can try the following:

  • Checkout the try/styles-loading-refactor branch
  • Run npm run build
  • Add this code somewhere (for example in a PHP file inside wp-content/mu-plugins):
add_theme_support( 'split-block-styles', true );
add_filter( 'block_styles', function( $block_styles ) {
    foreach ( $block_styles as $block => $styles ) {
        foreach ( array_keys( $styles ) as $key ) {
            $block_styles[ $block ][ $key ]['method'] = 'footer';
        }
    }
    return $block_styles;
} );

You can test all the different loading methods by changing the value from footer to any of the available methods.

Notes

Editor Styles

  • Additional styles added with the filters are not currently enqueued in the editor, that is one of the next things to be implemented.

@github-actions
Copy link

github-actions bot commented Sep 7, 2020

Size Change: -1 B

Total Size: 1.22 MB

Filename Size Change
build/block-library/style.css 8.1 kB -1 B
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.77 kB 0 B
build/api-fetch/index.js 3.42 kB 0 B
build/autop/index.js 2.84 kB 0 B
build/blob/index.js 664 B 0 B
build/block-directory/index.js 8.71 kB 0 B
build/block-directory/style-rtl.css 943 B 0 B
build/block-directory/style.css 942 B 0 B
build/block-editor/index.js 133 kB 0 B
build/block-editor/style-rtl.css 11.3 kB 0 B
build/block-editor/style.css 11.3 kB 0 B
build/block-library/blocks/audio/style-rtl.css 152 B 0 B
build/block-library/blocks/audio/style.css 152 B 0 B
build/block-library/blocks/button/style-rtl.css 488 B 0 B
build/block-library/blocks/button/style.css 488 B 0 B
build/block-library/blocks/buttons/style-rtl.css 301 B 0 B
build/block-library/blocks/buttons/style.css 301 B 0 B
build/block-library/blocks/calendar/style-rtl.css 249 B 0 B
build/block-library/blocks/calendar/style.css 249 B 0 B
build/block-library/blocks/categories/style-rtl.css 132 B 0 B
build/block-library/blocks/categories/style.css 132 B 0 B
build/block-library/blocks/code/style-rtl.css 133 B 0 B
build/block-library/blocks/code/style.css 133 B 0 B
build/block-library/blocks/columns/style-rtl.css 467 B 0 B
build/block-library/blocks/columns/style.css 466 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.26 kB 0 B
build/block-library/blocks/cover/style.css 1.26 kB 0 B
build/block-library/blocks/embed/style-rtl.css 419 B 0 B
build/block-library/blocks/embed/style.css 419 B 0 B
build/block-library/blocks/file/style-rtl.css 288 B 0 B
build/block-library/blocks/file/style.css 289 B 0 B
build/block-library/blocks/gallery/style-rtl.css 1.11 kB 0 B
build/block-library/blocks/gallery/style.css 1.1 kB 0 B
build/block-library/blocks/group/style-rtl.css 117 B 0 B
build/block-library/blocks/group/style.css 117 B 0 B
build/block-library/blocks/heading/style-rtl.css 137 B 0 B
build/block-library/blocks/heading/style.css 137 B 0 B
build/block-library/blocks/image/style-rtl.css 508 B 0 B
build/block-library/blocks/image/style.css 507 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 315 B 0 B
build/block-library/blocks/latest-comments/style.css 315 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 568 B 0 B
build/block-library/blocks/latest-posts/style.css 567 B 0 B
build/block-library/blocks/list/style-rtl.css 127 B 0 B
build/block-library/blocks/list/style.css 127 B 0 B
build/block-library/blocks/media-text/style-rtl.css 572 B 0 B
build/block-library/blocks/media-text/style.css 570 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 747 B 0 B
build/block-library/blocks/navigation-link/style.css 745 B 0 B
build/block-library/blocks/navigation/style-rtl.css 222 B 0 B
build/block-library/blocks/navigation/style.css 222 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 279 B 0 B
build/block-library/blocks/paragraph/style.css 279 B 0 B
build/block-library/blocks/post-author/style-rtl.css 229 B 0 B
build/block-library/blocks/post-author/style.css 230 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 126 B 0 B
build/block-library/blocks/post-featured-image/style.css 126 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 359 B 0 B
build/block-library/blocks/pullquote/style.css 359 B 0 B
build/block-library/blocks/quote/style-rtl.css 215 B 0 B
build/block-library/blocks/quote/style.css 214 B 0 B
build/block-library/blocks/rss/style-rtl.css 314 B 0 B
build/block-library/blocks/rss/style.css 313 B 0 B
build/block-library/blocks/search/style-rtl.css 384 B 0 B
build/block-library/blocks/search/style.css 386 B 0 B
build/block-library/blocks/separator/style-rtl.css 281 B 0 B
build/block-library/blocks/separator/style.css 281 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 125 B 0 B
build/block-library/blocks/site-logo/style.css 125 B 0 B
build/block-library/blocks/social-links/style-rtl.css 1.36 kB 0 B
build/block-library/blocks/social-links/style.css 1.36 kB 0 B
build/block-library/blocks/spacer/style-rtl.css 107 B 0 B
build/block-library/blocks/spacer/style.css 107 B 0 B
build/block-library/blocks/subhead/style-rtl.css 134 B 0 B
build/block-library/blocks/subhead/style.css 134 B 0 B
build/block-library/blocks/table/style-rtl.css 433 B 0 B
build/block-library/blocks/table/style.css 433 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 209 B 0 B
build/block-library/blocks/text-columns/style.css 209 B 0 B
build/block-library/blocks/video/style-rtl.css 238 B 0 B
build/block-library/blocks/video/style.css 238 B 0 B
build/block-library/common-rtl.css 908 B 0 B
build/block-library/common.css 908 B 0 B
build/block-library/editor-rtl.css 8.91 kB 0 B
build/block-library/editor.css 8.92 kB 0 B
build/block-library/index.js 147 kB 0 B
build/block-library/style-rtl.css 8.1 kB 0 B
build/block-library/theme-rtl.css 792 B 0 B
build/block-library/theme.css 793 B 0 B
build/block-serialization-default-parser/index.js 1.87 kB 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/blocks/index.js 48 kB 0 B
build/components/index.js 171 kB 0 B
build/components/style-rtl.css 15.3 kB 0 B
build/components/style.css 15.3 kB 0 B
build/compose/index.js 9.9 kB 0 B
build/core-data/index.js 14.8 kB 0 B
build/data-controls/index.js 827 B 0 B
build/data/index.js 8.74 kB 0 B
build/date/index.js 11.2 kB 0 B
build/deprecated/index.js 768 B 0 B
build/dom-ready/index.js 571 B 0 B
build/dom/index.js 4.92 kB 0 B
build/edit-navigation/index.js 11.1 kB 0 B
build/edit-navigation/style-rtl.css 881 B 0 B
build/edit-navigation/style.css 885 B 0 B
build/edit-post/index.js 306 kB 0 B
build/edit-post/style-rtl.css 6.51 kB 0 B
build/edit-post/style.css 6.49 kB 0 B
build/edit-site/index.js 23.3 kB 0 B
build/edit-site/style-rtl.css 3.98 kB 0 B
build/edit-site/style.css 3.98 kB 0 B
build/edit-widgets/index.js 26.3 kB 0 B
build/edit-widgets/style-rtl.css 3.16 kB 0 B
build/edit-widgets/style.css 3.16 kB 0 B
build/editor/editor-styles-rtl.css 476 B 0 B
build/editor/editor-styles.css 478 B 0 B
build/editor/index.js 42.5 kB 0 B
build/editor/style-rtl.css 3.85 kB 0 B
build/editor/style.css 3.85 kB 0 B
build/element/index.js 4.62 kB 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/index.js 6.86 kB 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 2.16 kB 0 B
build/html-entities/index.js 623 B 0 B
build/i18n/index.js 3.57 kB 0 B
build/is-shallow-equal/index.js 698 B 0 B
build/keyboard-shortcuts/index.js 2.52 kB 0 B
build/keycodes/index.js 1.94 kB 0 B
build/list-reusable-blocks/index.js 3.1 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/media-utils/index.js 5.32 kB 0 B
build/notices/index.js 1.79 kB 0 B
build/nux/index.js 3.4 kB 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/plugins/index.js 2.56 kB 0 B
build/primitives/index.js 1.43 kB 0 B
build/priority-queue/index.js 790 B 0 B
build/redux-routine/index.js 2.84 kB 0 B
build/reusable-blocks/index.js 3.05 kB 0 B
build/rich-text/index.js 13.3 kB 0 B
build/server-side-render/index.js 2.77 kB 0 B
build/shortcode/index.js 1.69 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/url/index.js 4.05 kB 0 B
build/viewport/index.js 1.84 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

@aristath
Copy link
Member Author

aristath commented Sep 8, 2020

I'm thinking perhaps all blocks should have an editorStyle and style defined in their block.json files... 🤔

@aristath aristath added [Type] Performance Related to performance efforts [Feature] Themes Questions or issues with incorporating or styling blocks in a theme. labels Sep 11, 2020
@aristath
Copy link
Member Author

aristath commented Feb 2, 2021

Closing this one in favor of #28358

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Themes Questions or issues with incorporating or styling blocks in a theme. [Type] Performance Related to performance efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant