为何commonjs加载是同步的,会造成堵塞,那为什么还继续用呢

212 阅读4分钟

要想搞懂这个问题首先想了解一下,前端模块化有哪些解决方案

CommonJS

语法:CommonJS 使用 requiremodule.exports 语法。

特点

  • 主要用于服务器端 JavaScript(Node.js)。
  • 模块加载是同步的,适用于后端环境。
  • 模块在运行时加载,因此不适用于浏览器原生环境。
  • 常用于构建工具和服务器端应用程序。

ES6 模块

语法:ES6 模块使用 importexport 语法,是浏览器原生支持的官方模块系统。

特点

  • 适用于现代浏览器,不需要额外的构建步骤。
  • 模块加载是静态的,可以在编译时分析模块依赖。
  • 可以通过构建工具(如 Babel 和 Webpack)将 ES6 模块转译为其他模块规范,以支持老旧浏览器。
  • 适用于构建大型前端应用程序。

AMD(异步模块定义)

语法:使用 definerequire 函数。

特点

  • 用于浏览器端,支持异步加载模块。
  • 模块加载是异步的,适用于需要延迟加载模块的情况。
  • RequireJS 是一个常见的 AMD 实现。
  • 适用于构建大型前端应用程序,其中延迟加载可以提高性能。

CMD (CommonJS Modules)

语法:CMD 使用 definerequire 函数。

特点

  • 主要用于浏览器端的 JavaScript 模块化。
  • 模块加载是延迟执行的,适用于需要异步加载模块的情况。
  • 可以与 AMD 规范一起使用,以满足浏览器端模块化开发的需求。
  • 通常用于浏览器端,特别在需要按需加载模块的情况下。

这些不同的规范和解决方案各自有其适用场景和优点,开发人员可以根据项目需求和目标平台选择适合的模块化规范。综合使用这些规范也是常见的实践,以满足不同项目的需要。

CommonJS 同步加载问题

现在让我们回到 CommonJS 的同步加载问题。CommonJS 模块加载是同步的,这意味着模块的加载和执行都在主线程中同步进行。这种同步加载方式在服务器端环境中通常不会导致严重问题,因为服务器通常只服务于少量并发请求,而同步加载可以简化模块之间的依赖关系管理。

然而,在浏览器端,情况就不同了。浏览器通常需要同时处理多个任务,包括用户界面渲染、用户交互响应等。如果在浏览器中使用同步加载的 CommonJS 模块,可能会导致以下问题:

  1. 阻塞UI:如果一个模块的加载时间较长,它可能会导致用户界面被冻结,用户无法与网页进行交互,因为浏览器主线程被模块加载阻塞。
  2. 性能问题:同步加载多个模块可能会导致性能下降,因为模块的加载和执行都是同步进行的,浏览器无法并行加载其他资源。
  3. 不利于大型应用程序:在大型前端应用程序中,大量的同步模块加载可能会导致代码的加载时间延长,影响用户体验。

尽管 CommonJS 的同步加载可能存在这些问题,它仍然广泛使用,主要因为它在服务器端开发中具有重要的作用,并且它的模块系统相对简单且易于理解。在浏览器端,为了解决同步加载问题,前端开发社区已经采用了其他模块化方案,如 ES6 模块和 AMD,它们支持异步加载,有助于提高性能和用户体验。

总之,CommonJS 模块加载是同步的,可能导致阻塞,但它在服务器端仍然有价值。在浏览器端,开发者通常倾向于使用异步加载的模块化方案以提高性能和用户体验。不同的规范和解决方案都有各自的优缺点,根据项目需求和目标平台进行选择非常重要。希望这些信息能够帮助您更好地理解前端模块化和不同规范之间的差异。