Moving JS to the Bottom of the Page

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
greggles's picture

I've been using yslow to review a few sites and always leave one last step out: move javascript to the bottom of the page

So, on a test site I just moved my

<?php
print $scripts
?>
to the bottom of the page.tpl.php right before the print $closure.

Of the two benefits (progressive rendering and better download parallelization) the progressive rendering makes a big differences for certain pages. For example, the admin/build/menu page problem is reduced - users see the page content and then the interface freezes while the JS loads/modifies the page. This makes it seem like "oh, js is working" as opposed to "woah, white screen of death!"

They mention that not all scripts can support this, such as document.write. AFAIK we don't use that much (at all?) so I feel like this is a good improvement. Has anyone else done this? Any advice you can share? Any reason not to do this for all themes in Drupal7?

EDIT: adding in the Javascript group so they can share their knowledge

Comments

Tested a little

agentrickard's picture

I tested it just a little, and it seemed to work. Don't know enough about JS to really debug. It would be trivial (code-wise) to make drupal_add_js() default to 'footer' instead of 'header'.

--
http://ken.therickards.com/
http://savannahnow.com/user/2
http://blufftontoday.com/user/3

Loading ads last

eli's picture

We've got ads on our site that are managed through a third-party ad server that sometimes runs a little slow.

I haven't tried moving all the javascript to the bottom, but something I did that made a big difference was leaving only placeholder divs for where the ads go, and then putting some javascript in the footer to fill in those placeholders with the actual ad code.

Since the page is no longer waiting for every ad to load before rendering the body, it made a big difference in apparent speed.

This sounds like the

greg_y's picture

This sounds like the solution to issues we've been having recently.

What did you surround the javascript in the footer with so that it loaded into the placeholders above (my template, CSS, javascript, etc skills are self-taught, and I'm not the best teacher)?

Thanks!

SEO would also impact

tjholowaychuk's picture

SEO would also impact slightly from this change allowing the bots to skip these tags and hop over to the content. As for document.write, I dont think so, jQuery does not use it but some of the plugins may

vision media
350designs

This is really hard to do in a generic way

bhuga-gdo's picture

We did a -lot- of experimentation with this at our site. We have serious performance issues stemming from large numbers of modules each requesting their own css and js files (still on 4.7) and went through great pains to backport boost to aggregate css and js into a file each. After we had a proof of concept of aggregation working (no small feat by itself), I tried to move JS to the bottom of the page.

Long story short, modules expect the page to be loading a certain way, if only implicitly (since developers test the way Drupal loads things by default). For some modules, this is fine--they don't do anything until the user interacts with something, so they can load at the end without an issue. Plenty of other modules, though, do things to the page before the user does anything or assist it in rendering correctly. As a simple example, we had a lot of problems with TinyMCE.

It's conquerable, but you'll have to do a lot of testing and customization to make it work right. You probably aren't running a google map and TinyMCE all on the same page like we are, and most of the modules we are working with were not a problem. We could have solved our issues (and still may), but it was going to require a pile of custom patches in our SVN repo; avoiding a patch to core involves significant things happening with the hooks at the tail end of the page rendering process that may or may not have worked with later modules or module upgrades.

If you really need this to happen, you'll really have to want it. Fixing it community-wide would require a change in core to load JS at the end of a page by default, unless a module specifically requests to be loaded at the top of the page. I doubt this will happen anytime soon, no matter how good of an idea it would be.

Should you do this if you use JQuery

andremolnar's picture

Couple of thoughts:
1)
One issue is certainly the number of JS files / CSS files you are loading in a page.
As the article you link to points out - all those http requests slow things down (Take a look at the "Net" tab in firebug - and watch the miliseconds add up).

I ran into this with the site I am working on now. We achieved significant speed improvements by a) compacting/obfuscating the JS (fewer bytes to download) b) consolidating several script files into a single file. There is greater code maintenance overhead - but that can be avoided with smart packaging of releases.

Long story short - loading one smaller JS file is going to make your page faster regardless of whether it is at the top or the bottom.

