我应该将我的javascript分成多个文件吗?

Pet*_*erg 38 html javascript

我习惯使用Java,其中(我们知道)每个对象都在自己的文件中定义(一般来说).我喜欢这个.我认为它使代码更易于使用和管理.

我开始使用javascript,我发现自己想要为单个页面上使用的不同脚本使用单独的文件.我现在只限于几个.js文件,因为我担心如果我使用的不止于此,我将来会因为我目前无法预见的事情而感到不便.也许循环引用?

简而言之,将我的脚本分成多个文件是不好的做法吗?

Nor*_*ard 25

这里有很多正确的答案,具体取决于您的应用程序的大小以及您将其交付给谁(由谁,我的意思是预期的设备等),以及您可以在服务器端做多少工作以确保你的目标是正确的设备(对于大多数非企业凡人来说,这仍然是100%可行的很长的路要走).

构建应用程序时,"类"可以快乐地驻留在自己的文件中.
在跨文件拆分应用程序时,或者在处理具有过多假设的构造函数的类时(比如实例化其他类),循环引用或死端引用一个很大的问题.
有多种模式可以解决这个问题,但最好的模式当然是让你的应用程序考虑到DI/IoC,这样就不会发生循环引用.
您还可以查看require.js或其他依赖项加载器.您需要获得的复杂程度取决于您的应用程序的大小,以及您希望所有内容的私密程度.

在为您的应用程序提供服务时,服务JS的基线是连接您需要的所有脚本(如果您要实例化假定存在其他内容的内容,则按正确顺序连接),并将它们作为一个文件提供给底层.这页纸.

但这是基线.
其他方法可能包括"延迟/延迟"加载.
加载使页面正常工作所需的所有内容.
同时,如果您的applet或小部件在页面加载时不需要100%的功能,事实上,它们需要用户交互,或者在执行任何操作之前需要时间延迟,那么为这些加载脚本小部件延迟事件.在用户点击选项卡上的mousedown的位置加载选项卡式窗口小部件的脚本.现在你只加载了你需要的脚本,并且仅在需要时加载,并且没有人会真正注意到下载中的微小延迟.

将此与尝试在一个文件中填充40,000行应用程序的人进行比较.
只有一个HTTP请求,只有一个下载,但解析/编译时间现在变成了一秒钟的显着部分.

当然,延迟加载不是将每个类留在自己的文件中的借口.
此时,您应该将它们一起打包到模块中,并提供将运行整个小部件/小程序/任何内容的文件(除非有其他逻辑位置,直到以后才需要功能,并且它隐藏在进一步的交互之后) ).

您也可以将这些模块加载到计时器上.
预先加载基线应用程序内容(再次在页面底部,在一个文件中),然后设置超时半秒左右,并加载其他JS文件.
您现在不会妨碍页面操作或用户移动的能力.这当然是最重要的部分.

  • 我做到了.当涉及到没有简单答案的问题时,答案就是我的答案. (2认同)

Dav*_*ave 22

由于下载时间的原因,您应该始终尝试将脚本设置为单个大文件.但是,如果你使用minifier(你应该),他们可以将多个源文件合并为一个.因此,您可以继续处理多个文件,然后将它们缩小为单个文件以进行分发.

主要的例外是jQuery之类的公共库,你应该总是从公共CDN加载(更有可能是用户已经加载了它们,所以不需要再加载它们).如果您确实使用公共CDN,那么如果失败则始终从您自己的服务器加载后备.

正如评论中所指出的,真实的故事有点复杂;

可以同步(<script src="blah"></script>)或异步(s=document.createElement('script');s.async=true;...)加载脚本.同步脚本会阻止加载其他资源,直到它们加载完毕.例如:

<script src="a.js"></script>
<script src="b.js"></script>
Run Code Online (Sandbox Code Playgroud)

将请求a.js,等待它加载,然后加载b.js. 在这种情况下,将a.js与b.js结合起来并让它们一举加载显然会更好.

类似地,如果a.js具有加载b.js的代码,无论它们是否异步,您都将具有相同的情况.

但是,如果您同时加载它们异步加载它们,并且取决于客户端与服务器的连接状态,以及一系列只能通过分析确定的注意事项,它可以更快.

(function(d){
    var s=d.getElementsByTagName('script')[0],f=d.createElement('script');
    f.type='text/javascript';
    f.async=true;
    f.src='a.js';
    s.parentNode.insertBefore(f,s);
    f=d.createElement('script');
    f.type='text/javascript';
    f.async=true;
    f.src='b.js';
    s.parentNode.insertBefore(f,s);
})(document)
Run Code Online (Sandbox Code Playgroud)

它要复杂得多,但会加载a.js和b.js而不会互相阻塞或其他任何东西.最终async将正确支持该属性,并且您将能够像同步加载一样轻松地执行此操作.最终.