使用ES6导入加载特定名称比导入名称空间更快吗?

时间:2017-08-17 12:46:30

标签: javascript ecmascript-6 bundling-and-minification es6-modules

我发现至少有两种方法可以从像Ramda这样的模块导入函数。可能还有一些方法可以做一些非常类似的事情,比如const R = require('ramda');

选项1是导入某些功能:

import { cond, T, always, curry, compose } from 'ramda';

选项2是导入整个模块,如:

import * as R from "ramda";

我更愿意引用调用函数的模块,如下所示:

R.T();

但如果使用第二个选项,它是否会引入每个Ramda函数,而不仅仅是我工作的模块中使用的函数?如果使用选项2,是否会对实际内存使用或带宽使用产生影响? 有可能以某种方式这样做:

// invalid syntax below:
import R { cond, T, always, curry, compose } from 'ramda';
R.T();

我的问题与此问题有点相关,但它有点不同 import R (ramda) into typescript .ts file

2 个答案:

答案 0 :(得分:9)

TL; DR :没关系。

import * as … from 'ramda';
import { … } from 'ramda';
默认情况下

两者总是引入完整的Ramda模块及其所有依赖项。将运行模块内的所有代码,并且使用哪种语法来引用导出的绑定并不重要。无论您使用命名导入还是命名空间导入都归结为完全偏好。

什么可以减少要下载的文件大小和使用的内存是静态分析。在评估模块之后,引擎可以垃圾收集那些从无处引用的绑定。模块命名空间对象可能会使这一点变得更难,因为任何有权访问该对象的人都可以访问所有导出。但是仍然以某种方式指定这些对象(作为不可变的)以允许对它们的使用进行静态分析,并且如果您使用它们的唯一事情是具有常量名称的属性访问,则引擎应该利用这一事实。

任何大小优化都需要猜测模块的哪些部分需要评估,哪些部分不需要,并且在模块捆绑器中发生(例如RollupWebPack)。这称为 Tree Shaking ,在不需要时删除部分代码和整个依赖项(由导入的任何内容使用)。它应该能够检测您正在使用哪些导入而不管导入样式,尽管在使用命名空间对象执行异常操作时可能需要挽救(例如循环它或使用动态属性访问)。

要了解您的捆绑商可以做出的确切猜测,请联系其文档。

答案 1 :(得分:1)

@Bergi在他的评论中是正确的,我认为应该是答案。我还想指出,你总是可以在Babel中尝试一下,看看它编写的内容:click here to see what an example destructuring actually does

所以基本上即使你只从模块中构造一个函数,也需要整个模块。在我给出的Babel例子中,我刚从'反应中提取了组件。模块,但编译的代码实际上只需要整个事情。 :)