Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to specify async files in headers?

So my timeline always looks like this

http://see.kirkstrobeck.com/TjQU/Screen%20Shot%202014-02-04%20at%206.40.14%20PM.png

The index.html loads and then asks for other files. I was thinking is there a way to have the headers that respond to the request say what files should come down? So it would look like this ..

http://see.kirkstrobeck.com/TjKl/Screen%20Shot%202014-02-04%20at%206.40.14%20PM.png

maybe something like ..

<?

header('fileGetRequest: /js/common.js');
header('fileGetRequest: /css/common.css');

?>
like image 298
Kirk Strobeck Avatar asked Feb 05 '14 02:02

Kirk Strobeck


3 Answers

I don't know of a way of doing it today, but SPDY expands the Link header with rel=subresource for exactly this use.

From Server Push and Server Hints:

Server Hint is a mechanism where the server can notify the client of a resource that will be needed before the client can discover it. The server does not send the entire contents of the resource, but rather just the URL as an early part of a response. The client can then validate its cache (potentially even eliminating the need for a GET-if-modified-since), and will formally request the resource only if needed.

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Encoding: gzip
Content-Length: 13847
Content-Type: text/html; charset=UTF-8
Date: Thu, 13 Jan 2011 17:47:12 GMT
Expires: -1
Server: FastServer1.0
Link: <logic.js>; rel=subresource

<html>
<body>
  [ lots of content here ]
  <script src="logic.js" type="text/javascript></script>
</body>

Source of the example: SPDY - LINK rel=subresource

If you know the client does not have the resource in cache, you may also want to consider Server Push, which saved the round-trip.

Server Push is where the server pushes a resource directly to the client without the client asking for the resource. The server is making an assumption here that pushing the resource is desirable. Pushing a cacheable resource can be risky, as the browser might already have the resource and the push can be redundant.


May, 2015 Edit

HTTP/2 (based on SPDY, which is somewhat phased out) also has Push Requests (and the Link header).

like image 181
Kobi Avatar answered Nov 19 '22 22:11

Kobi


If you're concerned with just javascript files and modern browsers there's an async attribute for script tags in HTML5. This is supported by Firefox 3.6+, IE 10+, Chrome 2+, Safari 5+, Opera 19+, IE Mobile 10+, iOS 5+ and Android 3+.

<script async src="script.js"></script>

If support for older browsers is required, and/or you also want to asynchronously load CSS and JS files you'll want to use one of the javascript async loaders. There are many great ones and one will likely fit your specific needs.

LazyLoad is one popular option that works with CSS and JS. Here's an example of it's use:

// Load multiple JS files and execute a callback when they've all finished.
LazyLoad.js(['foo.js', 'bar.js', 'baz.js'], function () {
  alert('all files have been loaded');
});

// Load a CSS file and pass an argument to the callback function.
LazyLoad.css('foo.css', function (arg) {
  alert(arg);
}, 'foo.css has been loaded');

Links to other asynchronous loaders:

  • HeadJS
  • ToastJS
  • RequireJS
  • yepnope.js
  • LABjs

And some credible sources:

  • Essential Javascript Loaders
  • Thinking Async
like image 25
Brett DeWoody Avatar answered Nov 19 '22 23:11

Brett DeWoody


1.This function will work cross-browser for loading scripts asynchronously

function loadScript(src, callback)
{
  var s,
      r,
      t;
  r = false;
  s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = src;
  s.onload = s.onreadystatechange = function() {
    //console.log( this.readyState ); //uncomment this line to see which ready states are called.
    if ( !r && (!this.readyState || this.readyState == 'complete') )
    {
      r = true;
      callback();
    }
  };
  t = document.getElementsByTagName('script')[0];
  t.parent.insertBefore(s, t);
}

2.If you've already got jQuery on the page, just use $.getScript(url, successCallback)

The simplest solution is to keep all of your scripts inline at the bottom of the page, that way they don't block the loading of HTML content while they execute. It also avoids the issue of having to asynchronously load each required script.

If you have a particularly fancy interaction that isn't always used that requires a larger script of some sort, it could be useful to avoid loading that particular script until it's needed (lazy loading).

3.Example from Google

<script type="text/javascript">
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/plusone.js?onload=onLoadCallback';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
</script>

4.You might find this wiki article interesting : http://ajaxpatterns.org/On-Demand_Javascript

5.If its any help take a look at Modernizr. Its a small light weight library that you can asynchronously load your javascript with features that allow you to check if the file is loaded and execute the script in the other you specify.

Here is an example of loading jquery:

Modernizr.load([
  {
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js',
    complete: function () {
      if ( !window.jQuery ) {
            Modernizr.load('js/libs/jquery-1.6.1.min.js');
      }
    }
  },
  {
    // This will wait for the fallback to load and
    // execute if it needs to.
    load: 'needs-jQuery.js'
  }
]);
like image 1
Augustus Francis Avatar answered Nov 19 '22 23:11

Augustus Francis