javascript autoload
DESCRIPTION
TRANSCRIPT
JavaScript Autoload
2011-08
更好的组织你的 JavaScript�文件
拔赤 – F2E@Taobao
@jayliF2E & Translator
htt[p://[email protected]
http://ued.taobao.com/javascript http://jayli.github.com/jswebapps
ongoing�project
静态语言vs
动态语言
如何载入外部文件/包?
PHP
<?phpinlcude(‘config.php’);include(‘head.php’);include(‘sidebar.php’);include(‘main_content.php’);Include(‘sth_section.php’);
//other logic?>
C++
#include <fstream>#include <sstream>#include <time.h>#include <stdio.h>#include <string.h>
int main(int argc,char **argv){//main logic…
}
Python
import dump.logimport io.xmlimport io.jsonfrom bean import *From mod1 import *
# main logic…
PHP文件依赖
index.php
config.php
header.php
content.php
sitenav.php
channel.php
section.php
JavaScript�?
<script src=‘core.js’ /><script src=‘dom.js’ /><script src=‘util.js’ /><script src=‘selection.js’ /><script src=‘editor.js’ /><script>//main logic…
</script>
JavaScript�文件依赖 ?
editor.js
selection.js
plugin.js
editor‐util.js
dom.js
event.js
core.js
style.js
browser.js
JavaScript�Loader
YUI Loader
http://developer.yahoo.com/yui/3
Yepnope.js
http://yepnopejs.com
SeaJS
http://seajs.com
Loader.add({‘base’:{
path:’base.js’,requires:[‘dom’,’node’,’io’]
},‘pagination’:{
path:’pagination-v121.js’,requires:[‘page-skin’,’node’,’base’]
}//…
});
Loader.use(‘pagination’,‘dump’,function(Y){//main logic…
});
异步载入文件
Why�异步?
function getScript(url,callback){var el = $.createElement(‘script’);el.src = url;el.onload = function(){
callback();};document.head.appendChild(el);
}
除了html中的<script>标签JavaScript文件载入都是异步
并行 or�串行 ?
并行载入文件getScritp(‘file1.js’);getScript(‘file2.js’);getScript(‘file3.js’);…//main logic ?
getScritp(‘file1.js’,function(){getScript(‘file2.js’,function(){
…getScript(‘fileN.js’,function(){
//main logic…});
});});
串行载入文件
getScritp(‘file1.js’,‘file2.js’,‘file3.js’,…function(){
//main logic…}
);
可以这样串行!
yepnope([{load:[’file1.js’,’file2.js’]complete:function(){
//main logic…}
}]);
Yepnope.js�串行载入文件
有条件载入文件?
PHP<?php
if(condition1){include(‘file1.php’);
} else if (condition2){include(‘file2.php’);
} else {include(‘file3.php’);
}
//main logic…
?>
Yepnope.js
yepnope([{test:condition,yep:’file1.js’, // condition == truenope:’file2.js’,// condition == falsecomplete:function(){
//main logic…}
}]);
任意条件if(condition1){getScript(‘file1.js’,foo);
}else if(condition2){getScript(‘file2.js’,foo);
}else{getScript(‘file3.js’,foo);
}
function foo(){ //主逻辑必须写入回调中
//main logic…}
可不可以不写回调?
CommonJS ∈�ServerSide JS
define(function(require){
require(‘./mod1’); //阻塞式载入
require(‘./mod2’); //阻塞式载入
//main logic…});
CommonJS ∈�Client Side�JS�?
http://seajs.com/docs/demo/calculator/
SeaJS Demo�- Calculator
JavaScript�文件依赖
init.js
stdin.js
stdout.js
jquery.js
calculate.js
math.js
define(function(require){
require(‘./stdin’); //输入的逻辑
require(‘./stdout’); //输出的逻辑
});
init.js
stdin.js
define(function(require){
require(‘./jquery’); //载入jQueryrequire(‘./calculator’); //计算器的逻辑
});
JavaScript�加载过程
闭包的重要性
http://seajs.com/docs/commonjs-modules.html#why-wrapped
SeaJS 伪阻塞 (init.js)
define(function(require){return;require(‘./mod1’);require(‘./mod2’);
});
What�everGood�Idea�!
• 串行加载JavaScript文件• 统一的沙箱结构• 对沙箱逻辑的“预解析”• 动态加载JavaScript文件
Good�Idea�!
降低 JS�文件之间的耦合
Problem!
使用某个类的前提是必须知道它所在的模块/文件名称!
并手动载入模块/文件!
define(function(require){
require(‘./dom’); //必须手动引入文件?
DOM.get(‘#id’);});
define(function(require){require(‘./dom’);
//知道了方法名,何必再需知道文件名?
DOM.get(‘#id’);});
I�want�this!
CommonJS
文件名 =>�命名空间
<?phpfunction __autoload($class_name) {
if($class_name == ‘MyClass1’){require_once(‘MyClass1.php’);
}else if($class_name == ‘MyClass2’){require_once(‘MC2_v102.php’);
}}
$obj = new MyClass1();$obj2 = new MyClass2();
?>
function __autoload() { return {
'S.Carousel':'carousel.js', 'S.ColorPicker':'colorpicker-v1.js', 'S.Editor':'article.js'
}; }
autoload map
SandboxJS Demo�- autoload
http://jayli.github.com/sandbox/examples/autoload/test/mojo.html
<script src=“种子文件.js & 配置文件.js” /><script>Sandbox.ready(function(S){
// 旋转木马模块
S.Carousel.init(‘bid’);
//选择颜色模块
S.ColorPicker(‘cid’);
//编辑器
S.Editor(‘eid’,'淘宝UED'); });</script>
• 代码解耦更充分• 开发者记忆负担最低• 免除基础库升级更改文件名的麻烦• 享受动态语言编程• …
JavaScript�Autoload
Ok,开始享受编程?
Warning !!!
JavaScript�Autoload 的不足
• 串行加载JS�- 速度是个问题• 伪阻塞 - 客户端无“真”阻塞• 对包装器的支持不好(Wrap(dom))• 对链式调用支持不好
适用 JavaScript�Autoload 的场景
• 内部系统 – 对性能要求不高• Server�Side�JavaScript• 当你想要更纯粹的编程时• …
SeaJS - spm
YUI3 - configurator
CDN - Combo Handler
优化JS加载器的手段
Enjoy�it,�Just�for�fun~
ref
http://developer.yahoo.com/yui/3
http://yepnopejs.com
http://seajs.com
https://github.com/seajs/spm
https://github.com/jayli/sandbox
http://www.commonjs.org
http://cn.php.net/__autoload
@jayliF2E & Translator
htt[p://[email protected]