前些时间也是想写点关于CMD
模块规范的文字,以便帮助自己理解。今天看到一篇知乎回答,算是给了我一点启发。
同步写法却不阻塞?
先上一个sea.js
很经典的模块写法:
1 | // 定义一个模块 |
按道理加载模块,就是需要等jquery.js
加载完毕才能使用,应该是一个异步的过程,为什么可以写成同步的形式呢?这是用了什么黑科技?
原来作者玉伯大佬用了一个小魔法来“欺骗”我们。而卢勃大神在知乎给了一个很精彩的解释,这里直接分享下:
也就是说,require.js
和sea.js
都是在执行模块前预加载了依赖的模块,并没有比require.js
显得更“懒加载”,只是所依赖模块的代码执行时机不同。require.js
加载时执行,而sea.js
是使用时执行。
其实从代码的写法也看得出来,require.js
的依赖模块在加载后便有了执行结果,并作为回调函数的实参传入。
reuiqre.js
写法:
1 | // 加载完jquery.js后,得到的执行结果$作为参数传入了回调函数 |
sea.js
写法:
1 | // 预加载了jquery.js |
从这一点上来看,两者在性能上并没有太多差异。因为最影响页面渲染速度的当然是资源的加载速度,既然都是预加载,那么加载模块资源的耗时是一样的(网络情况相同时)。
而模块代码的执行时机并没有那么影响性能(除非你的模块太大),现在的js
引擎如V8
引擎足够强,没什么压力。
懒加载是否存在?
懒加载是存在的。我刚才说的sea.js
并没有比require.js
更显得“懒加载”是指模块加载的时机上两者是一致的,都是预先加载,而不是说不能懒加载。
比如说,有一个模块,页面渲染时,我不需要加载使用,但是在做了某种交互时(比如点了按钮),才需要加载使用,这个时候“懒加载”的作用就体现了。下面以require.js
举个实例:
1 | require.config({ |
页面渲染时只加载模块A
点击按钮后加载模块B
总结
虽然AMD
和CMD
两种思想有一些差异,但都不失为一种优秀的模块化方案,为大佬们打call!
扫一扫下方小程序码或搜索Tusi博客
,即刻阅读最新文章!