Needs work
Project:
Speedy
Version:
7.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
5 May 2012 at 16:57 UTC
Updated:
17 Mar 2013 at 21:50 UTC
Jump to comment: Most recent file
Comments
Comment #1
johnalbinAnd the patch.
Comment #2
johnalbinJust read http://www.pixel-whip.com/blog/12/03/all-cool-kids-back-bus
Comment #3
johnalbinOk. Here's a much better patch that works with footer scope aggregation. And doesn't cause footer-scoped scripts to load before header-scoped scripts. That last patch was a complete hack now that I look at it again.
This uses hook_js_alter to change the scope of header scripts to be footer. It also adds a UI to whitelist the names of scripts that should remain in the header. The whitelist defaults to htlml5.js and modernizr_loader.js (the script used by the Modernizr module.)
Comment #4
mfer commentedYou are right to note that some scripts don't work properly in the footer. Sometimes this is a flash when the JS is applied after the pages load (e.g., chosen for select tags). You might not see it in local machine dev but once you are on a remote server the problem can pop up. I saw this become an issue recently.
I'm not sure saying "Some JavaScripts do not function properly in the footer" is good enough. Someone might move jquery to the footer with chosen. See a problem and write a support ticket here. I know I'm not going to be good about responding to that.
What else could we put in to help developers with this. Or site builders. I really want to avoid the support requests this has the potential to bring.
Comment #5
mfer commentedThe use of basename here isn't going to cut it. For example, drupal core has an ajax.js and so does the views module. Saying to put ajax.js in the footer will move multiple files there without control over which is moved individually. I'd imagine there are other cases of this.... I just found this example fairly quickly. Thoughts?
Comment #6
ruplI've implemented code very similar to pixelwhip's example that John linked to above. I use the full path instead of just the filename.
I think we could improve this whitelist by adding a hook that allows modules to tell Speedy which files should remain in the
<head>. Then the onus is not on the site admin to whitelist correctly. The textarea could stay to allow for manual exceptions, but by and large I think modules reporting their own exceptions will be easier and less error-prone.I have some code here but it's not quite right yet. Will circle back sometime today or tomorrow with functional patch.
As an aside, modernizr_loader.js probably needs to be dropped from the Modernizr module. The module defaults to directly loading Modernizr as of the 2.x release last year. But yeah, if Speedy lets modules report their own whitelist, this guessing game goes away! :)
Comment #7
mfer commented@rupl modules can put their own JS in the footer if they want. This is an override to tell it to happen differently from what the module defined.
Comment #8
ruplYup, I understand. What I'm suggesting is that since we're redefining a default, it seems like less work overall if the few modules which truly require JS in the
<head>just implement a whitelist entry to tell Speedy "hey, I really need my JS in the header, and I know what I'm doing."It seems simpler to allow for automated exceptions than to refactor poorly-written JS from other modules, or to file 300 issues in various modules to ask that their drupal_add_js() scope be declared as footer.
In IRC we discussed Chosen as an example of JS that might need to be in the
<head>due to a possible FOUC. @mfer brought up the need for jQuery to shift back up to the top if even one jQuery plugin is in the head. That is a valid use-case that I hadn't considered yet.In my head this validates the need for a method by which modules can opt out of this default that we're redefining. The whitelist entry could even include a flag that says it depends on jQuery. Here's an imaginary implementation of
hook_speedy_whitelist()that I just made up:Comment #9
mfer commentedIn addition to a white list I'd like a documentation page or blog post explaining the potential problems with the footer. Something to link people to so they can better self troubleshoot.
Comment #10
andypostSuppose a line on project page and readme.txt is enough
Comment #11
johnalbinRelated core issue #784626: Default all JS to the footer, allow asset libraries to force their JS to the header
Comment #12
ruplIn Munich we had some interesting discussion about this. I was going to propose using
JS_LIBRARY - 10as the group value and specifically avoiding those entries in the_js_alter().However, a more obvious solution popped up organically across multiple base themes without the maintainers even discussing. Peep both of them: Omega 4.x and Aurora 1.x (after loading the pages use your browser to search for "js_alter")
The functions differ slightly, but they both rely on the same setting within each
drupal_add_js()call:By following this pattern, we could provide an obvious, intuitive method for people to specify scripts which must live in the
<head>. What does everyone else think?Comment #13
socialnicheguru commentedplease be careful of this option. See http://drupal.org/node/1945222
issues include the following:
1. modules use hook_page_alter to include inline js in $page['page_bottom'] by various modules
2. hook_js_alter scope is not a region even though the api implies it. so scope footer does not equal theme footer. it is equivalent to to $closure in D6. $page['page_bottom'] is supposedly the equivalent but javascript variables are not added to $page['page_bottom']
3. there is no way to order js added by hook_js_alter relative to that added by hook_page_alter