2)

I'll be the first to admit that I am no javascript or JQuery rock star / expert, but my understanding is that $(document).ready() exists so that javascript can be loaded at the earliest possible time (in < head >) and start interacting with the DOM as soon as it is loaded (but before the browser has finished rendering the page).

By loading scripts at the end of the page do you not lose this benefit?

andre

By loading scripts at the

blueflowers's picture

By loading scripts at the end of the page do you not lose this benefit?

You totally lose this benefit, in fact there are times when interaction cannot occur if the js files are loaded at the bottom.

I'm having a hard time understanding the 'benefit' to this considering after the js file is loaded the first time, your browser will look in the cache first for it before sending a new request, perhaps optimization needs to be made elsewhere like in your markup or image slices if your pages are loading so slow.

In fact, if you look at the source to the original link posted there is still js being loaded at the top, and the bottom only contains 'analytics' code -- which makes sense to load at the bottom.

Yeah anything onload or

catch's picture

Yeah anything onload or document.ready is going to get out of whack with this afaik, which means jquery and any dependent scripts which use those are going to have to be in the header anyway. With js aggregation in D6, there'd be no point splitting a few scripts into the footer, you'd lose any speed gains from that by serving the extra files. I'd rather have the page take a fraction longer to load, than have js layout changes shifting things around during the process.

Well I just tried this, and

catch's picture

Well I just tried this, and it's working pretty good - including stuff like suckerfish menus and jquery.corner.js

I thought most of the issues would be around stuff that happened at window.onload - maybe document.ready avoids all that, in which case, great!

edit: no actually I am getting some 'onload' with jquery corners - since it's adding elements to the DOM. But the saving in firefox spinning is massive.

OK well here's one issue -

catch's picture

OK well here's one issue - quicktags disappeared completely from our comment textareas.

/me goes off to see if there's something similar which can get around this.

Doesn't use $(document).ready()

Wim Leers's picture

That module still uses plain old JS instead of jQuery. It doesn't use jQuery's $(document).ready(), and that's the reason :)

Yeah I noticed ;)

catch's picture

Yeah I noticed ;) document.write and all kinds of stuff in there.

I really really don't want wysiwyg on my site, but my users really, really want buttons. Looks like there's at least one alternative that's jquery based so I'm going to try to get one going soonish. I miss my extra quick loading times already :(

I was doing the yslow optimisations independently of reading your Planet post earlier this week, alongside getting APC working finally (had it going before, but major segfault issues which seem to be better this time around). It's great, cut out a good second of page requests, and APC has massively cut down the load on my VPS.

$.document.ready(func);

jefkin@drupal.org's picture

The jquery code for this is essentially an onload (though implemented differently). Both onload and jquery's document.ready will run AFTER all the html DOM has been built.

So, in an ideal world, from a performance view, location of the $script in your template shouldn't matter at all.

The reason pages are often affected is probably because many modules use shortcut direct javascript queries not protected by onload or document.ready, so placing those "offending" scripts at the bottom of the page lets the dom get better established prior to that js running.

My results have been:

1) With well behaved modules that already use document.ready, you could have a small benefit on most pages.
2) With troublesome modules that SHOULD use document.ready, you will see a great benefit on most pages.
3) With bad modules that use 1st generation javascript like document.write, you can see errors or even failures.

ymmv: Caveat Emptor (or in my case Caveat Speller)

more details?

greggles's picture

there are times when interaction cannot occur

Can you provide more details on how to sense those situations or what specifically to look for?

I'm having a hard time understanding the 'benefit' to this considering after the js file is loaded the first time, your browser will look in the cache first

Two thoughts here. First, my understanding of js aggregation in D6 means that many pages will have page specific combos of JS so you'd have to browse a lot of a site before you cached all the js files. Second, it really depends on your site whether "slowness goes away on the second page load" is an acceptable problem. It's a site-by-site situation whether that's acceptable so I think it warrants more investigation.

Thanks for your thoughts.

--
Open Prediction Markets | Drupal Dashboard

Did some testing

andremolnar's picture

