YUI on the goHow to include YUI components on demand
Christian HeilmannYahoo! Frontend Engineering Summit UK
December 2007
Why use libraries?
Use goodlibrary
Plan Code
Job done
Without libraries:
Browser HellPlan Code
OS inconsistenciesForget about obscure bugs
Cannot reproduce
> CVS commit> Conflict: > Too much fail error.
You.sacked = true
MCSE
“You want fries with that?”
Ergo:Libraries are good, mkay?
A common complaint.
“YUI is too big! If I want to build something on top of it, I need to include a lot of large
files!”
yahoo.js – 4.6kbdom.js – 35kbevent.js – 61kb
reset.css – 0.5kbfonts.css – 0.6kbgrids.css – 3kb
6 HTTP requests – 104.7kb
First Aid remedies:
– Use the minified YUI versions
yahoo-min.js – 1kbdom-min.js – 10.2kbevent-min.js – 13kb
reset-min.css – 0.4kbfonts-min.css – 0.2kbgrids-min.css – 2.4kb
6 HTTP requests – 27.2kb
First Aid remedies:
– Use the minified YUI versions – Cut down on included YUI
components by using the combined component includes.
yahoo-dom-event.js – 24.1kbreset-fonts-grids.css – 3.1kb
2 HTTP requests – 27.2kb
First Aid remedies:
– Use the minified YUI versions – Cut down on included YUI
components by using the combined component includes.
– Use the hosted YUI versions.
This is all packing and level crunching.
What we really want is...
On-demand delivery
Why is that needed?
Use cases:
Use cases:
– We don’t want to make users load things they don’t need.
Use cases:
– We don’t want to make users load things they don’t need.
– Distribution (badges, banners) works a lot better if it is one <script> and not 3.
Use cases:
– We don’t want to make users load things they don’t need.
– Distribution (badges, banners) works a lot better if it is one <script> and not 3.
– We can offer implementers to trigger extra functionality with markup:
Use cases:
– We don’t want to make users load things they don’t need.
– Distribution (badges, banners) works a lot better if it is one <script> and not 3.
– We can offer implementers to trigger extra functionality with markup:
“add an ‘animated’ CSS class for smooth transitions”
Example?
<div class="flickrbadge"> <p><a
href="http://www.flickr.com/photos/11414938%40N00">
My latest photos on flickr</a>
</p> </div> <script src="flickrbadgeloader.js"></script>
http://icant.co.uk/sandbox/flickrbadgev2/
<div class="flickrbadge"> <p><a
href="http://www.flickr.com/photos/11414938%40N00">
My latest photos on flickr</a>
</p> </div> <script src="flickrbadgeloader.js"></script>
http://icant.co.uk/sandbox/flickrbadgev2/
<div class="flickrbadge"> <p><a
href="http://www.flickr.com/photos/11414938%40N00">
My latest photos on flickr</a>
</p> </div> <script src="flickrbadgeloader.js"></script>
http://icant.co.uk/sandbox/flickrbadgev2/
How?
Supercool Solution:
The YUI Loader
http://developer.yahoo.com/yui/yuiloader
YUI Loader:
YUI Loader:
– Knows about dependencies
YUI Loader:
– Knows about dependencies – Automatically gets the newest
hosted versions
YUI Loader:
– Knows about dependencies – Automatically gets the newest
hosted versions– Works without yahoo.js
YUI Loader:
– Knows about dependencies – Automatically gets the newest
hosted versions– Works without yahoo.js– Extendable with non-YUI
components(!)
<script src="http://yui.yahooapis.com/2.3.1/build/yuiloader/yuiloader-beta-min.js"></script>
<script>loader = new YAHOO.util.YUILoader();loader.require('calendar','tabview');loader.insert(function() {
// Your code});</script>
http://yuiblog.com/assets/pdf/cheatsheets/yuiloader.pdf
Other option – 11kb is too much!
Rolling your own
The YAHOO_config way
YUI has an often forgotten configuration setting in
YAHOO_config.
YUI has an often forgotten configuration setting in
YAHOO_config.
http://developer.yahoo.com/yui/yahoo/#config
YUI has an often forgotten configuration setting in
YAHOO_config.
http://developer.yahoo.com/yui/yahoo/#configNow with more AWESOME!
It allows you to define a listener function that gets notified every time a YUI
component is loaded.
<script>function snitch(component){
console.log('can has YUI ' + component.name);
};YAHOO_config = {
listener:snitch};</script><script src="http://yui.yahooapis.com/2.3.1/build/yahoo/yahoo-min.js"></script><script src="http://yui.yahooapis.com/2.3.1/build/event/event-min.js"></script>
Using this in conjunction with your scripts and repeat calls
of the “snitch” function allows you to dynamically
include the YUI.
var myScript = function(){// other code function addScript(url){
var s = document.createElement('script');s.setAttribute('type', 'text/javascript');s.setAttribute('src', url);document.getElementsByTagName('head')[0].appendChild(s);
};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {
if(o.name === 'yahoo-dom-event'){ // YUI is ready}
};};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code function addScript(url){
var s = document.createElement('script');s.setAttribute('type', 'text/javascript');s.setAttribute('src', url);document.getElementsByTagName('head')[0].appendChild(s);
};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {
if(o.name === 'yahoo-dom-event'){ // YUI is ready}
};};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code function addScript(url){
var s = document.createElement('script');s.setAttribute('type', 'text/javascript');s.setAttribute('src', url);document.getElementsByTagName('head')[0].appendChild(s);
};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {
if(o.name === 'yahoo-dom-event'){ // YUI is ready}
};};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ // YUI is ready
}};
};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
You can extend that to load different YUI components one
after the other.
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
if(typeof o === 'undefined'){var APIurl = 'http://yui.yahooapis.com/2.3.1/' +
'build/yahoo-dom-event/' + 'yahoo-dom-event.js';
addScript(APIurl);} else {if(o.name === 'yahoo-dom-event'){ var url = 'http://yui.yahooapis.com/2.3.1/' +
'build/animation/' + 'animation-min.js';
addScript(url);}
};};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
var myScript = function(){// other code
+ function addScript(url){};function YUIready(o){
+ if(typeof o === 'undefined'){} else {if(o.name === 'yahoo-dom-event'){ var url = 'http://yui.yahooapis.com/2.3.1/' +
'build/animation/' + 'animation-min.js';
addScript(url);};if(o.name === 'animation'){
// done …};
};};YUIready();return { YUIready:YUIready };
}();YAHOO_config = { listener:myScript.YUIready };
You can also make it dependent on classes or IDs
used in the document, or configuration options of your main script and many more
things.
Have fun!
Thanks!