Problem/Motivation

See discussion in #3437499: Use placeholdering for more blocks for some background.

Also see the original issue that removed the last time we had something like this #977844: Remove the 'every_page' option for CSS/JS assets: it is confusing, even damaging which also discussed bringing it back in some sense. drupal_add_js() is fully gone now, you can only add a library.

Drupal often creates asset aggregates with a lot of overlapping (duplicate) files between them.

If we can identify libraries which are added on every page (and every page needs to be defined in this issue), and isolate those to their own aggregate, we should have less duplication.

There are three possible ways to do this:

1. Add an every_page: true to library definitions, this would probably only be usable by themes since otherwise libraries can't control when they're added.

2. Programmatically determine which libraries are likely to be loaded on every page via dependencies. For example we could load libraries that are dependend upon in separate aggregates.

e.g. if we take core's jQuery library and library B that only depends on jQuery, they would always be in separate aggregates, which would avoid jQuery being aggregated with and without library B. However when you have other libraries that are also depended-upon like AJAX, that would be aggregated with jQuery still.

3. Something more like #3437499: Use placeholdering for more blocks where we capture where a library is added from, and render it separately.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Comments

catch created an issue. See original summary.

geek-merlin’s picture

What about starting with Option one and doing the others in a follow up?

catch’s picture

Trouble with doing #1 first is that it's very easy for library definitions to get it wrong, this is why we removed it last time. It might be fine doing it again, but not sure how exactly yet.

Possible #4 would be to collect/group assets by region.

Let's say a theme has:

header
content
left sidebar
right sidebar
footer

If we collect libraries for each region and render/group the assets for them independently, then some of the regions will be more or less static (like a header) and some will potentially change assets a lot more (like content).

This gets complicated though because we only load libraries once, so given the controller has to get rendered first usually, if that includes various libraries that are dependencies of other libraries, but only sometimes, then we could still end up with a lot of duplication.

berdir’s picture

What if we start with adding this behavior specifically only to global libraries in themes and just separate those out and look at expanding it in follow-ups? that it can't be configured incorrectly. And instead of adding it to libraries, we could add it somewhow to #attached?

E.g. something like extlink module that implements hook_page_attachments() could then do:

$attachments['#attached']['global_library'][] = 'extlink/drupal.extlink';

Aware that this while feature kind of conflicts with the whole idea of SDC, a theme that fully embraces SDC might not have any global libraries at all, but I assume you always have some base CSS stuff that's shared that's always loaded. Don't know...

catch’s picture

@berdir so global libraries from themes are added in BareHtmlPageRenderer::systemPageAttachments().


// Attach libraries used by this theme.
$active_theme = \Drupal::theme()->getActiveTheme();
foreach ($active_theme->getLibraries() as $library) {
$page['#attached']['library'][] = $library;
}

We could make CssCollectionGrouper theme-aware, and then force assets into a new group when they're in one of those libraries.

#attached['global_libraries'] seems tricky to implement because normal libraries can depend on global libraries and vice versa so we'd still have to mush them together for ordering etc. in the asset logic.

Maybe we could separately add a list of global libraries (YAML file or wherever) with an alter hook specifically for customising the list, although probably it'd be weird to maintain that outside the library definitions.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.