I decided to do some tests with regard to manipulating the DOM by including code in the Head and near the bottom of the page - keeping in mind the purpose of $(document).ready():

Testing method:

Configuration:

I created 200 nodes with the devel module. Each with 2000 characters displayed before the teaser break. I adjusted the default_nodes_main drupal variable to allow 200 nodes to be displayed on the home page. (Basically, I wanted to have a great deal of content rendered by the browser between the head of the document and the footer [approx 400k of HTML text])

Scripts:

I Create two js files. head.js and footer.js
Containing the following code:

head.js

Obviously not useful code in the real world - but it does DOM manipulation

//time before document is ready
headNotReadyTime = new Date();
//manipulate DOM before its ready - not usually a good idea can cause funkiness but this is a test
$('body').addClass(' head NOT ready time: '+headNotReadyTime+' '+headNotReadyTime.getMilliseconds());

$(document).ready(function(){
  //time when document is ready
  headReadyTime = new Date();
  //manipulate the DOM again
  $('body').addClass(' head ready time: '+headReadyTime+' '+headReadyTime.getMilliseconds());
})
footer.js

//time before document is ready
footerNotReadyTime = new Date();
//manipulate DOM before its ready - not usually a good idea can cause funkiness but this is a test
$('body').addClass(' footer NOT ready time: '+footerNotReadyTime+' '+footerNotReadyTime.getMilliseconds());

$(document).ready(function(){
  //time when document is ready
  footerReadyTime = new Date();
  //manipulate the DOM again
  $('body').addClass(' footer ready time: '+footerReadyTime+' '+footerReadyTime.getMilliseconds());
})

head.js was included inside the document < head >
footer.js was included just before the end of </ body >

Results (edited for readability):

footer NOT ready time: 02:31:25 23ms
head ready time:       02:31:25 26ms
footer ready time:     02:31:25 28ms

Reading the results:

Obviously the headNotReadyTime was called and executed first - but since it attempted to manipulate the DOM by adding something to the < body > which did not exist yet - it failed to work.
footerNotReadyTime was executed next - and by the time that code was called at the bottom of the page < body > existed and was able to add its time to the < body > tag.
headReadyTime was executed next - and since the DOM was 'ready' it was able to write its time.
footerReadyTime executed next - and it was able to write its time.

Followup:

All well and good - but I want to know how long it took between 'headNotReady' and 'footerNotReady' - so I modified the footer script to print the headNotReady time

(results edited and sorted for readability and logical sequence - actual results had head Not ready time printed last)

head Not ready time:   02:41:03 302ms
footer NOT ready time: 02:41:04 167ms
head ready time:       02:41:04 169ms 
footer ready time:     02:41:04 169ms 

And there it was - 0.8 second difference between the top and the bottom of a 400K page. This number represents the DOM loading time.

Conclusions:

