

Show HN: Cross-browser asynchronous JS script loader w/callbacks - niftylettuce
https://github.com/niftylettuce/javascript-async-callback

======
OmarIsmail
I'm seeing some pretty fundamental issues here. I suppose if you assume that
you'll have total control of everything loaded then some of the assumptions
made here may be an ok trade off, but from my experience it's better practice
to be more guarded.

Specifically:

1) the window.onload is being directly overwritten without any chaining. The
safe way is to first store a reference to whatever was in .onload beforehand
and call that in the overwritten onload.

2) the load check uses an interval on a 10ms timer. Chained setTimeouts are
much better for performance and 10ms is quite an aggressive default. 50ms gets
called 5x fewer and has a imperceptible difference to the user.

3) _async is some big ol' global var with no function scoping at all.

~~~
phoboslab
How has setTimeout "much better performance" than setInterval? It's a myth
that setInterval queues up function calls if they take a long time, if that's
what you're referring to.

~~~
anatoli
"Much better performance" is perhaps a bit misleading since it's not black and
white, but at the core OP is right. See this thorough SO answer for more info:
<http://stackoverflow.com/a/731625/886402>

------
taf2
thank you for posting code!

the problem with this solution is you had to include a blocking js script
first to use it... a better solution is to inject your script and for
callbacks use an array. Look at how GA.js works, this is all it does, push
functions onto an Array (builtin) and once the code loads start pop'ing
functions to invoke off the array see: <https://gist.github.com/3616965>

to make it even better replace the push method on the Array with the invoke
method meaning once the code's are loaded - you have immediate invoke of
functions... someone should spell this out clearer but it makes me sad to not
see this technique used more... it's tiny. see:
<https://gist.github.com/3616991>

updated with two version and formated.

~~~
muyuu
Good stuff. I guess this is quite compatible as well.

------
scriby
Not sure why I would use this when other solutions like LABjs are rock solid,
fully featured, and small (~2k zipped).

<http://labjs.com/>

------
przemoc
It's good to know other, already used, mature solutions.

yepnope is an asynchronous conditional resource loader that's super-fast, and
allows you to load only the scripts that your users need. 1.7kb minified and
gzipped. Check it out!

<http://yepnopejs.com/>

<https://github.com/SlexAxton/yepnope.js>

Another Script Loader?#?@$!@# - Why Use Yepnope? - quoting conclusion from the
page:

> In short, we want you to make the right decision for your application. We
> can certainly think of times when yepnope.js would not be the correct choice
> for a resource loader, and we hope we've made those situations abundantly
> clear in our documentation. However, we also think that yepnope meets a lot
> of people where they are, when it comes to a balance of performance,
> usability, size and feature-set.

> If you have questions about if yepnope is right for your application. Send
> us a tweet or an email and we'll help you out. Most of us in the script-
> loader author scene are total BFFs and we aren't about competition, we're
> about pushing the edge. In other words, we totally use LABjs and RequireJS
> in a bunch of our projects, because they're badass (and the other ones are
> probably great too!).

------
spicyj
Would be nice if conditional comments weren't used so that it's compatible
with most JS minifiers.

------
wamatt
Nifty, thanks for sharing. :)

Also, as others have mentioned, there are plenty of options out there, so it
might be useful highlight any specific difference or advantage this solution
provides over LabJS, RequireJS, Yepnope, curl.js etc

On a side note, there is a rather comprehensive feature matrix of a number of
popular JS loaders
[https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxh...](https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ)

~~~
niftylettuce
EDIT: put the repo back up to not cause broken link here... and added a notice
to keep people from starring it

i (originally) took the repo down b/c so many people starred it and i didnt
want them to be scarred :) never saw that spreadsheet b4, thx for posting. a
lot of good discussion in this thread. the project was just a little hack
rewrite, i never stated anywhere it was better than anything else and you guys
can see why :) feedback is great. i did run some tests on it and it is
surprisingly almost as fast/faster +/- as similar solutions though! haha.

~~~
wamatt
Given that you probably didn't know about many existing solutions, it's rather
great you wrote your own, after realizing a need :)

I'd keep the repo up! (even if the feedback is a bit daunting)

~~~
niftylettuce
done, put a notice on the repo though

------
teh_klev
Nothing to see now. Yanked by OP:

<https://twitter.com/niftylettuce/status/242946633367683075>

~~~
niftylettuce
see <http://news.ycombinator.com/item?id=4474094>

------
jonny_eh
Cool stuff, very handy. Next step, add dependancy support. Maybe pass in an
array of scripts, along with their dependancies, and load them all in the
right order.

------
ashray
Nice work! Definitely simplifies stuff. Are you thinking of integrating
writecapture [1] for a document.write override option ? Might be a nifty thing
to do since a lot of external scripts use that and can block access or worse,
clear the DOM on an async load.

[1] <http://github.com/iamnoah/writeCapture>

------
huskyr
I wrote something similar some time ago:

<https://github.com/hay/jsdynaload>

Allows you to do something like this:

jsDynaLoad(['1.js', '2.js', '3.js'], function() { console.log('callback'); });

------
alagappanr
The question might be naive, but can you tell me the advantage of using this?

~~~
jonny_eh
Normally, you would load javascript files by inserting a <script
src="whatever.js"> tag into your HTML document's <HEAD> or <BODY>. The big
disadvantage to that is it's synchronous. That means no rendering or executing
of javascript can occur while that js file is being run.

This library would allow you to run it asynchronously, so that other js code
can continue to run.

------
niftylettuce
See <https://gist.github.com/3620903#comments> for a better solution!

------
culshaw
Nice work, I would change that you are browsers sniffing to detecting
variables declared in the window for webkit prefixes.

------
jonthepirate
Similar to require.js but I like it!

