Why do concatenated RequireJS AMD modules need a loader?

南楼画角 提交于 2019-12-02 17:16:59

An AMD optimiser has the scope to optimise more than the number of files to be downloaded, it can also optimise the number of modules loaded in memory.

For example, if you have 10 modules and can optimise them to 1 file, then you have saved yourself 9 downloads.

If Page1 uses all 10 modules then that's great. But what if Page2 only uses 1? An AMD loader can delay the execution of the 'factory function' until a module is require'd. Therefore, Page2 only triggers a single 'factory function' to execute.

If each module consumes 100kb of memory upon being require'd, then an AMD framework that has runtime optimisation will also save us 900kb of memory on Page2.

An example of this could be an 'About Box' style dialog. Where the very execution of it is delayed until the very last second as it won't be accessed in 99% of cases. E.g. (in loose jQuery syntax):

aboutBoxBtn.click(function () {
    require(['aboutBox'], function (aboutBox) {
        aboutBox.show();
    }
});

You save the expense of creating the JS objects and DOM associated with the 'About Box' until you are sure it's necessary.

For more info, see Delay executing defines until first require for requirejs's take on this.

The only real benefit is if you use modules across sections so there's a benefit to caching modules independently.

I had the same need, so I created a simple AMD "compiler" for that purpose that does just that. You can get it at https://github.com/amitayh/amd-compiler

Please note that it has many features missing, but it does the job (at least for me). Feel free to contribute to the codebase.

In case you compile you code with require.js into a single large file for production, you can use almond.js to completely replace require.

Almond only handles the module references management not the loading itself which is no longer needed.

Be careful of the restrictions almond imposes in order to work

There is no reason why there couldn't be a build tool such as the one you propose.

The last time* I looked at the optimizer's output, it converted the modules to explicitly named modules, and then concatenated those together. It relied on require itself to make sure that the factory functions were called in the right order, and that the proper module objects were passed around. To build a tool like you want, you would have to explicitly linearize the modules -- not impossible, but a lot more work. That's probably why it hasn't been done.

I believe** that the optimizer has a feature to automatically include require itself (or almond) into the built file, so that you only have to have one download. That would be larger than the output of the build tool you want, but otherwise the same.

If there was a build tool that produced the kind of output you're asking for, It would have to be more careful, in case of the synchronous require, the use of exports instead of return, and any other CommonJS compatibility features.

*That was a few years ago. 2010, I think.

**But can't seem to find it right now.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!