Posted by nedjo on July 21, 2008 at 3:27pm
8 followers
Jump to:
| Project: | Drupal core |
| Version: | 7.x-dev |
| Component: | base system |
| Category: | task |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed (fixed) |
Issue Summary
hook_init() is used in several functions for loading CSS and/or JS files.
However, there are very few valid use cases for a module loading CSS or JS files on every page on which it is present. CSS and JS are usually needed only if certain content is present on a page--content that the module itself adds or modifies.
We should therefore be adding CSS and JS files not in hook_init() but as part of rendering--e.g., in theme preprocess functions.
Eliminating these hook_init() implementations will help with #259412: Total module system revamp.
Comments
#1
Agreed, but not that easy to do, apparently.
#2
Well, when it is simple, do a drupal_add_css() each time you know you need it. If not simple, then use hook_init().
#3
Isn't the idea that by loading on every page, they get aggregated on every page, so you don't serve different aggregated CSS files on different pages? Saves requests once it's cached etc.
Either way, hook_init docs recommend it: http://api.drupal.org/api/function/hook_init/7
Also cached blocks lose their css files, which at the moment means more hook_init usage: #214856: CSS and JS for Cached Blocks (drupal_add_css incompatible with blocks)
Core modules which add css in hook_init():
hook_init() only for css:
dblog (does arg() check before adding it too...)
aggregator
book
forum
node
poll
user
hook_init for other stuff, but also adding css:
system (also does arg() check for one drupal_add_css).
#4
The natural way to solve this would seem to be allowing module info files to define styles and scripts arrays the same as themes. Those would then get loaded for all pages (and cached), just as they do for themes.
#5
That makes a lot of sense. Would be consistent, and generally lovely.
#6
The difference to themes is that modules only need to load stylesheets for certain users, pages or roles. I know that modules in Drupal core are most often loading stylesheets unconditionally, but that's a bug on its own.
The proper solution is to move JS/CSS loading into theme functions, form builders or page callbacks. To do this, we have to overcome the caching issue. However, that could be solved by caching any added JS/CSS structures for cached contents. That approach is doable; it is already working in a custom Panels Cache module that (basically) performs a diff of added JS/CSS before and after rendering an panel. When the cached version is served, the additional JS/CSS is added.
#7
@sun, I disagree. Most module CSS files are quite small. Loading them all at once on the first page load, compressed, means that they never need to be accessed again. If they're loaded conditionally, then you get a different compressed file for each combination of module CSS and need to resend the entire compressed file every time. That's worse for performance.
Besides, if we get #340723: make modules only require .info files in, then we can have modules that are just JS and CSS files. That makes providing, say, a jquery plugin really really easy, with virtually no server-side performance hit.
#8
You don't want to load tons of CSS and JS for anonymous and/or regular users that is not even used for them.
If you want all your users of your site to get the same CSS/JS, then go ahead and use hook_css_alter() and hook_js_alter() to load and aggregate all possible files for everyone into one bloated thing.
Compression and aggregation is fine, as long as you don't add needless overhead for every user and visitor. For the very same reason, http://drupal.org/project/jquery_ui does not unconditionally load 300 kB of (already minified) JavaScript on all pages for all users.
Some ideas:
- Separate CSS/JS for users and admins
- Put structured CSS/JS information into the $page array, so we can process it also for cached page bits
#9
As css/js no longer should be added in hook_init() I guess this one is fixed.
Some Leftovers are handled in #630100: Check non-preprocessed CSS/JS is loaded only when really needed.
#10
Automatically closed -- issue fixed for 2 weeks with no activity.