If you want to manipulate the DOM - the DOM must obviously be loaded in order for you to manipulate it.
$(document).ready(function(){//DOM manipulation}) does what it is advertised to do. i.e. wait till the DOM is loaded.
But if you insert code at the bottom of the page outside of such a function the DOM is nearly completed its load and your code will do its trick (But, it is still best to wrap it in that function)
So -It turns out that if you want to manipulate the DOM it makes no significant difference whether the code that does the manipulation is included at the top or the bottom of the page.

However, if what you want to insert into the DOM requires calculation you might want to start those calculations at the TOP of the page OUTSIDE OF $(document).ready(function(){}); They will get a head start. Though I wonder what happens if the results aren't ready by the time your DOM manipulation code starts? I suppose you would either conditionally insert the value of your calculation OR you could put a 'sleep' in your code to keep trying until the value was available.

So - long story short - I've demonstrated that some code is perfectly fine at the bottom of the page. I've demonstrated that there maybe a reason to start some code at the top of the page.

BUT, I don't know how to test for what Yahoo says is a problem. i.e. What kind of js code introduced at the top of the page will slow down the page render? What kind of code would keep the page from loading progressively? What is the test case that would cause a slower page load by having js at the top.

Sorry, that was way longer a post than I had intended to make. I hope its of some value to someone. Let me know if you see a flaw in my test or if I have drawn any incorrect conclusions. OR if you have different conclusions please share.

andre

thanks so much!

greggles's picture

Andre, to my javascript-naive mind this is quite helpful.

BUT, I don't know how to test for what Yahoo says is a problem. i.e. What kind of js code introduced at the top of the page will slow down the page render? What kind of code would keep the page from loading progressively? What is the test case that would cause a slower page load by having js at the top.

You can see the effect of progressive rendering quite easily on the admin/build/menu/navigation page in Drupal6. That has a huge menu structure which js manipulates to add the drag/drop feature. If you leave JS at the top, the page looks like a big white screen until the DOM manipulation is done (at least for me on FFx2.x). When I move my $scripts to the bottom it loads the html first and I see the structure and then hangs for a second while the DOM manipulation is finished.

Testing for faster downloading via better parallelization is perhaps a bit harder to do. I'm not sure how we test that in a way that provides meaningful results (i.e. is statistically significant).

--
Open Prediction Markets | Drupal Dashboard

sorry to resurrect ancient

HansBKK's picture

sorry to resurrect ancient history, but this is all that turned up in my initial searching

I adjusted the default_nodes_main drupal variable to allow 200 nodes to be displayed on the home page

How? I can't seem to find that option anywhere in the D5 or D6 admin config screens? Is it leftover from D4?

Can you provide more details

blueflowers's picture

Can you provide more details on how to sense those situations or what specifically to look for?

sure almost anything using an 'onload' method that requires immediate DOM manipulation. So for example I'll have a menu that is pure CSS, and does a fancy rollover with scriptaculous. If one image on the page creates a hang, the user may (un)experience this 'feature' due to the js not being loaded yet. By keeping the JS in the head, you are (almost) guaranteeing that this will not happen It's a pretty rough example, but illustrates the point. -- I know clients hate this kind of crap.

My biggest headshaking with this method, is (as illustrated by andremolnar) that you're just stealing from Peter to pay Paul in this case.

The page loading time is the same but now 'yahoo' is asking us to mix JS script tags with content, which is why everyones 'standards' detectors are going off. Sure it's considered 'standard' by w3c, but is this not going against the entire 'separate content from scripts and functionality' methods we've been working to hard to acheive these last few years? The head is absolutely perfect for this.

Two thoughts here. First, my understanding of js aggregation in D6 means that many pages will have page specific combos of JS so you'd have to browse a lot of a site before you cached all the js files.

Do you mean that the JS files are only loaded as needed? If that's the case, that's awesome! That in-itself will speed page loading significantly.

Second, it really depends on your site whether "slowness goes away on the second page load" is an acceptable problem. It's a site-by-site situation whether that's acceptable so I think it warrants more investigation.

Well unless you have a site which is "sans-images", you're going to experience this regardless.

I have to wonder if people are just running out of ideas for site optimization and the content needed to write books on the subject ;)

I recently read about doing

aaron's picture

I recently read about doing this somewhere. Can't find the link right now. It pointed out there are some cases where this is bad practice, but I don't remember where. I'll see if I can find that again.

Aaron Winborn
Advomatic, Web Design for Progressive Advocacy, Grassroots Movements, and Really Cool Causes

Aaron Winborn
Drupal Multimedia (my book, available now!)
AaronWinborn.com
Advomatic

I recently have done this on

yaph's picture

I recently have done this on a few Drupal sites and experienced no problems. I can't say that those sites feel faster for me but yslow told me that they are being loaded and rendered more quickly.
--
Websites: SEO-Expert-Blog.com | Torlaune.de

do some quick benchmarks

tjholowaychuk's picture

do some quick benchmarks with AB and compare, im curious, APC was definatly the biggest contenter for me when it comes to performance, over a 42% increase in our last site

vision media
350designs

AB?

kbahey's picture

AB will not help at all when it comes to the effect of Javascript.

Neither would APC.

Both measure/speed up the backend components, not the total browser time.

Drupal performance tuning, development, customization and consulting: 2bits.com, Inc..
Personal blog: Baheyeldin.com.

Drupal performance tuning, development, customization and consulting: 2bits.com, Inc..
Personal blog: Baheyeldin.com.

Thats true, I didnt mean

tjholowaychuk's picture

Thats true, I didnt mean that APC would help with this issue, just simply stating that I would target those big/easy performance enhancements before I would go sticking JS in a different location in the DOM.

vision media
350designs

well

greggles's picture

Two reasons to consider this proposal even though it's not big/easy.

1) For people who are on a VPS or Dedicated, we assume they have already done the Big/Easy things, so that is no longer relevant. Now we need yet more performance, but where do we get it from? This is an option.
2) For people who are on a shared server who have no control over the Big/Easy things, this is something which they do have control over. So, this could help them as well.

