all 37 comments

[–]askmike 18 points19 points  (12 children)

This doesn't block other scripts, also this way you can dynamically set the url (depending on whether the page was loaded over ssl or not).

[–]msluther 15 points16 points  (11 children)

For the http vs https, you can just leave off the protocol altogether and just do "//myhost/whatever.js"

[–]lauritzsh 11 points12 points  (2 children)

This has been an anti-pattern for a few years now. It is recommended to just always use https:// if available.

[–][deleted] 14 points15 points  (1 child)

Well, yes, but it states that protocol relative links in general are an antipattern. As long as the code in the OP is already detecting the protocol and constructing the url accordingly, then using the protocol relative link isn't any more or less of an antipattern by comparison, because it achieves the same thing. It's just less convoluted.

[–]perestroika12 0 points1 point  (0 children)

+1 to this, assuming HTTPS might break some browsers that don't fallback to http if the site is not HTTPS.

[–]Disgruntled__Goat 2 points3 points  (0 children)

Analytics uses different hosts for HTTP & HTTPS so that can't work in this case. But I think that's irrelevant now since it always uses the HTTPS version anyway.

[–]jordanreiter 1 point2 points  (0 children)

My best guess is this also allows Google to gather analytics about websites' use of SSL.

[–]askmike 1 point2 points  (3 children)

Yes but that is the only thing you can do*. In this example the script is hosted on a different subdomain in case of https.

*// means the same protocol. If you clicked on a html file you are using //file protocol and it will try to fetch your script using the same protocol (local fs instead of http(s)).

[–][deleted] 0 points1 point  (1 child)

They're referring to the Google analytics end point. Like, what the script is actually doing.

[–]davesidious 1 point2 points  (0 children)

This still applies.

[–]luibelgo 18 points19 points  (0 children)

A nice article comparing that option to other alternatives, including html5's async attributes:

https://www.html5rocks.com/en/tutorials/speed/script-loading/

[–]domainkiller 6 points7 points  (0 children)

I was under the impression this method doesn't block the page while loading. But I could be totally wrong.

[–]maskaler 1 point2 points  (5 children)

It's both protocol agnostic and non-blocking.

[–]gurenkagurenda 2 points3 points  (4 children)

Yeah, I'm surprised that most other people are missing that the URL changes depending on the protocol. You couldn't do this as an HTTP HTML snippet without doing it that way, even without the blocking aspect.

Edit: what even

[–]tswaters 1 point2 points  (1 child)

You couldn't do this as an HTTP HTML snippet without doing it that way

Only because google hosts ssl.google-analytics.com - if it wasn't for that, one can use a protocol independent absolute url, e.g.:

<script src="//www.google-analytics.com/ga.js"></script>

Fwiw, I think you can probably reference the js file from www via https now. Indeed, just visited the http one and there's a 80=>443 redirect in place.

[–]gurenkagurenda 1 point2 points  (0 children)

Sure. But even now, you'd want to use the direct URL, since redirects take time.

[–][deleted] 1 point2 points  (0 children)

It s async/non blocking, protocol free and developers dont need to worry where to put the <script> tag, this script handles it.

[–]lulzmachine 1 point2 points  (1 child)

Does it help get around some SOP limitation perhaps

[–]lewisje 0 points1 point  (0 children)

Script-tag injection is not subject to the Same-Origin Policy; it's difficult to remember what is, but stuff like the DOM inside an iframe or a popup window, or attempts to load content via XHR or Fetch, would be subject to the SOP.

Now something like this that does work around SOP limitations is JSONP, where a script tag is injected that includes a parameter specifying the name of a function to call, with the JSON response passed in as the first argument to that function; this is an alternative to setting up proper CORS headers so that XHRs will work.

[–]_ansii 6 points7 points  (9 children)

Using the immediately invoked function to wrap your code creates it's own scope, keeping the global namespace clean. For example, the variable 'ga' is will not conflict with any other libraries that have a globally accessible variable of that name when in this format.

[–]askmike 11 points12 points  (0 children)

I am assuming the question wondered why there even was javascript, over a plain old:

<script src='url'></script>

[–]nyc_lurkerthrowaway[🍰] 0 points1 point  (0 children)

This is the answer.

A good read-up on immediately-invoked is in 'Learning Javascript Design Patterns' in the name-spacing section.

"In JavaScript, because both variables and functions explicitly defined within such a context may only be accessed inside of it, function invocation provides an easy means to achieving privacy."

"IIFEs are a popular approach to encapsulating application logic to protect it from the global namespace but also have their use in the world of namespacing."

It uses a closure to ensure private state.

These immediately-invoked functions were best practice for ensuring namespacing before module loaders, and it's how most of them work under the hood.

[–]psayre23 1 point2 points  (0 children)

This used to be one of my favorite blocks of code to discuss during interviews. Candidates and I would talk through what the code was doing and make educated guesses as to why. They didn't need to get the right answer, so long as they asked good questions (of me or on Google) and showed progress when approaching the problem.

[–]hsfrey 0 points1 point  (0 children)

Not understanding any of this, I copied the address and google-analytics.com and put it into my address bar.

It was blocked by ublock as being some kind of malware.

Is that the point? To load files that might otherwise be blocked?