Consider adding back the 'every page' concept to libraries

Created on 30 December 2024, 21 days ago

Problem/Motivation

See discussion in 📌 Create placeholders for more things Active 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 📌 Create placeholders for more things Active 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

📌 Task
Status

Active

Version

11.0 🔥

Component

asset library system

Created by

🇬🇧United Kingdom catch

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @catch
  • 🇩🇪Germany geek-merlin Freiburg, Germany

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

  • 🇬🇧United Kingdom catch

    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.

    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.

  • 🇨🇭Switzerland berdir Switzerland

    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...

  • 🇬🇧United Kingdom catch

    @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.

Production build 0.71.5 2024