--
Open Prediction Markets | Drupal Dashboard

I got a little sidetracked

tjholowaychuk's picture

I got a little sidetracked :P
Anyone have numbers for load speed with JS / CSS aggregated into single files compared to normal?

vision media
350designs

easy to test

andremolnar's picture

This is easy to test

As mentioned before - take a look at the 'net' tab in firebug.
Create a page with 5 js files included and 5 css files included

Take a look at the 'net' tab - it will show you how long it took to load the files (http requests)

Now consolidate the 5 js files into one

Take a look at the 'net' tab again.

It will have taken a little less time to load the page - having to do only 1 http request instead of 5.

repeat for css files.

andre

Yeah I know, sorry im bad

tjholowaychuk's picture

Yeah I know, sorry im bad with my speech today or something haha, I just didnt have time to check earlier today, but I just did the test with the CSS aggregation/compression which bumped it from 1.40s to 900ms

vision media
350designs

Front end vs. back end

kbahey's picture

Just to be clear, this thread is about client side tuning: how fast pages are rendered, not how fast they are generated.

I would like to point out to Steve Souders of Yahoo, who has a video on client side tuning here http://video.yahoo.com/video/play?vid=1040890

It covers this topic and much more.

Drupal performance tuning, development, customization and consulting: 2bits.com, Inc..
Personal blog: Baheyeldin.com.

Drupal performance tuning, development, customization and consulting: 2bits.com, Inc..
Personal blog: Baheyeldin.com.

Some code needs to be loaded in header

ximo's picture

The following is a comment I wrote on Wim Leers blog post Improving Drupal's page loading performance. I haven't read the whole thread, so sorry if I'm repeating something or stating the obvious :)


AFAIK, loading JS at the bottom should be fine in most cases - jQuery usually works unobtrusively by interacting with the DOM once the document is ready. As long as the jquery.js file is loaded before any jQuery code, there should be no problem.

There are however some situations where you'd want jQuery to do its magic before the document is completely loaded, such as dynamically adding classes to elements to change their appearance. If this has to wait for the bottom of the document to be reached, one would experience an annoying glitch as the code is run. An exampe of this is the plugin to add rounded corners to boxes.

So loading jquery.js and drupal.js in the footer by default, and in the header if a module has added some JS there, sounds reasonable. Themes may add JS directly into tpl.php files, but this is bad practice anyway, one should use drupal_add_js() instead.

"Query to do its magic

tjholowaychuk's picture

"Query to do its magic before the document is completely loaded, such as dynamically adding classes to elements to change their appearance"

Would this work properly? I have no tested this, I have the 'glitch' effect on stationerystyle.com when switching themes VIA JS, however not all DOM elements would be ready so some may not inherit the proper classes?
vision media
350designs

Where on stationerystyle.com

ximo's picture

Where on stationerystyle.com can one switch themes? Moving the JS to the bottom of the page makes the DOM ready before the browser gets to the JS, which is faster than having the JS in <head>. Have you tried that?

I recall having a delay before the jQuery would kick into effect on one site, but can't remember which. When I think about it, I think I solved it by actually putting the JS at the bottom of the page.. so maybe I'm just mixing things up here.

