Skip to content

Loading…

Use yepnope/Modernizr.load or jQuery for the analytics snippet #542

Closed
beverloo opened this Issue · 23 comments

9 participants

@beverloo
H5BP member

EDIT..original title was:

Make script loading asynchronous or deferred

but now its about the GA snippet

Currently, all scripts defined in the boilerplate HTML will be loaded synchronously. We should investigate the possibility to make most of them either asynchronous, or deferred.

Line numbers are based on this revision:
https://github.com/paulirish/html5-boilerplate/blob/bad4fb528/index.html

Line 30 (modernizr-1.7.min.js):
Required to enable HTML5-elements in certain browsers. Keep it as it is.

Line 31 (respond.min.js):
This will only process stylesheets defined in the head, although it's a bad-practice, it's possible to define <style> (or rather, <style scoped> once browsers start implementing it) or <link> elements throughout the page. I recommend deferring this. Furthermore, since the vast majority of users getting this will be IE6, 7 and 8, we should consider placing this in an conditional [IE LT 9] comment.

Line 52 (jquery.min.js):
Required for the fall-back on line 53 to work. Without the fallback, deferring this would be fine (as only older Opera versions have issues with the execution order of deferred scripts). Keep it as it is.

Line 53 (inline):
It's an inline script, deferred/asynchronous execution requires the script to be external. Keep it as it is.

Line 57 (plugins.js):
Defer execution. Depends on jQuery, which will be loaded synchronously.

Line 58 (script.js):
Defer execution. Same as plugins.js

Line 63 (inline):
It's inline -- keep it as it is.

That'd mean changing three out of seven scripts, seems reasonable enough?

@retlehs

i like this. also take a look at #28

@mathiasbynens
H5BP member

+1 to most of this. However, as @necolas points out (see his comments below), deferring respond.min.js would result in a FOUC.

respond.min.js and modernizr.min.js could be combined into a single minified file. This would be even better than serving respond.js to IE-only — it’s so small the extra HTTP request for IE is more of a performance issue than the increased total file size of the combined files.

@necolas
H5BP member

This sounds great.

I think there might be some issues with deferring Respond.js

A "FOUC" in browsers without Media Query support.

I'm not that keen on using conditional comments around the script because if people don't want to use the conditional <html> classnames they may block downloads by leaving the conditional comments around Respond.js. We could use a MQ feature test from Modernizr 2 instead.

@scottjehl

Agreed, deferring respond.js makes for an ugly load in ie6-8. I'd love to make a version of respond that uses Modernizr's matchmedia function to see if it needs to run. That'd eliminate some redundancy between the two scripts. Happy to help!

@beverloo
H5BP member

Alright, thank you. All changes need to be properly tested prior to being rolled out either way.

Adjusting the contents of scripts, such as combining respond.min.js and modernizr.min.js, is not something I'm strongly in favor of. In their current form they're completely independent scripts, serving different purposes (with the exception of Modernizr 2 MQ-detection). Creating a modified version of RespondJS to work with Modernizr does sound like a great idea though, or, to make it even bolder, it could be an optional component available through Modernizr's builder. Both scripts are MIT-licensed.

@beverloo beverloo closed this
@beverloo beverloo reopened this
@nimbupani
H5BP member

@beverloo can haz pull req?

@paulirish paulirish closed this in 401e66a
@paulirish
H5BP member

done and done. thxx

@aoberoi

what about changing the google analytics code to use Modernizr.load()? there is a snippet in the docs that shows this done. is that not boilerplate-y?

@paulirish
H5BP member

@slexaxton whatcha think?

@SlexAxton

Yep. The technique I use on http://2011.texasjavascript.com/ does this with google analytics just dandily.

var _gaq = [['_setAccount','UA-XXXXXXXX-1'],['_trackPageview']];
Modernizr.load({
  load : 'http://www.google-analytics.com/ga.js' // usually last in the list
});
@aoberoi

mixed content issues on https?

@SlexAxton

Oh sure!

var _gaq = [['_setAccount','UA-XXXXXXXX-1'],['_trackPageview']];
Modernizr.load({
  load : '//www.google-analytics.com/ga.js' // usually last in the list
});

