你把JavaScript放在哪里?

11
你是将JavaScript本地化到页面中,还是有一个主要的“application.js”文件或类似文件?
如果是后者,那么最佳实践是什么,以确保你的.js文件不会在错误的页面上执行?
编辑:通过JavaScript,我指的是你作为开发人员编写的自定义JavaScript,而不是JavaScript库。我无法想象有人会将jQuery源代码复制/粘贴到其页面中,但你永远不知道。
8个回答

10
将所有的js放在一个文件中可以提高性能(只有一个请求而不是多个)。如果你正在使用像Akamai这样的内容分发网络,它可以提高缓存命中率。此外,总是将内联的js放在页面底部(正好在body标签上面),因为它是同步执行的,可能会延迟页面的呈现。
是的,如果你正在使用的js文件之一也被托管在Google上,请确保使用那个文件。

非常好的建议!我们的应用程序已经形成了一个最佳实践,尽可能将JavaScript放入包含的JS文件中,因为我们预计高比例的用户将通过56K调制解调器拨入。 - Ogre Psalm33
谢谢!我认为对于大多数开发人员来说,把所有东西都放在一个文件中似乎是一种可怕的做法。但有时候性能胜过代码清洁度。 - Tim Merrifield

5
以下是我的“指南”。请注意,这些都不是正式的,只是看起来应该这么做。
所有共享的JS代码都存放在`SITE/javascripts`目录中,但它们以“层次结构”方式加载。
对于整个站点的内容(例如jquery或我的站点宽应用程序.js),站点宽布局(这将是ASP.net中的主页面)包括文件。`script`标签放在页面顶部。
还有“区域范围”的内容(例如仅在网站管理部分需要的js代码)。这些区域要么有一个公共布局(然后可以包含脚本标记),要么会呈现一个公共部分,该部分可以包含脚本标记。
对于不太共享的内容(例如我只需要在一些地方使用的库),则在这些HTML页面中单独放置`script`标记。脚本标记放在页面顶部。
对于仅与单个页面相关的内容,我只需编写内联javascript。我尽量让它靠近它的“目标”。例如,如果我有一个按钮的onclick js,则`script`标记将位于按钮下方。
对于没有目标的内联JS(例如`onload`事件),它放在页面底部。
那么,如何将某些内容放入本地化库或站点宽库?
- 第一次需要时,请编写内联代码。 - 下次需要时,请将内联代码提取到本地化库中。 - 如果您从大约3个或更多地方引用了本地化库中的某些代码,请将代码提取到区域范围库中。 - 如果需要从多个区域访问它,请将其提取到站点宽库中。
对于这种系统的常见抱怨是,最终会得到10或20个小JS文件,而2或3个较大的JS文件从网络角度来看会更好。但是,Rails和ASP.NET都具有处理将多个JS文件组合和缓存为一个或多个“超级”js文件的功能,以用于生产环境。
我建议使用此类功能,而不是牺牲实际源代码的质量/可读性。

同意。除了把所有内容都放在一个大文件中之外,还有其他提高性能的方法;特别是当几个页面只使用少量函数时(下载一个1MB文件真的比下载3个2KB文件更快吗?在对较小的文件进行GZIP压缩或缩小后呢?)。 - Max Lybbert

2

1

我尽量避免将javascript函数放在呈现的页面上。通常,我有一个application.js(也可能是root.js),其中包含菜单操作等通用功能。如果某个页面具有特定的javascript功能,则会创建一个.js文件来处理该代码,并模仿如何访问该文件的目录结构(还使用与呈现文件相同的名称)。

换句话说,如果渲染的页面位于public/dir1/dir2/mypage.html中,则js文件将位于public/js/dir1/dir2/mypage.js中。我发现这种风格非常适合我,特别是在网站上进行模板化时。我构建了模板引擎,通过获取请求路径,并在根目录的css和js目录中检查相应的css和js文件,以“自动加载”我的资源(css和js)。


0

个人而言,我尝试包含多个按模块排序的Javascript文件(像YUI一样)。但偶尔当我写一个基本上是一行代码时,我会把它放在页面上。


0

最佳实践可能是将其放在Google的服务器上。

(不过,我想这取决于你所说的“你的”JavaScript的含义:)


用户连接到谷歌本地服务器的速度比连接到您的Web服务器快得多,这是可能的吗?这可能会节省带宽并加快页面加载速度。(不投票,因为它没有回答问题) - Dean Rather

0

这也是我一直在努力解决的问题。最终,我使用后端PHP脚本根据用户请求的内容智能地构建所需JS文件列表。

通过将我的JS文件组织成包含多个按目的组织的文件的存储库(无论是通用使用、针对单个页面、单个部分等),我可以使用后端构建页面的事件链来有选择地选择需要包含哪些JS文件(请参见下面的示例)。

这是在没有充分考虑代码方面实现我的Web应用程序之后。现在,我还应该补充说明,我使用的JavaScript只是增强而不是构成我的网站基础。如果您使用类似SproutCore或Ext的东西,我想解决方案可能会有所不同。


这是一个关于PHP驱动网站的示例: 如果您的网站被分成了不同的部分,其中之一是日历。用户导航到“index.php?module=calendar&action=view”。如果PHP代码是基于类的,则路由算法将实例化CalendarModule类,该类基于'Module'并具有虚拟方法'getJavascript'。这将返回所需的javascript类,以执行'calendar'模块上的'action' 'view'。它还可以考虑任何其他特殊要求,并为其返回js文件。渲染代码可以验证在构建最终页面的javascript包含列表时是否存在js文件的重复项。因此,getJavascript方法返回如下数组:
return array('prototype.js','mycalendar.js');

请注意,这个想法或类似的想法并不是新的。但我花了一些时间来思考它是否重要到足以麻烦实现。

0
如果它只有几百个字节或更少,并且不需要在其他任何地方使用,我可能会将其内联。另一个http请求的网络开销很可能超过从页面中提取它所获得的任何性能提升。
如果它需要在几个地方使用,我会将函数放入一个公共的外部文件中,并按需要从内联脚本调用。
如果你的目标是iPhone,请尝试将任何想要缓存的东西保持在25k以下。
没有硬性规定,每种方法都有其优缺点。强烈建议您查看在雅虎开发者部分可以找到的文章,以便您可以根据具体情况做出明智的决策。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接