There may still be situations where you'd want to have JS in <head> though, and we should be careful not to block out that option.

If you click options there

tjholowaychuk's picture

If you click options there are sorting / filter / theme & layout options, it has a bit of a glitch look to it while loading in the white/black images, however the theme choosen is stored in a js cookie and then toggled when the DOM is ready, not the best solution but its what we have right now

vision media
350designs

Adding classes to elements

Xano's picture

Adding classes to elements can only be done after those elements have been created. This should be done or is likely to be done using $(document).ready(), which isn't executed before the entire DOM has bee parsed, which is after the HTML has been loaded. Moving scripts to the end of the document shouldn't pose a problem in this case.

FYI

agentrickard's picture

Doing some other testing, and I put some jQuery at the bottom of the page. Seems to work fine.

http://mdxlab.com/mysite/

--
http://ken.therickards.com/
http://savannahnow.com/user/2
http://blufftontoday.com/user/3

We've added all JavaScript

m3avrck's picture

We've added all JavaScript to the bottom of http://www.mothersclick.com/ and the site is rendering considerably faster, no problems whatsoever.

It's also the default behavior of my new base-theme that is coming out this Feb too: http://drupal.org/project/blueprint

Partner at Detroit Venture Partners. Sold ParentsClick to A&E. Ex-Drupal dev. Cornell Engineering alum. Tech pioneer leading startup renaissance in Detroit.

I should note, the

m3avrck's picture

I should note, the JavaScript at the bottom of the page is for internal QA builds right now, production will be sometime in Feb.

Partner at Detroit Venture Partners. Sold ParentsClick to A&E. Ex-Drupal dev. Cornell Engineering alum. Tech pioneer leading startup renaissance in Detroit.

Case reported that does cause problems

Wim Leers's picture

