🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 看东西要仔细,关键的地方一个字不看清楚就会意淫差之千里 sea.js 的 CMD 推崇 as lazy as possible,并不是懒加载,而是懒执行(懒解析) > 注意我这里说的是执行(真正运行define中的代码)模块, 而非加载(load文件)模块. 模块的加载都是并行的, 没有区别, 区别在于执行模块的时机, 或者说是解析. script加载后立即运行是没错,只不过是运行define,而不是运行define内的代码,请注意这点。 之前没看仔细,误读了sea.js的意思,还以为真是懒加载文件的,就和懒加载图片是一样的,真是自己一厢情愿的意淫的,呵呵,想多了。 * * * * * ### sea.js 可以看到b.js中的代码此时才执行。这样就真正实现了“就近书写,延迟执行“,不可谓不优雅。 如果你一定要挑出一点不爽的话,那就是b.js的预先下载了。你可能不太想一开始就下载好所有的资源,希望像requirejs那样,等点击按钮的时候再开始下载b.js。本着兼容并包的思想,seajs也实现了这一功能,提供require.async API,在点击按钮的时候,只需这样写: JavaScript var b = require.async('b'); b.hello(); var b = require.async('b'); b.hello(); b.js就不会在一开始的时候就加载了。这个API可以说是简单漂亮。 引自:[JavaScript 模块化历程 · Issue #6 · wqb2017/yctabs](https://github.com/wqb2017/yctabs/issues/6) ### 参考 [SeaJS 所为何](http://cyj.me/why-seajs/zh/) - [seajs与requirejs区别](http://zccst.iteye.com/blog/2084545) - [第三课:sea.js模块加载原理](http://www.cnblogs.com/chaojidan/p/4123980.html) - [seajs的CMD模式的优势以及使用 - chaojidan - 博客园](http://www.cnblogs.com/chaojidan/p/4147925.html) - [JS模块加载器加载原理是怎么样的? - 知乎](https://www.zhihu.com/question/21157540) - [Sea.js作者发布微博: 应该给 Sea.js 和 KISSY 也树一块墓碑了。 为啥啊?过时了吗?](https://www.zhihu.com/question/34756861) - [LABjs、RequireJS、SeaJS 哪个最好用?为什么? - 知乎](https://www.zhihu.com/question/20342350) > 大部分的页面不是Single Page Application,不需要依靠脚本来初始化页面。服务器返回的页面是立即可用的。也就是单页往往服务器返回的都不是立即可用的。请注意,体会这个用词。 - [让我们再聊聊浏览器资源加载优化](http://www.infoq.com/cn/articles/browser-resource-loading-optimization) [Hello Sea.js 深入浅出分析Sea.js模块机制](http://island205.github.io/HelloSea.js/) ### 扩展 >[info] 上文说过SeaJS会在html页面打开时通过静态分析,一次性下载所有需要的js文件,如果想要某个js文件在用到时才下载,可以使用require.async。 原来你说的懒并不是真正的懒加载啊? ```text 我之前还一直纠结: 到底是异步加载文件还是怎么的啊,都在绕着弯子,只谈想让别人知道的,而对于别人想知道的,文件加载方式,避而不谈,讳莫如深,避重就轻,还说什么没有明显的bug ``` 如果以服务端的模式去思考前端的模块化,文件加载,那是行不通的,因为服务端不用考虑网络IO,并且JS也不想PHP,并没有PHP那样可以在脚本执行的过程中直接引入其他文件的特性,所以以服务端的思维来看前端的模块化,就是不正确的。并且如果真的懒加载文件,那么页面解析执行的过程中,不断的请求加载JS文件,页面就会卡卡卡的,这样的用户体验谁受得了,所以直接拿S端的开发经验来给B端使用,这本身就是一件非常愚蠢的事情。(所以别老揪着懒加载这个问题不放,让自己纠结了) 浏览器端无法做到和服务端一样的依赖加载模式,因为浏览器端和服务端工作的方式不同 依赖都是以根为起点,在服务端,先加载根,遇到依赖的叶子,直接加载叶子。 而在浏览器端,还是以根为起点,如果先加载根,再遇到叶子加载叶子就行不通了,因为浏览器端的工作模式不像服务端,js也不是PHP,所以要处理好依赖关系,实现类似的加载,在浏览器端就必须首先分析出依赖树,然后从最末的叶子端依次往根的方向加载才行,也就是和服务端的加载顺序完全相反。 既然这样,那么浏览器端也就无法做到跟服务端一样的懒加载了,所以服务端的思维拿过来是够不能直接套用的。 其实sea.js也有真正的懒加载,`require.async()` 用到才加载,不过实际应用中不会大规模使用这种方式,而是更偏向于一次性静态分析加载所有的文件,因为浏览器环境的特性决定了越少的http请求越好,不能过度依赖网络IO,并且SPM依赖打包分析的工具也是将静态分析的结果一次性打包加载,关于这个问题我们已经在 [技术/思想的斗争](http://www.kancloud.cn/xiak/quanduan/279198)里面讨论过了。 本来浏览器端的依赖关系对加载顺序很重要,[script标签](http://www.kancloud.cn/xiak/quanduan/278616) 的顺序,因为JS没有PHP运行时动态加载包含文件的特性,所以这个加载顺序是很严格的,没严格按照依赖顺序加载就会出错的。比如依赖JQ的插件必须放在JQ的下面。 现在使用模块化工具后,js文件按照模块化的格式书写,定义在define函数里面,此时依赖关系完全的交给框架来处理了,所以忘了之前的标签顺序关系吧,使用框架就好了。 所以前端要实现模块化,依赖加载,依赖管理,加载顺序,就不是那么容易了,不是仅仅只处理好文件的加载,网络的IO就好了那么简单的。 这就是模块化规范,框架需要做的事了。 update:2017-8-4 18:33:18