资讯专栏INFORMATION COLUMN

sea.js的同步魔法

cloud / 349人阅读

摘要:写法加载完后,得到的执行结果作为参数传入了回调函数写法预加载了执行模块,并得到结果赋值给调用模块提供的方法从这一点上来看,两者在性能上并没有太多差异。

前些时间也是想写点关于CMD模块规范的文字,以便帮助自己理解。今天看到一篇知乎回答,算是给了我一点启发。

同步写法却不阻塞?

先上一个sea.js很经典的模块写法:

// 定义一个模块
define(function(require, exports, module) {
  // 加载jquery模块
  var $ = require("jquery");
  // 直接使用模块里的方法
  $("#header").hide();
});

按道理加载模块,就是需要等jquery.js加载完毕才能使用,应该是一个异步的过程,为什么可以写成同步的形式呢?这是用了什么黑科技?

原来作者玉伯大佬用了一个小魔法来“欺骗”我们。而卢勃大神在知乎给了一个很精彩的解释,这里直接分享下:

也就是说,require.jssea.js都是在执行模块前预加载了依赖的模块,并没有比require.js显得更“懒加载”,只是所依赖模块的代码执行时机不同。require.js加载时执行,而sea.js是使用时执行。

其实从代码的写法也看得出来,require.js的依赖模块在加载后便有了执行结果,并作为回调函数的实参传入。

reuiqre.js写法:

// 加载完jquery.js后,得到的执行结果$作为参数传入了回调函数
define(["jquery"], function($) {
  $("#header").hide();
});

sea.js写法:

// 预加载了jquery.js
define(function(require, exports, module) {
  // 执行jquery.js模块,并得到结果赋值给$
  var $ = require("jquery");
  // 调用jquery.js模块提供的方法
  $("#header").hide();
});

从这一点上来看,两者在性能上并没有太多差异。因为最影响页面渲染速度的当然是资源的加载速度,既然都是预加载,那么加载模块资源的耗时是一样的(网络情况相同时)。

而模块代码的执行时机并没有那么影响性能(除非你的模块太大),现在的js引擎如V8引擎足够强,没什么压力。

懒加载是否存在?

懒加载是存在的。我刚才说的sea.js并没有比require.js更显得“懒加载”是指模块加载的时机上两者是一致的,都是预先加载,而不是说不能懒加载。

比如说,有一个模块,页面渲染时,我不需要加载使用,但是在做了某种交互时(比如点了按钮),才需要加载使用,这个时候“懒加载”的作用就体现了。下面以require.js举个实例:

require.config({
    baseUrl: "./assets/js/",
    paths: {
        modulea: "module-a",
        moduleb: "module-b"
    }
})

require(["modulea"], function(modulea) {
    var btnNode = document.querySelector("#btn-load");
    var node1 = document.createElement("span");
    node1.innerText = "模块A已经加载!"
    btnNode.insertAdjacentElement("beforebegin",  node1)
    btnNode.addEventListener("click", function() {
        require(["moduleb"], function(moduleb) {
            var node2 = document.createElement("span");
            node2.innerText = "模块B已经加载!"
            btnNode.insertAdjacentElement("afterend",  node2)
        });
    })
});

页面渲染时只加载模块A

点击按钮后加载模块B

总结

虽然AMDCMD两种思想有一些差异,但都不失为一种优秀的模块化方案,为大佬们打call!

首发链接

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110322.html

相关文章

  • 前端模块化之AMD/require.js、CMD/sea.js

    摘要:代码地址模块化的主要区别此前年前前前前前端模块化,主流的就是,支持的二者都可以用为什么模块化一直以来,前端开发的痛点之一就是代码复用职责划分问题,兼容性比如等新语法的支持组件化代码压缩等不在本文讨论范围。showImg(https://user-gold-cdn.xitu.io/2019/5/22/16adee75f360801a); 前言 请注意,现在是2019/05/22,这!不!是!坟...

    buildupchao 评论0 收藏0
  • 浅谈 JavaScript 模块化编程

    摘要:与在模块化编程的世界中,有两个规范不得不提,它们分别是和。所有依赖于某个模块的代码全部移到模块加载语句的回调函数中去。的语句接受两个参数在回调函数中,可以通过变量引用模块。回调函数的返回值就是当前对象的导出值。 JavaScript本身不是一种模块化语言,设计者在创造JavaScript之初应该也没有想到这么一个脚本语言的作用领域会越来越大。以前一个页面的JS代码再多也不会多到哪儿去,...

    wdzgege 评论0 收藏0
  • 阅读sea.js源码小结

    摘要:依赖信息是一个数组,比如上面的依赖数组是源码如下是利用正则解析依赖的一个函数时间出发函数主要看这个部分注释是防止拷贝该时间的回调函数,防止修改,困惑了一下。对的赋值需要同步执行,不能放在回调函数里。 sea.js想解决的问题 恼人的命名冲突 烦琐的文件依赖 对应带来的好处 Sea.js 带来的两大好处: 通过 exports 暴露接口。这意味着不需要命名空间了,更不需要全局变量。...

    chavesgu 评论0 收藏0
  • 前端模块化详解(完整版)

    摘要:二模块化规范概述应用由模块组成,采用模块规范。模块化语法命令用于规定模块的对外接口,命令用于输入其他模块提供的功能。 前言 在JavaScript发展初期就是为了实现简单的页面交互逻辑,寥寥数语即可;如今CPU、浏览器性能得到了极大的提升,很多页面逻辑迁移到了客户端(表单验证等),随着web2.0时代的到来,Ajax技术得到广泛应用,jQuery等前端库层出不穷,前端代码日益膨胀,此时...

    Sanchi 评论0 收藏0
  • 前端模块化详解(完整版)

    摘要:二模块化规范概述应用由模块组成,采用模块规范。模块化语法命令用于规定模块的对外接口,命令用于输入其他模块提供的功能。 前言 在JavaScript发展初期就是为了实现简单的页面交互逻辑,寥寥数语即可;如今CPU、浏览器性能得到了极大的提升,很多页面逻辑迁移到了客户端(表单验证等),随着web2.0时代的到来,Ajax技术得到广泛应用,jQuery等前端库层出不穷,前端代码日益膨胀,此时...

    Pines_Cheng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<