When using something like jCarousel, which (heavily) alters the appearance of your site, you have to do the following to prevent flicker:
1) put the JS file at the top
2) make the calls inline (yes... that's ugly!)

Reported by dalin of advomatic, over here: http://wimleers.com/article/improving-drupals-page-loading-performance#c...

I haven't done benchmarking

mfb's picture

I haven't done benchmarking but I imagine this could do more for performance than moving some script tags around: Add to your apache config (assuming js is being served as "application/javascript"): AddOutputFilterByType DEFLATE text/css application/javascript

Once you are compressing your js on the fly, you can get rid of the packed version of jQuery that comes with Drupal. Instead use the minified jQuery which has less overhead on the client side (no unpacking necessary).

I swear you posted this a

tjholowaychuk's picture

I swear you posted this a few weeks ago :P
I agree though, as great as the packing algo looks I have heard nothing but downers performance-wise. Tough to benchmark things like this since there is such inconsistency with latency and loading of other resources as well, would be interesting though.

vision media
350designs
Print Huge Edmonton Printing Services
Design Inspiration Gallery

Sadly this is a sever level

moshe weitzman's picture

Sadly this is a sever level directive, not .htcess.

No, it's per directory.

jcisio's picture

No, it's per directory. Putting it in .htaccess works perfectly for me. Just note that it's deprecated in Apache 2.1, use AddOutputFilter instead.

--
[vi] www.thongtincongnghe.com
Trang tin điện tử về CNTT, Viễn thông, Điện tử...

Late coming to this highly

Gman's picture

Late coming to this highly informative discussion. I have tried the $scripts to the bottom trick and it works great, except on my Google maps sites. There is a Drupal.extend call that is inline where the map is placed. It probably should be added at the 'footer' level but it would be hard to mandate such a thing from all module developers. I know that the FCKEditor also has a similar issue.

But for pages that didn't have this issues, I experiences a 10 point lift on my YSlow score. First, we are slave to the google gods for search ranking placement, now we are slaves to the YSlow score. :)


Drupal Blog
Dog Parks via Drupal

What about keeping two

Xano's picture

What about keeping two arrays of JS files in Core: $scripts and $scripts_init (or something else, I'm not good at naming). Both are rendered and passed on to page.tpl.php like $scripts in D6. $scripts should be printed right before </body> and $scripts_init in </head> for necessary tasks. Drupal_add_js() would have to accept another parameter to define whether the JS file should be put at the top or the bottom of the page. When aggregating JS files sites would be left with a maximum of two JS files.

AFAIK, Drupal 7 have this

jcisio's picture

AFAIK, Drupal 7 has this feature: another position for drupal_add_js.

--
[vi] www.thongtincongnghe.com
Trang tin điện tử về CNTT, Viễn thông, Điện tử...

Thanks for the tip. A $scope

Xano's picture

Thanks for the tip. A $scope parameter has been introduced in D5:

$scope (optional) The location in which you want to place the script. Possible values are 'header' and 'footer' by default. If your theme implements different locations, however, you can also use these.

My problem with this is that it's theme dependent, while JS files should actually not depend on the theme. Modules can't be certain what locations are possible afaik, unless these locations are actually regions, but I would keep it restricted to header and footer use to make sure this stuff works for every theme possible.

Here's a code snipet I

hkirsman's picture

Here's a code snipet I wrote:

/**
* Implements hook_js_alter.
*/
function YOUR_TEMPLATE_NAME_js_alter(&$javascript) {
  foreach($javascript as $key=>$var) {
    if ($var['scope'] !== 'footer') {
      $var['weight'] -= 100000;
    }
    $var['scope'] = 'footer';
    $javascript[$key] = $var;
  }
}

Some modules use scope setting in drupal_add_js and set the script to the footer. It's echoed in $page_bottom variable in html.tpl.php. So if you put $scripts; after $page_bottom, some scripts might stop working.

My code puts all the script to footer and sets weight to very low number so the scripts that suppose to be loaded in the footer would have similar load order (jQuery first etc).

Without putting js to footer, my site flickers on every page load (even with aggregation). When scripts are in the footer, page loads without flicker.

I think this sould be packaged into a module that adds extra setting to /admin/config/development/performance

All in all, Drupal should do itself. :)

What you think?

if there was a js file that

SocialNicheGuru's picture

if there was a js file that absolutely needed to be loaded in the header, I could also exclude it in code. Not bad.

How does this work with CDNs (http://drupal.org/project/cdn)

Check

Weight of script

SocialNicheGuru's picture

Hi all,

I used the code above. http://groups.drupal.org/node/8399#comment-880993

this outputs the scripts in the footer.

A module writes to page_bottom via hook_page_alter and the js content gets written to the footer region.

It writes above the script js that the above code inserts and breaks the site.

How can I change the weight of what is produced by the code above above vs what is placed by the module?

What's the module you are

hkirsman's picture

What's the module you are talking about?

Another issue with the code I wrote is that the config is also in the footer. So some modules might not get access to it if they launch too early.

Advanced CSS/JS Aggregation

mgifford's picture

I think you can do that with https://drupal.org/project/advagg

Along with a lot of other good stuff.

If we will print $script

phponwebsites's picture

If we will print $script below the footer in .tpl.php page, then we've chance to face below given proplems.

ReferenceError: jQuery is not defined
})(jQuery, Drupal);
js_B2uv...8Qrg.js (line 166)

TypeError: Drupal.behaviors is undefined
attach: function(context) {
lightbo...3212595 (line 1183, col 2)

TypeError: Drupal.behaviors is undefined
attach: function (context, settings) {
js_igOG...0jj8.js (line 49, col 4)

TypeError: Drupal.behaviors is undefined
attach: function (context, settings) {
js_sc0R...NNZo.js (line 3, col 4)

TypeError: obj is undefined
length = obj.length,

function

qqboy's picture

function qin_tt_js_alter(&$js){

foreach($js as $k => &$j) {
if ($j['data'] == 'misc/drupal.js' ||
$j['type'] == ' setting' ||
(is_string($j['data']) && (preg_match('/jquery/i',$j['data']) || preg_match('/admin_menu/i',$j['data'])))
){
$j['scope'] = 'header';
} else {
$j['scope'] = 'footer';
}
}
}