the code in drupal.js uses jQuery only to use the ready event triggering attachBehaviors. This issues introduce domReady (https://github.com/ded/domready) to provide a way of triggering behaviors without the need to load jQuery. It's straight away the minified version because it's the kind of code we never want to have to look at, like modernizr and html5shim.
- Drupal.getSelection() is removed, nothing uses it in core. And I haven't seen any contrib code using it either.
- Drupal.ajaxError is moved to ajax.js, it seemed fair :)
- Removed freezeHeight, it's code from 2006 because the image field widget made the page jumped around #69786-8: Pave the way for integration of jQuery into core. It's not the case anymore.
Also something seemingly unimportant but is: I got rid of the check for previous versions of the Drupal object (I'm talking about the first line of drupal.js here). There is no way the drupal object should be existing beforehand. Ajax loading you say? it's the whole point of our Way too big ajax requests, we never load a script twice. I'll open a follow-up issue to get rid of all of them.
What does this patch means when you script depend on the drupal library:
Before
your script + 90kb (jQuery) + 3.5kb (drupal.js) of minified, ungzipped JS on the page
After
your script + 740o (domready) + 3kb (drupal.js) of minified, ugzipped JS on the page
Original report
In a couple of files we have utilities that don't have a dependency other than the Drupal object (debounce, annouce soon, etc.) but they have to depend on the drupal library, which has a dependency of jQuery, ensuring nobody will look at it when using streamlined JS.
This patch put all of the API which isn't dependant on jQuery in the drupal.js file. And put all the initialisation (the call to attachbehavior, some wierd ajax-related stuff and messing around with the js class) in the drupal.init.js file.
Liraries have been updated to require the drupal.js and not the whole thing (since they only add a new member on the Drupal object).
Next step is if we want to remove the first line of drupal.init.js and make the global Drupal object not dependant of drupal.init.js
There are still a few things I'm not totally clear on but that's definitely a first step in the right direction. With this patch is you want to use a different loader, run behaviors before or after page load or whatever you only need to override the drupal.ini.js file, which is pretty small considering.
Comment | File | Size | Author |
---|---|---|---|
#41 | core-js-untangle-drupal.js-1974580-41.patch | 431 bytes | nod_ |
#36 | core-js-untangle-drupal.js-1974580-36.patch | 11.42 KB | nod_ |
#24 | core-js-untangle-drupal.js-1974580-24.patch | 11.17 KB | nod_ |
#19 | core-js-untangle-drupal.js-1974580-19.patch | 11.09 KB | nod_ |
#16 | core-js-untangle-drupal.js-1974580-16.patch | 10.24 KB | nod_ |
Comments
Comment #1
Wim LeersOverall, I like this step. However, I think this causes us to be in a fairly schizophrenic place :)
drupal.js
does not depend on jQuery anymore, but it depends ondrupal.init.js
, which depends onjQuery
. Which is the most schizophrenic part probably.drupal.js
does not depend on jQuery anymore, but forDrupal.attachBehaviors()
to be called, it needs jQuery. Is it not feasible to have something like thejQuery.ready
event without jQuery?drupal.init.js
does 4 things:Drupal.settings = drupalSettings
, which is temporary, and can easily live in drupal.jsDrupal.(un)freezeHeight()
, which is very dependent on jQuery, but is only a few LoC. Is it not feasible to rewrite this to not use jQuery? Then it can live indrupal.js
.drupal.js
. Furthermore, the "js" class on the "html" element is already being set by Modernizr! So should we even keep it? I guess we should, because sites should be allowed to not load Modernizr and still not break things.Overall, it seems that it might be easier to just make Drupal.js *not* depend on jQuery? Assuming it's possible to refactor items 2 and 4 in the above list to not use jQuery, of course.
Comment #2
nod_Basically everything in drupal.init.js is stuff I want to get rid of.
#1, #2 worst case, I'm planning on making a module or something that will get rid of drupal.init.js and it's jquery dep. If we can do it in core, all the better.
#3
1. I'd put all the cruft in drupal.init.js it's clear what needs to go away this way.
2. that's an ajax thing. It's not used anywhere else and I don't think contrib uses it. if it can't be in .init.js then it should be moved to ajax.js
3. that's tricky. We have CSS depending on this class and modernizr is not on every pages like you said. I'd say it's safer to keep.
4. that's tricky. Getting the ready event seems to be painful, just look at what jQuery does, it's pretty ugly i wouldn't want that.
Thanks for getting the discussion going :)
Comment #3
webchickDuring clean-up phase of the release is generally not the point to introduce things that need further clean-up. I'd rather do #1 & #2 in this issue, rather than commit us to a weird state that makes Drupal harder to grok for people.
Comment #4
Jelle_S4. If all you need is a "domready" function, we could just add a small library. Ded's domready.js looks like a decent one, and according to GitHub is only 0.74kb in the minified version. Yes it would mean adding another js "library" to core, and possibly having duplicate code (well sort of => $(document).ready()), but I think the benefit is large enough to at least consider it (0.74kb vs 92kb for jquery-1.9.1.min.js). This way we can have a decent cross-browser ready event, without having to figure it out ourselves...
Just my 2 cents.
Comment #5
Wim Leers#3: Indeed. This is a small patch anyway, so it wouldn't hurt to do it all in one patch.
#4: Thanks — that's very useful :)
Comment #6
nod_Ok, domReady looks good, here is a patch adding it. The minified version because we never want to have a look at it, like modernizr and html5shim. I don't need the drupal.init file anymore like that, good.
I deleted the Drupal.getSelection() function, nothing uses it in core. Doesn't looked used on d.o either even with the fancy textarea buttons (that are kinda broken on opera btw).
I moved Drupal.ajaxError to ajax.js, seemed fair :) also moved freezeHeight/unFreezeHeight in there like in previous patch.
Also something seemingly unimportant but is: I got rid of the check for previous versions of the Drupal object (I'm talking about the first line of drupal.js here). There is no way the drupal object should be existing beforehand. Ajax loading you say? it's the whole point of our Way too big ajax requests, we never load a script twice. I'll open a follow-up issue to get rid of all of them.
What does this patch means when you script depend on the drupal library:
Before
your script + 90kb (jQuery) + 3.5kb (drupal.js) of minified, ungzipped JS on the page
After
your script + 740o (domready) + 3kb (drupal.js) of minified, ugzipped JS on the page
Win.
Comment #7
nod_with the patch maybe
Comment #8
nod_and better title, bear with me it's still 13 in the morning here.
Comment #10
nod_Haha I'd just remove this test since that's really not what happens IRL. Anyway "fixed" it.
Comment #11
Wim LeersLooks very nice! Any tricky aspects I'm not aware of? :)
Comment #12
seutje CreditAttribution: seutje commentedAny particular reason we're not trying to prevent overriding any global Drupal object already present?
Also, it feels very much like "I have a dependency on domReady" actually means "I should probably run in the footer", but I guess that's not an assumption we should be making.
Ideally we'd need something like "domReady is defined as dependency, but another script requires jQuery, so dropping domReady in favor of jQuery", but then we'd need some sort of unified syntax, which would require custom code. But I guess contrib could very well handle that...
Comment #13
nod_We're not preventing overriding because it's actually never overridden, it's just useless precaution. We don't do that for Drupal.behaviors.XXX and it works just fine. It's the exact same thing.
If it is actually overriding somewhere, you're not using the Drupal API properly and then you're on your own. That's the point of ajaxPageState.
Yes I though about the domready/jQuery thing, but considering it's less than 1k and we removed Drupal.getSelection and Drupal.AjaxError from drupal.js it balances out. It would be really cool in other places though.
Comment #14
seutje CreditAttribution: seutje commentedfigured as much.
I don't have any other questions/objections, but would like to take this for a manual spin.
Should be able to do so later today.
Comment #15
seutje CreditAttribution: seutje commentedThis will error out when using drupal.js without jQuery, won't it?
Comment #16
nod_haha that was stupid, thanks for catching it :)
Comment #18
Wim Leerscore/misc/domready/ready.min.js
is missing from the patch, hence the test failure.Comment #19
nod_-_-"
Comment #20
seutje CreditAttribution: seutje commentedGoing once, going twice... Sold! No more AJAX stuff where it doesn't belong!
Comment #21
catchWhy are freezeHeight and unfreezeHeight moved to ajax.js?
Comment #22
nod_The ajax framework is the only thing using them. And I'm pretty sure it's not doing much, I didn't want to remove them and having to test it everywhere.
Comment #23
catchOK maybe a follow-up issue to try to remove them? They look generic-ish but if they're only used in one place and not doing anything useful it's worth trying to clean up.
Comment #24
nod_Ok checked where it comes from, it's code from 2006 because the image field widget made the page jumped around #69786-8: Pave the way for integration of jQuery into core. It's not the case anymore. I even got my IE8 fired up to test it, works fine.
Comment #25
nod_Comment #26
Wim LeersComment #27
alexpottSince we're adding a new javascript library (https://github.com/ded/domready) assigning to Dries to make the call.
In my opinion this fantastic improvement in overall page weight justifies adding the new library.
Comment #28
nod_updated the issue summary to reflect what's happening in the patch.
Comment #29
droplet CreditAttribution: droplet commentedIs it safe to use above domready script in Drupal ?
https://github.com/jquery/jquery/blob/master/src/core.js#L799
https://github.com/ded/domready/issues/14
I assumed you going to remove jQuery-like stuff, otherwise I see no point to replace it. Everywehre in Drupal using jQuery, doesn't it?
Also, any chance add unload support to drupal_add_library ??
half of sites loading jQuery. (http://trends.builtwith.com/javascript/jQuery)
(another half may load other scripts, eg. Dojo)
Is that means 50% Drupal site loading extra 1kb + 1 extra http request?
Comment #30
Dries CreditAttribution: Dries commentedI'm not sure I fully understood droplet's comment in #29 but it seems like it could be an important point. It sounds like droplet is suggesting that this may cause an extra HTTP request for many sites. If so, we should certainly discuss this more.
Comment #31
catchSites with js aggregation enabled (which should be every production site) won't get an extra HTTP request.
The 1kb of extra js I think is fine given it's going to result in a 90kb reduction for most pages without jQuery loaded - which is going to include a lot of real sites in the wild if we get the js refactoring in core right.
Comment #32
nod_Correct me if I'm wrong droplet but you're talking about replacing one library when another one is loaded ? For example replacing domready with a 1 line polyfill that uses jQuery to provide the domready functionality when the domready library is used and you have jQuery used also?
That's something we'd need in at least 3 more places so I'm hoping we can get that working at some point.
Comment #33
xjm#24: core-js-untangle-drupal.js-1974580-24.patch queued for re-testing.
Comment #34
Dries CreditAttribution: Dries commentedThanks for the explanations. I'm comfortable with this patch being committed so I'm un-assigning it from myself. The patch does not appear to apply anymore so I'm asking for a retest.
Comment #36
nod_reroll
Comment #37
readyventure CreditAttribution: readyventure commentedIndeed. This is a easy patch, so it wouldn't hurt to do it all in one patch.
Thanks I'm new to Drupal
Comment #38
nod_Ok I couldn't test the patch in #36 when I made it. Tested it now, works as expected.
Comment #39
alexpottCommitted 235142a and pushed to 8.x. Thanks!
Comment #40
alexpottJust realised that I accidentally committed this from "needs review"... but in my defence... #36 was a re-roll and it was rtbc'd in #26 and signed off by Dries... sorry everyone.
Comment #41
nod_Removing two leftover lines that are moved from drupal.js to ajax.js
Comment #42
droplet CreditAttribution: droplet commentedI'm not offense, but check #29.
http://bugs.jquery.com/ticket/12282#comment:15
https://github.com/ded/domready/issues
Comment #43
nod_moved the patch to #1993622: Follow-up on #1974580 remove two extra lines from drupal.js.
Comment #44
nod_@droplet the way we're using domready I don't think we'll run into much troubles.
I asked the maintainer of domready about using it in Drupal, told me it's fine https://twitter.com/ded/status/329619860743131138 . If there really are big and unsolavble issues we can still replace the whole domready file by
domready = jQuery(document).ready;
.I'll try spending some time with D8 on IE9 see if I can hit an edge case somehow.
Comment #45
nod_Here is the change notice: https://drupal.org/node/1994482
Comment #47
xjmUntagging. Please remove the "Needs change notification" tag when the change notice task is complete.
Comment #47.0
xjmupdate issue summary