现在很多同学们都在代码里模拟YUI3实现JavaScript异步模块化加载,也就是一个add,一个use..
YUI3里对模块的加载是串行模式,当没有combo配合时,看起来很不美观.
今天army8735同学提到这个事儿,发现还真是很多同学注意到了这一点.kissy本身的add use就是并行,也有同学对YUI3做了改进.
而进来我正在开发kissylite,是kissy的一个支持有限方法的子集,目标是用1.5k代码支持包管理和模块化管理,也遇到了这个问题.不如拿出来一起讨论.
我觉得kissy和yui3的问题是模块必须先注册,这样扩展性有一定的局限.
kissylite引入了包的概念,每一个包对应一个codebase,通过模块名就完全确定js所在路径.
那么在一个包内新增了模块之后,种子文件是不需要修改即可直接使用的.
这样增加循环依赖的风险a->b b->c c->a..
虽然这样循环了明显是程序逻辑错误,但是如果不加以防范,合作开发,多次上线,死循环漏到线上那打击是致命的..
我的解决办法很土..在env中有一个对象记录x=模块依赖哪些,又支持哪些..当出现x依赖x的时候就抛一个error出来好了.
以a->b b->c c->a为例use("a")时:
首先载入a,Env中:
依赖关系方面a->b,
支持关系方面b->a
然后载入b,Env中:
依赖关系方面:b->c,在通过上面的支持关系可以得到a同样依赖c,即a->b,c
支持关系方面:c->b;a,b->a
最后载入c,Env中:
依赖关系方面:c->a,再通过现有的支持关系能得到a->b,c,a 矛盾出现a依赖自己,报个错吧:循环依赖.
这种算法效率是很低的,但是先粗暴的实现一下用着,每次add可能都要访问相关依赖关系对象和支持关系对象,毕竟kissylite目标是给页面中的广告,这类小应用的,模块不会太多.算抛砖吧,求更好的算法.
另一方面这里看到a b c的加载是串行的,在开发完成后,每次use可以自动给出一个use的并行优化方案.
比如use("a"),在use成功后,可以控制台log一下,为了更好的并行加载模块,你应该use("a,b,c")..这样就可以边开发,边优化.
kissylite还解决了一个问题,就是add的时候永远不attach.
steve blog:Evolution of Script Loading给出的mobile上js加载方案,看到代码从按需加载进化到了按需执行的阶段.
对于模块化js简单一些,只要不先attach,只是一个单纯简单的add,耗费的精力少的多了.
大家可能担心use时候attach是不是慢了些,这个同样可以边开发边优化.
在开发一个页面,可以把常用的功能都跑一边,Env中包含你所有使用过的包.
那么就可以在domready后,不忙的时候把这些先use一遍...
这就有点
facebook primer的意思了,domready之前按需执行,domready之后选择性预热.
这里也说说异步执行单元的串行和并行.
这个老道正好在velocity china提到.
异步执行单元:asyncUnit(args,callback).所有可能需要等待一段时间才能收到结果的函数都可以叫异步单元.比如getScript(url,callback),use(mods,callback),还有一些动画回调,都是异步执行单元.
我们常常遇到很多异步执行单元,比如use(mods)这个场景.
按程序的业务逻辑,如果这些异步单元需要串行,则会遇到多层复杂的callback嵌套.
a(a1,function(resA){
b(b1,function(resB){
c(c1,function(resC){
///your code
})
})
})
这种代码不美观,越向内运行时scope链越长,性能也不好.
而按照程序业务逻辑,如果多个异步单元需要并行,则会遇到每次手动监测其他单元执行是否完成的情况
a(a1,function(resA){
window.resA = resA
if(window.resB){
c();
}
});
b(b1,function(resB){
window.resB = resB
if(window.resA){
c();
}
})
function c(){
//your code run after resA & resB returend
}
这种代码同样不美观,通过写死判断条件if(resA/B)每次手动检查其他相关异步单元执行情况.
kissylite增加了方法multiAsync(asyncers,callback),因为use时并发的情况较多,先解决并发这个问题,计划再增加一个参数,解决串行异步单元的问题..
最后附一下kissylite的readme,以及googlecode上临时预览地址:
http://tbad.googlecode.com/svn/trunk/kslite/testcase/test_loader.html
kslite为kissy的仅支持有限方法的子集:
这些方法包括log,mix,clone,extend,add,use,getScript,substitute
kslite为所在页面引入KSLITE全局对象.
相比于kissy,发生变化的方法如下:
add:任何时候只add,不attach.
use:不用add即可直接use,详见下面的包和模块管理.
包和模块管理:
模块名由包名,路径,文件名.三部分构成
如{packagename}-{path_0}-...-{path_n}-{filename}
包类似*.jar,每个包对应一个codebase即classesroot.在S.config.lt_pkgs中配置
是一个http地址,如果没有则以为kslite.js所在地址为base.
比如:
S.Config.lt_pkgs={
inf:"http://a.alimama.cn/kslite/",
test:"http://demo.taobao.com/tbad/kslite"
}
模块"inf-a"对应地址 http://a.alimama.cn/kslite/inf/a.js
模块"test-t-1"对应地址 http://demo.taobao.com/tbad/kslite/test/t/1.js
这样根据模块名称即可定位模块地址,所以不需要add预先注册模块即可直接use.
add不执行attach.只有第一次use的时候才执行attach.
add同样支持require.可以在载入js后根据require串行加载更多模块.(已处理循环引用风险,办法很土.)
暂时不支持use外部JS文件,如use("jquery.js");
性能方面考虑:
这种模式只要use中包含的模块足够,满足所有依赖,则可以保证所有模块并行load,否则可能存在串行情况.
开发时使用小模块模式,每一个正式产出,比如生成广告投放用inf.js,广告展现用showad.js应该手动combo.
因为在use时会按照require顺序attach,所以手动combo的代码不需要关心模块间顺序.
其他配置项:
kslite相关配置项,在局部变量kslite_config中,之后mix入S.Config
lt_b:kslite的base,推荐每个产出写死一个kslite的base地址,而不是通过currentScript获得.因为kslite不一定作为<script>节点静态引入
lt_pkgs:包路径信息,如上.
lt_t:时间戳比如20101129.js
lt_v:版本 如1.1.5 计划沿用kissy版本.
关于与kissy兼容性:
在页面存在同一版本的Kissy实例时,S.app("KSLITE")构建.
同时根据当前kissy的add模式,需要额外生成一段代码,将所需模块预先注册一下.
分享到:
相关推荐
- 缺点:执行顺序不可控,可能影响依赖关系;如果脚本处理时间过长,仍可能阻塞浏览器。 5. **最佳实践**: - 将关键路径脚本放在`<head>`中,使用`defer`属性确保执行顺序。 - 非关键路径的脚本(如分析代码、...
在Unity3D游戏开发中,异步加载(Asynchronous Loading)是提高用户体验的关键技术之一,尤其是在处理大型场景或大量资源时。本项目提供了一个简洁且漂亮的加载画面,旨在帮助Unity3D学者理解和实现游戏资源的高效...
**jQuery 异步加载页面详解** 在Web开发中,异步加载页面是一种常见的优化技术,它允许我们在不刷新整个页面的情况下动态地加载新的内容。jQuery,一个强大的JavaScript库,提供了丰富的API来实现这一功能,使得...
具体的模块注册和配置信息则放在如`app.config.js`、`oclazyload.config.js`、`route.config.js`等配置文件中。 4. 示例代码解析: 在提供的代码片段中,首先定义了一个标准的HTML文档结构,使用`...
4. **依赖管理**:如果JS文件之间存在依赖关系,`JSLoader`会按照依赖顺序加载,确保依赖的JS先加载完成。 5. **通知主程序**:所有JS文件加载完毕后,`JSLoader`会触发一个全局事件或调用预设的回调函数,以便...
这主要涉及到JavaScript的异步编程和资源管理,特别是对于大型应用或者高流量网站,有效地加载和管理资源可以显著提高用户体验。以下是对标题和描述中涉及的知识点的详细解释: 1. **异步加载**: 异步加载是指在...
3. 图片压缩:在加载图片时,可以预先设定合适的大小和质量,减少内存占用,提高加载速度。 4. 占位符与错误图:在图片加载过程中,显示占位符,加载失败时显示错误图片,提供更好的用户体验。 5. 懒加载:只在列表...
在Cocos2d-x游戏开发中,资源管理是至关重要的,特别是对于大型或者资源密集型的游戏,异步加载资源能够显著提升用户体验,避免因等待资源加载而造成的卡顿。本篇将深入探讨如何利用Cocos2d-x和Boost库实现多线程...
考虑到有些模块无需在启动时载入,因此modJS提供了可以在运行时异步加载模块的接口:require.async (names, onload, onerror)names可以是一个模块名,或者是数组形式的模块名列表。当所有都加载都完成时,onload被...
在Unity3D游戏开发中,异步加载是提高游戏性能和用户体验的重要技术。它允许游戏在不阻塞主线程的情况下加载资源或场景,使得玩家在等待加载的过程中仍能进行游戏或者看到进度条更新,从而避免了游戏突然卡顿或者长...
- **内核接口扩展**:内核提供扩展接口,允许模块注册延迟加载回调函数。当模块需要时,内核调用回调函数进行加载。 通过以上对内核模块动态加载原理、优化策略及其实现方法的详细介绍,我们可以看到,内核模块动态...
该系统旨在通过监控所有可能的内核模块加载接口,并根据预先设定的保护域和用户验证来控制内核模块的加载过程,从而提高操作系统的安全性和稳定性。 #### 内核模块加载的安全隐患分析 Windows NT系统因其强大的...
在实际开发中,我们需要结合使用这些技术,根据项目需求选择合适的图片异步加载和缓存策略。例如,可以先使用Service Worker预加载首屏图片,然后使用Intersection Observer进行懒加载其他图片,并利用Cache API或...
在网页设计和开发中,"gallery异步加载图片"是一个重要的技术实践,它涉及到用户体验优化、性能提升以及资源管理等多个方面。"Gallery Demo"可能是某个JavaScript库或框架的一个实例,用于展示如何在图像画廊中实现...
在Android开发中,...通过合理配置预加载策略、使用LoaderManager和异步加载机制,我们可以提升应用性能,避免因一次性加载大量数据而引发的性能问题。同时,结合第三方库如XListView,可以进一步优化用户体验。
因此,采用异步加载(Async Load)策略,用户只会在需要时加载特定区域的数据,极大地提升了加载速度和用户体验。 异步加载在zTree中的实现通常涉及到以下几个关键步骤: 1. **初始化zTree**:在HTML页面(如tree....
模块内部可以通过`define`函数来定义其依赖和其他模块的关系。例如: ```javascript // 定义模块 seajs.use('./module.js', function(module) { // 在这里使用module模块 }); // module.js define(function...
在IT行业中,异步编程、线程池和线程管理是优化应用程序性能和响应速度的关键技术,尤其是在处理网络请求如加载图片这样的IO密集型任务时。让我们深入探讨这些概念及其在实际应用中的重要性。 首先,异步编程是一种...
Unity-ImageLoader是一款专为Unity游戏引擎设计的图片异步加载库,主要目的是优化游戏性能,提高用户体验。在Unity中,直接加载大图或者大量的图片可能会导致应用卡顿,因此异步加载技术变得尤为重要。这款库是基于...