BOOM.

@SlexAxton

oh sad, google has different subdomains for their analytics. sry. yea. we'd need to sniff the window.location.protocol

@mathiasbynens
H5BP member

Note that we track page loading times as well, so the snippet would become:

window._gaq = [['_setAccount','UA-XXXXXXXX-1'],['_trackPageview'],['_trackPageLoadTime']];
Modernizr.load({
  load: ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js'
});

That said, switching to this snippet would make H5BP slightly less “delete-key friendly”, since users that don’t need Modernizr/yepnope for a specific project will have to switch to the regular GA snippet manually then.

I’m not against this change, but it’s something to consider.

@paulirish paulirish reopened this
@paulirish
H5BP member

reopening and changing the title since this ticket is now repurposed..

anyone -1 on making the GA snippet dependent on Modernizr?

@necolas
H5BP member

That said, switching to this snippet would make H5BP slightly less “delete-key friendly”, since users that don’t need Modernizr/yepnope for a specific project will have to switch to the regular GA snippet manually then.

This. But at the very least it would make a good addition to the "make it better" wiki.

@aoberoi

@SlexAxton i still get the same script when i go to https://www.google-analytics.com/ga.js vs https://ssl.google-analytics.com/ga.js. is there something im missing about including the ssl subdomain?

with that said, i think @mathiasbynens is right about it being less 'delete friendly'. if initializr could distiguish and do the right replacement this may still be worth it but for what? im not a pro on the script loading stuff, but it seems like the only benefit of using yepnope to do this versus the script dom element technique is that execution order would be preserved. this doesnt seem to matter knowing this should be the very last script, and no use case that i am aware of would want to listen for it to call back.

however that raises the question, do we have anything to gain by using Modernizr.load() for jQuery followed by plugins.js and script.js? we could get them to all load asynchronously (instead of serially with plugins.js berfore scripts.js) as they are right now, and still preserve execution order.

EDIT:

oh, fallback situation requires recursive yepnope. so we could parallelize the loading of plugins.js and script.js using

Modernizr.load([{
      load: 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js',
  callback: function () { if (!window.jQuery) Modernizr.load('js/jquery-1.6.2.min.js'); }
}, ['js/plugins.js', 'js/script.js']]);
@paulirish
H5BP member

@aoberoi

there is an edge case with IE6 with regard to SSL certificates that can cause a prompt to come up
if you dont support IE6 you arent exposed to the edge case
but
the GA team has said they do not officially support SSL use on their regular subdomain so if it breaks its your fault.

@aoberoi

@paulirish, okay gotcha.

actually theres no point in doing what i said above either if you deploy using the build script. it has gains if you are not, but this would complicate the logic in build.xml. i don't know how people feel about that.

i apologize for making this thread a mess! Just trying to contribute :)

@mathiasbynens
H5BP member

If yepnope isn’t available, but jQuery is, you could use something like:

// Don’t use $.getScript() since it disables caching
$.ajax({
  'url': ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js',
  'dataType': 'script',
  'cache': true
});

…or, for multiple scripts:

$.each(
  [
    ('https:' == location.protocol ? '//ssl' : '//www') + '.google-analytics.com/ga.js',
    '//connect.facebook.net/en_US/all.js#appId=1234567890&xfbml=1',
    '//platform.twitter.com/widgets.js',
    'https://apis.google.com/js/plusone.js'
  ],
  function(index, url) {
    // Don’t use $.getScript() since it disables caching
    $.ajax({
      'url': url,
      'dataType': 'script',
      'cache': true
    });
  }
);

I feel like all these alternative script loading solutions should go on a wiki page.

@necolas
H5BP member

I've also used this snippet (no dependencies) - https://gist.github.com/1025811

@paulirish paulirish closed this in d9cc711
@paulirish
H5BP member

now using Modernizr.load for analytics. ^_^

@rdeknijf rdeknijf referenced this issue
Commit has since been removed from the repository and is no longer available.
@gigafied gigafied referenced this issue
Commit has since been removed from the repository and is no longer available.
@gigafied gigafied referenced this issue
Commit has since been removed from the repository and is no longer available.
@gigafied gigafied referenced this issue
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.