我有兴趣听取有关如何在一个可能会看到高流量的大型Web应用程序项目中有效组织JavaScript(和jQuery)的意见。
与我有关的事情是:
让我们假设所有创作的JavaScript都保存在一个巨大的application.js
文件中,该文件又与所有外部库连接成一个服务器必须提供的单个js文件。这在服务器上应该是最有效的,因为它只需要提供一次,然后浏览器将为每个后续页面加载缓存它。
其中包含大量自定义jQuery函数,这些函数挂钩到选择器,如下所示:
$('#my_unique_selector').bellsAndWhistlesPlugin();
如果上面的选择器仅存在于几个页面上,那么使用在一个包中提供所有内容的方法意味着每个加载浏览器的页面都必须解析插件代码(不会被使用),并且然后解释bellsAndWhistlesPlugin()
方法,即使选择器找不到匹配项。
所以我想我的问题是,这种方法在什么时候变得低效?是否存在分裂JavaScript并且只提供每个页面所需的位的论据?或者我什么都不担心 - 浏览器能够处理大量冗余代码?
答案 0 :(得分:4)
您绝对不应该做的就是将所有JavaScript连接到一个文件中。如果您对代码库进行了更改,则会重新创建该文件并将其重新分发给每个访问者。 HTTP开销相当微不足道,因此除非你加载成百上千个独特的文件,否则加载20个不同的文件而不是加载1个大文件除了连接异常缓慢的用户(谁将等待大无论如何,它们都不会从HTTP开销中注意到额外的一两秒。
ToonMariner建议使用托管代码(尤其是Google Code repos)是一个很好的建议 - 它可以节省您托管文件的时间,它允许遇到该文件的用户利用缓存(提高明显的加载速度)您的网站),如果您进行更改,它将不会包含在您的连接文件中。即使你选择将整个应用程序保存在一个大文件中,你也应该考虑使用它,因为你可以避免打包jQuery,这可以节省50 + kb。
此外,您对解释bellsAndWhistlesPlugin()的担忧是正确的 - bellsAndWhistlesPlugin函数中的this
只是一个空列表(尽管我希望插件执行$(this).each调用迭代元素并且提前返回,因为没有元素......否则,您可能想要重新访问插件!)。您可以通过从完整的application.js文件中删除特定于页面的代码并将其放入内联< script>来消除此问题。页面本身的元素,无论如何都属于它,或者重写插件以使其在没有匹配元素的情况下提前返回。
只需确保为从/ js目录加载的资源启用缓存,并且您不会遇到重新加载库的问题 - 只有那些已更改的库。您可以使用Expires标头或Last-modified标头;除非人员重新加载或缓存已过期,否则Expires不一定会强制更新,Last-modified会为每个文件调用HTTP开销,这对于大量文件来说是个问题。您必须评估应用程序的权衡。
如果您真的,真的,对最高效率感兴趣,可以使用GWT重写您的应用程序。从技术上讲,这保证了最大的跨浏览器可移植性,最高的代码效率,消除了对jQuery库的依赖,将更快地执行,并生成更小的文件大小。我可能会在一个文件中添加,但是获取静态编译器以获得最高效率JavaScript的权衡是值得的...如果您愿意在GWT中重写整个内容。
你必须问自己的问题是:谁是我的普通用户?他/她有什么样的联系?我的应用需要在移动设备上运行吗?如果您的普通用户有快速连接,请不要担心 - 他们会以您选择的方式加载您的页面足够快。如果您需要使用移动设备,或者您的目标受众的连接速度较慢,请考虑缓存不经常更改的大型库并使用外部存储库(例如jQuery),然后将应用程序的其余部分打包到一个大文件中。移动设备和慢速互联网的HTTP开销足以保证这一点。
答案 1 :(得分:0)
我个人的方法是使用托管代码(我使用googles jquery repo)并将我的所有全局资产(javascript文件,css,css使用的图像)放在gzip文件中。
答案 2 :(得分:0)
如果$('#my_unique_selector')没有找到任何匹配项,则调用它的方法将发生零次。您仍在运行'#my_unique_selector'查询,但永远不会调用bellsAndWhistlesPlugin()。
答案 3 :(得分:0)
前几天我想发布一些与你的问题非常相似的内容,直到我偶然发现:
Is there a JavaScript MVC (micro-)framework? 虽然我确实看了一下javascriptMVC的文档但我没有时间完全去了它。听起来它需要重大改写才能开始......
我猜你在项目中尽可能早地尝试解决这些问题。