If you use drupal_add_js('window.google_analytics_uacct = ' . drupal_json_encode($id) . ';', array('type' => 'inline', 'group' => JS_LIBRARY, 'weight' => -21)); to order an inline JS code above the jquery lib it is not added above the jquery.js - no it's added below. This is incorrect.
If you use drupal_add_js('window.google_analytics_uacct = ' . drupal_json_encode($id) . ';', array('type' => 'inline', 'weight' => JS_LIBRARY - 21)); it works, but this have also worked in past and is not the way how drupal_add_js() should be used in D7.
For an example see #975504: drupal_add_js() API change that have a patch that can be applied to GA to repro the bug, please.
Comments
Comment #1
hass commentedHere is an example how the HTML code should looks like:
And here how it looks like with the bug if 'group' is used in the API:
You can see the weight is clearly wrong.
Comment #3
effulgentsia commentedSee #769226-212: Optimize JS/CSS aggregation for front-end performance and DX. I'll respond on #975504: drupal_add_js() API change as well.
Comment #4
hass commentedOptimization have nothing to do with this bug here.
Comment #5
effulgentsia commentedOptimization has everything to do with this bug here :)
drupal_sort_css_js() sorts the js items by 'group', then by 'every_page', then by 'weight'. This allows aggregate files to be more effectively re-used across a site visit. But, it means you can't place a JS item above one whose 'every_page' is TRUE without either setting 'every_page' of your item to TRUE, or else putting your item in an earlier group, as per #975504-4: drupal_add_js() API change.
I admit this is a WTF in some situations. Though I also think
array('type' => 'inline', 'group' => JS_LIBRARY-1)makes sense for what you're trying to do, since what you're trying to do is say "place this javascript code above all JS_LIBRARY files".Comment #6
hass commentedThis sentences are much easier to understand how the logic works than the API docs of drupal_add_js()...
Comment #7
hass commented@effulgentsia: I checked how jquery.js is added to the page and I do not see a 'every_page' => TRUE. Maybe the bug is that a JS file order from a hook_library() cannot over-weighted? As you can see above I'm only using a lower weight than misc/jquery.js what should cause the script tag to move above jquery.js, but it does not.
So I'm NOT trying to place JS above a JS file that have 'every_page' set to TRUE. The title seems now missleading and wrong as this seems to be no documenatation or WTF issue to me.
Comment #8
effulgentsia commentedWell, I guess you can add one more WTF to the mix. You can pass $every_page as a parameter to drupal_add_library(). And that is done for 'jquery' within drupal_add_js(). Which is understandable: in some cases, the caller of drupal_add_library() needs to decide if the library is being added to every page or not.
The documentation about all of this needs a lot of love. Some of it is just plain wrong. I'll try to help on that when I have a chance.
Comment #9
hass commentedHell... now I found this every page TRUE for jquery. every page is not really correct for Google Analytics - so I need to go with group -1 for now... thank your very much for the many hints!
Comment #10
effulgentsia commentedComment #11
ohnobinki commented+
It would be nice to understand more clearly what effect every_page has on Drupal. I.e., does drupal assume that if it has already cached all `every_page' JS files it doesn't need to confirm that the cache is correct? That is, would I need to call drupal_clear_js_cache() after changing a setting in my module which changes my drupal_add_js() calls in hook_init()? I think that the answer to my question is `no' and that doesn't make all that much sense to me :-p.
Comment #12
nod_Comment #13
robloachThere is absolutely no guarentee any given CSS/JS file should be presented on every page request. Especially now that jQuery is not required to be displayed on every page, the JavaScript/CSS aggregation sorting system completely breaks. What would happen if we simply removed the flag? With the likely move to an AMD architecture, this seems less relevant.
Comment #14
sunComment #15
wim leersIndeed, the
every_pageheuristic is pretty broken… by design. It depends on the site which assets are loaded on every page. Hence declaring an asset is (probably) going to be loaded on every page is at best an educated guess; but it's definitely site-specific.However, on to the good news: every single asset in Drupal 8 is now loaded through asset libraries. That also means we know about all dependencies. Which means we can build a dependency tree, and thus we can calculate the
every_pageheuristic automatically!Therefore I think we should remove the
every_pageheuristic from Drupal 8, remove it from the docs, and either implement the above dependency tree heuristic before release (if we think it's that important), or add it in 8.1, where it won't be breaking any APIs.In any case, in the current implementation, it is:
Comment #16
wim leersComment #17
catchYeah I've never seen this used correctly, in either direction, so just dropping it seems good. And we won't really be breaking any APIs either dropping it or figuring out the same information via dependencies.
Comment #18
catchDo we think we can remove this after 8.0.0? This implication would be that setting it is a no-op, which might be fine if it gets handled better anyway.
Adding 'beta target' though in case that's not true.
Comment #19
wim leersYes, see #15 for a proposed plan.
Keeping the tag until you remove it again, i.e. if you're convinced that that is a plausible plan.
Comment #20
catchThe plan in #15 looked to be removing it before 8.0.0 then adding it back at a later date. I meant if we don't do anything before 8.0.0, could we still ditch it even then. IMO the answer is 'yes' but good to validate that.
Comment #21
wim leersOh, hm, good point. Rather than analyzing whether it's possible, I think it's easier to just do it.
Here's a patch to remove
every_pagein this issue, before 8.0.0.Comment #22
catchDouble checked this removes every reference. RTBC for me once green.
Comment #23
wim leersHeh, okay. Filed a feature request for 8.1 to do what I described in #15: #2554051: Use the asset library dependency tree to improve CssCollectionGrouper & JsCollectionGrouper.
Comment #24
wim leersMore accurate title.
Comment #25
nod_Wim said it in #15, now that we have libraries this is obsolete.
Comment #26
nod_Comment #28
catchCommitted/pushed to 8.0.x, thanks!
We can add the optimization back in #2554051: Use the asset library dependency tree to improve CssCollectionGrouper & JsCollectionGrouper properly.
Comment #29
davidhernandezNice. I didn't know there was an open issue to get rid of every_page. I found it confusing when I first encountered, knowing the flexibility we have with libraries. I'm glad this simplifies things.