Problem/Motivation
Libraries allow custom weights to be specified for each individual file, this has been shown to be fragile/brittle in issues such as #3222107: Library order asset weights do not work properly when a large number of javascript files is loaded between two jQuery UI libraries and #3397713: [Performance regression] Starting with Drupal 10.1, some sites hit PHP for every page view due to aggregated asset URL hash mismatch from different order of asset items - it means that the ordering of assets can be very unpredictable (when different assets have the same weight, when different libraries are loaded on different pages etc.) and we already have a dependency system between libraries that covers the use-case. It also blocks further aggregation improvements like #3232810: [PP-1] Allow setting aggregation groups for js files in library definitions.
Steps to reproduce
Proposed resolution
Remove weights from all core library definitions and rely exclusively on dependency declarations to determine ordering between libraries.
Where files within a library definition depend on each other, they can be declared in the order they should be loaded on the page.
This doesn't remove support for weights from the libraries API, that is deferred until #3467488: Deprecate support for per-file weight in libraries API because we have additional decisions to make for CSS.
Remaining tasks
Un-postpone #3232810: [PP-1] Allow setting aggregation groups for js files in library definitions, #1924522: Remove separate CSS_AGGREGATE_THEME aggregate file, #3467488: Deprecate support for per-file weight in libraries API and related issues.
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #139 | 1945262-nr-bot.txt | 90 bytes | needs-review-queue-bot |
| #137 | 1945262-nr-bot.txt | 90 bytes | needs-review-queue-bot |
| #135 | 1945262-nr-bot.txt | 90 bytes | needs-review-queue-bot |
| #133 | 1945262-nr-bot.txt | 90 bytes | needs-review-queue-bot |
| #118 | 1945262-nr-bot.txt | 7.21 KB | needs-review-queue-bot |
Issue fork drupal-1945262
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
nod_forgot tags
Comment #2
robloachYup.... Dependencies should determine asset order, not "weight".
Comment #3
wim leersThis broke at least two tricky edge cases:
drupalOverlayOpenevent is triggered andDrupal.behaviors.contextualToolbar.attach()must already have been executed. The removal of the weights broke that. Note that we may not introduce a dependency here because contextual.toolbar.js does not depend on overlay-parent.js, but instead it listens to it in case it exists.I think the only way to solve this is by setting up the listener outside of the Drupal behaviors, so that it runs earlier. I hope I'm wrong :)
Comment #4
nod_Reroll.
Looks like contextual links work. Tour is still broken.
Comment #5
wim leersI had no idea what this issue was about — it's witty, but this is hopefully a bit more clear :)
Comment #6
nod_You're right, wasn't clean. Little small adjustment to make it easier on the eyes.
Comment #7
wim leersThis is blocked on a mechanism that uses a DAG (Directed Acyclic Graph) to determine the order of the assets. We can then work around the problem in #3 by having the ability to mark a library to be loaded before another one, and having the DAG take that into account.
(As per a call with sdboyer and a discussion with nod_.)
Related: #1014086-114: Stampedes and cold cache performance issues with css/js aggregation.
Comment #8
sunLet's revisit this — I think we were able to remove some of the weights in the libraries.yml patch already, but there are certainly lots of remaining instances.
Comment #9
yesct commentedchanging to use the more common tag, so the less common one can be deleted, so it does not show up in the auto complete and confuse people.
Comment #10
wim leersIs #1805552: Remove custom weights from library definitions a duplicate of this?
Comment #11
nod_Reroll, There are two cases of conditional dependencies. I think the only problem could be with views-contextual but doesn't seems broken.
Anyway, last patch was before yml files so here it is.
Comment #12
robloachTested, clicked around Views. Works well.
Comment #13
webchickOh, nice! Less code, same functionality.
Committed and pushed to 8.0.x. Thanks!
Comment #15
catchCould someone cross-link the issue that actually removes weight support for js? I can't find it atm.
Comment #16
wim leersPlease revert this commit; it broke at least
/admin/config/development/testing. Hence, this wasn't sufficiently manually tested. Is it possible that #12 only tested the JS in the Views module?Comment #18
webchickSorry about that! Sometimes my enthusiasm for a small RTBC queue gets the better of me. :) Reverted.
Comment #19
swentel commentedyes, you can't filter and all checkboxes are gone ...
Comment #20
penyaskitoRemoved simpletest_js_alter(). Simpletest form works again.
Comment #21
penyaskitoAttachedAssetsTest::testAlter()has a@seeforsimpletest_js_alter(). We should do something about it if we remove it.Comment #22
penyaskitobtw, after this change the only
hook_alter_js()implementation in core is locale :_)Comment #24
penyaskitosimpletest depends on drupal.tableselect, so I guess we should just remove the test.
Comment #25
penyaskitoDone that.
Comment #26
robloachRather than removing the test, it might be better to add a mock that tests the hook_js_alter() functionality. It's in core, and it should be tested.
Comment #27
penyaskitoNeeds work then.
Comment #28
robloachSomething like this? https://github.com/RobLoach/drupal/pull/4
Interdiff
Comment #29
robloachWrong file, sorry. Here's the correct patch.
Comment #32
penyaskito@RobLoach: Thanks for the test! I changed it so the module is only enabled for testAlter. I could have added a check for jquery in the test module, but this looks cleaner to me.
Comment #33
amol_tatkare commentedI have tested the issue on views and test module. Patch #32 is working fine.
Please find attached screen shot.
Comment #34
amol_tatkare commentedAdding Issue tag as #DCM2015. This patch was tested in Code Sprint.
Comment #35
penyaskitoComment #36
robloachElegant solution :-) . What other places should we manually test before this goes RTBC?
Comment #37
penyaskitoThere isn't any other hook_js_alter() but locale, and that one already fails in HEAD and is being worked on #2419897: Javascript translations are loaded in the wrong order due to missing dependencies.
So I guess we are good.
Aside of that, I don't know the *official* procedure for manually testing JS patches. IMHO there is no problem with RTBCing this one.
Comment #38
wim leersThis patch makes several comment lies. We either need to remove those comments by verifying that the ordering requirements that used to exist no longer apply, or we can't remove all weights just yet…
This comment is now a lie. And I'm afraid this means we'll have to keep this one for now.
Why can this simply be removed?
This comment says
simpletest.jsmust run *before*tableselect.js. But the library definition says the opposite:Which is it?
This comment is now also a lie.
Comment #39
penyaskitoThanks for the review @Wim!
I'm not sure how to proceed.
1. and 3.) I tested diverse cases of contextual links with different contextual items (nodes, blocks, views) + inline editing using the standard profile and found no errors. It worked as expected and they were included in the same order than previously. Maybe is just *luck*.
2) simpletest.js is included after tableselect.js, but it works as expected (which makes me ask: is *included* order the same than *executed* order? I guess yes and the order is not relevant anymore, but clarification would help).
How can we verify that the order is not relevant anymore? Git log and check the changes on the files?
In the meantime, while testing 2) I found a different problem. We have e.g testing groups Action and action, and clicking on the checkboxes has the desired behavior. But if we click on the labels, always the same group is checked/unchecked. The problem relies on having the same lowercased element id in both checkboxes. If we think about keeping the casing is works for my browser (Google Chrome), but we should not rely on that as per http://www.w3.org/TR/html401/struct/links.html#h-12.2.1 it is invalid to have the same id even with different casing.
I will create an issue for that tomorrow, too late here...
Comment #40
wim leers#39: manually tested both of these.
contextual.toolbar.jsmust run aftercontextual.js. But it does NOT depend oncontextual.js: ifcontextual.jshasn't run, then it short-circuits itself: if there are no contextual links on the page, thencontextual.jswon't have been loaded, and there is no need to show the corresponding toolbar tab (the pencil icon) in the toolbar.This need is discussed several times in #1762204: Introduce Assetic compatibility layer for core's internal handling of assets but apparently it doesn't have its own dedicated issue.
Due to lack of strong guarantees, I'm suggesting to keep this weight declaration in place for now. Until we have the ability to declare "before" and "after" relationships.
Exactly.
Also: oops, I was clearly confused. SimpleTest's JS depends on
tableselect.jsis equivalent with setting thetablselect.jsweight lower! My bad. So this change is actually fine already :) (Thathook_js_alter()implementation should have been removed when it was converted into a library, but that was clearly forgotten.)contextual.js.This case is similar to the one in point 1, but instead of needing an "after" relationship, this one needs a "before" relationship.
Therefore, I propose to remove the changes I quoted in #38.1 and #38.3. The rest we can keep. That brings down the total number of "weight" usages to *two*. That'll make actually removing it easier, and a follow-up issue to add support for "before" and after" simpler too.
Pinging catch for his thoughts on adding "before" and "after" besides only "dependencies" to asset library declarations.
Comment #41
nod_We can't do that, otherwise we end up with contextual.js before jquery, drupaljs and the rest and things crash. Need to remove all weights or none.
Wen we remove all the things, we can implement behavior order execution by extending #2367655: Control the list of behaviors run by Drupal.attachBehaviors and having something declared in the Drupal.behaviors objects.
Comment #42
nod_Comment #44
nod_I apologize about the whole "diet" part of the initial title and patch name, it was a poor attempt at wit. https://the-pastry-box-project.net/marc-drummond/2015-december-21
Comment #46
robloachControl lists being broken by Drupal.attachBehaviors is somewhat related to this, but doesn't have to block this from moving forwards. I'm going to re-open this, as as still have explicit weight definitions in our libraries.
Comment #47
wim leersComment #51
wim leersWithout #39 being addressed, this is impossible. We'll need not only
dependencies, but alsobeforeandafter.#2781577-17: Properly style outside-in off canvas tray lists yet another case where this is necessary; the only alternative right now is to implement hooks to alter weights. That example cannot specify
dependencies: ['classy/dialog'], because then it'd depend on a particular theme to be loaded, which is not at all true. What it needs, isafter: ['classy/dialog'].Comment #56
wim leersBecause this didn't happen, we now have #2905036: Lower weight of classList library to optimize aggregation :(
Let's get this going again!? :)
Comment #58
markhalliwellNote: this could and probably should be a separate issue, but I'd thought I'd raise my thoughts here for now.
Personally, I think the main problem is that we're not really using any of the
JS_*groups anymore. Instead, we've been abusing it and placing everything inJS_LIBRARYby default (which, ironically, is notJS_DEFAULT).From LibraryDiscoveryParser::buildByExtension():
This constant was chosen because of the "everything is now a library" movement that swept through core. While true, I think it's important to note that there should be a very clear distinction between what a "Drupal library" is and what a "Standalone JS library is" (outside of the Drupal-sphere).
This should have defaulted to
JS_DEFAULT, notJS_LIBRARY.True "libraries" (independent libraries that don't require other dependencies, like classList, domready, jQuery, underscore, etc.) are being grouped with the rest just because they're considered a "Drupal library" (which is a different concept).
Only these true libraries are the ones that should be in the
JS_LIBRARYgroup IMO. This change alone would likely allow core to get away from arbitrary weights for these JS libraries.We could even default to
JS_LIBRARYat this point if the Drupal library doesn't specify anydependencies.I'm sure all of this was done in an effort to reduce the number of aggregated bundles, but from what I've seen, even with this setup, we're still at a minimum of around 2-4 JS bundles depending on the site. Changing this to the above won't really affect this, but it would give clarity as to what is a "true library" and what isn't.
---
This all being said, I do think this issue is also important. Sometimes, one needs to be explicit as to "when" a library should be included. Having a mechanism that checks for a "before" and/or "after" dependency would be nice. Arbitrary "weights" are confusing and meaningless.
Comment #59
berdir> we're still at a minimum of around 2-4 JS bundles depending on the site
I opened #2905036: Lower weight of classList library to optimize aggregation a while ago, which is a trivial change to save 1 additional aggregated JS file. That got pushed back due to a missing/unclear comment, I don't know how to really improve it to make it clearer, help welcome. This would IMHO be a nice performance improvement for everyone.
Comment #67
wim leersAnybody interested in taking this on? I can promise reviews 🤓
Comment #68
catchComment #70
wim leersThings are moving in core on this front! #2258313: Add license information to aggregated assets just landed and #3302755: On-the-fly JavaScript minification is now unblocked.
I'm hoping we can start pushing this forward too soonish, because it'll unblock #3232810: [PP-1] Allow setting aggregation groups for js files in library definitions, which is blocking #3224261: [PP-1] Front-end performance: concatenate CKEditor 5 JS assets for every unique configuration.
Comment #71
nod_Just looking at what fails if we remove the weights.
Added some before keys, they don't do anything yet.
Comment #72
nod_Comment #73
nod_with failing tests
Comment #74
nod_I guess the only way to go about this would be to leave the weights as-is because that might cause mayhem in contrib to remove them. even in core dependencies are not set properly and it's "hidden" by the weights.
anyway, trying to bring down failures as low as possible before putting the weights back.
For the before/after processing I was thinking of doing that in LibraryDependencyResolver but I don't want to add new dependencies if they don't already exist in the list of dependencies.
Comment #75
nod_bunch of failures left, probably missing dependency declaration.
For the before/after implementation i'm not sure at which level it makes the most sense to implement and I'm worried about circular "dependencies". At the very least I think that before/after should be a library-level key, not a file-specific key.
Comment #76
wim leersThis was exactly my fear 😬
I don't yet see how we can introduce this without breaking BC 😬 Maybe … just … maybe … this could work:
weights, but addbefore+afterweightsweights of non-core asset libraries with theweights of all assets in the tree of assets in that asset library'sdependencies, and deducebeforeandafterbased on this⇒ this should in theory allow the asset library system to not rely on
weightanymore, while still retaining BCThoughts? 🤓
Absolutely!
P.S.: nice, shockingly few failures when using just Drupal core! 🥳 Looks like it should be doable to get it down to zero?
P.P.S.: would be cool if eventually we'd test this patch against contrib modules that use
weights and have functional/functional JS test coverage as a way to validate the approach? 🤓Comment #77
nod_That should make all test pass beside the 2 new explicitly failing tests.
I like the plan, theorically it should be possible to do it like that.
Comment #79
catch#76 sounds like how we ought to do it. My only question is with #2 I would assume we'd want to blanket trigger deprecations when we find weight and remove any declarations from core in the first place.
Comment #80
wim leers#3303067: Compress aggregate URL query strings was committed last week — yay! Let's get this moving now? 🤓
Comment #81
taran2lComment #82
taran2lComment #84
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #86
taran2lhi @nod_, seems like rebase kinda "kills" notifications, sorry I've missed your comment. Added an explanation
MR removes all the weights throughout core, but before/after logic is still missing. However, as you can see all tests are passing, except the new one (before/after), and one that expected a specific weights (which are not there by the nature of the change)
Comment #87
nod_explanation is good, needs to be in comment inside the file
Comment #88
taran2laccomplished so far:
Comment #89
taran2lAfaik, everything works as expected, but probably some manual testing is required
The one test that is failing checks whether jQueryUi assets have a specific weights, which is not true anymore. Thus, we need a decision what to do with it: remove or refactor to test whether everything is working properly rather than just checking weights.
A few places where weights are still in use:
1.
ckeditor5_js_alter()- https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/modules/cke...Not sure what exactly Drupal tries to achieve here, someone else needs to take a look
2.
AttachedAssetsTest::testAlter()- https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/tests/Drupa...Tests altering weight via a hook, but this should not be a case anymore. Remove?
3.
settings_tray.theme.css- https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/modules/set...There is a mention of this issue, but a lot of things have changed since it has been added (not sure it is relevant anymore)
Next steps (imo)
1. Refactor existing library discovery to use different key for specifying an asset level (?) (btw, what should be the naming here?) - (can be a follow-up issue)
2. Deprecate usage of weight key with a deprecation message (can be a follow-up issue)
Comment #90
nod_Excellent, had a quick look and I like what I see :)
One question is how does it work when a library that has a before/after is added but the library it should be loaded before/after is not added to the page at the same time?
Comment #91
wim leersYay, #3222107: Library order asset weights do not work properly when a large number of javascript files is loaded between two jQuery UI libraries landed, which means we'll be able to make this change with more confidence! 😊
Comment #92
larowlanIs there an option to just use native es6 imports and type=module and just let the browser sort this out now we don't have to support IE
Comment #93
taran2lSo, in short, it collects all needed libraries first (pass one), and only after that (with the full list) it adds before/after logic (pass two)
Comment #94
taran2lSetting this to NR, as some guidance needs for the next steps, see #89
Comment #95
smustgrave commentedMoving to NW for the issue summary update
And failure in MR seems to be legit to the issue at hand.
Comment #97
acbramley commentedWas hoping this would fix an issue I'm having with Paragraphs Library and Entity embed. For some reason in the final Entity embed modal while adding a paragraph library item, jquery ui's dialog button styling is overriding Claro's leading to some pretty ugly buttons:
This does not happen when embedding an entity in a paragraph on a node form, only via Paragraphs Library (i.e /admin/content/paragraphs/add/default)
Unfortunately the MR doesn't solve this particular issue.
EDIT: Further debugging - it seems like
/core/themes/claro/css/components/jquery.ui/theme.cssis being added multiple times to the page. Once when the page loads, once when I add a paragraph, and then again when I open the embed modal so that would explain why styles are getting overwritten.Comment #98
taran2l@acbramley, well, this is good to be honest, as this issue is pure DX change, i.e. it should not fix anything (yeah, maybe, accidentally)
Comment #99
acbramley commented@Taran2L no worries - this was a red herring anyway. My issue - #3378341: claro.jquery.ui css assets may be added the page multiple times
Comment #103
catchAttempted a rebase here. We re-organised
internal.jquery_uiin core.libraries.yml since this was last worked on, and it wasn't that easy to reconcile. That plus some test changes were the main conflicts though, and fortunately the test failures are loud when you get things wrong so weren't too bad to correct.I've pushed the rebase to a new branch/MR https://git.drupalcode.org/project/drupal/-/merge_requests/9158 since the old one was named '10.1.x' and so it was easier to compare the state from a year ago to the rebase.
Also hid two MRs here which appeared to be dead ends.
Pipeline is green now, so ready for review again.
Comment #105
smustgrave commentedWonder if the issue summary could be updated?
Wonder if this change will need a CR? Won't tag but just asking
Comment #106
catchComment #107
catchUpdated the issue summary and added a CR.
After commit, https://www.drupal.org/docs/develop/creating-modules/adding-assets-css-j... will need an update.
This seems pretty solid as far as JavaScript goes, but CSS is a bit trickier because we mix the CSS_AGGREGATE_GROUP constants with weight in LibraryDiscoveryParser. I'm not sure what's best to do about that yet.
Comment #108
smustgrave commentedSo no way to deprecate 'weight' key?
Comment #109
taran2lI would deprecate weight as a follow-up, as it's quite a piece of an extra work
Comment #110
smustgrave commentedCould that follow up be created?
Comment #111
catchI also am leaning towards deprecating weight in a follow-up, but would like more feedback/reviews here before opening it, in case we discover we need to do it here after all.
Comment #112
swentel commentedoops - wrong issue!
Comment #113
catchThis will probably need a rebase now that #3467860: Ensure consistent ordering when calculating library asset order landed. That issue fixed some bugs in the current ordering logic, so we should be in a good position to validate this one now.
Still need to figure out what to do with CSS groups per #107. It may be that we can defer that to the follow-up that attempts to deprecate weight altogether.
Comment #114
taran2l@catch, updated branch with the latest changes from the upstream (actually a different issues was causing merge conflict), should be good to go now
Comment #115
podarokLooks good, thank you
Comment #116
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #117
smustgrave commentedFalse positive
Comment #118
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #120
luenemannFixed missing return type in new tests.
Comment #121
smustgrave commentedRe-solved the threads but appears to need a manual rebase (200 commits back), surprised the bot never picked it up.
Comment #122
taran2lthe conversion to OOP hooks broke this MR, corresponding code should be moved to the class files, I can take a look later this week
Comment #123
wim leersThis keeps causing problems, now also in Experience Builder, with a crazy work-arounds just having landed that would not have been necessary if this had been fixed.
Comment #124
taran2lComment #125
smustgrave commentedComment #126
smustgrave commentedSo I tried testing this with the Tour module now in contrib. And it broke things out right, saying it couldn't find jquery even though I had it as a dependency. Tour may have a bug or it's dependencies off but this change could break existing things with no guidance where to go.
Comment #127
catch@smustgrave this is probably due to
weight: -1in tour module: https://git.drupalcode.org/project/tour/-/blob/2.0.x/tour.libraries.yml?...Could you try the MR without the weight?
If tour needs to appear before something else, it might need to replace the weight declaration with the API added here.
Comment #128
smustgrave commentedYup tried without the weight -1 and even tried
after:
- core/jquery
Comment #129
rbrandon commentedSimilar to XB we have had to backport this to workaround some dependency issues and it is working well. We have several libraries that all depend on shared libraries. We were running into cases where the libraries were included in different aggregates and the dependencies were included in the minimal representative subset for both and ending up on the page twice.
Since the optimized aggregate urls don't track explicitly what other dependencies have been loaded like with ajax it would have required a lot of tinkering with weights and making duplicate libraries like with XB to get what the dependency sorting gives us out of the box.
Comment #130
bwaindwain commentedThis fixes https://www.drupal.org/project/drupal/issues/3506870
Comment #131
liam morlandDoes this change make it so that I can declare before/after relative to a library that is not on the page? In other words, if that library is on the page, load this library before/after it, but do not add that library to the page if it would not already be there.
Comment #132
catch@liam morland yes that's exactly the idea.
Comment #133
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #134
liam morlandRebased
Comment #135
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #136
liam morlandRerolled
Comment #137
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #138
liam morlandRerolled
Comment #139
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #140
larowlan