在性能和易维护性方面,我想知道何时应该包含外部脚本或使用html代码内联编写它们.
这是什么一般做法?
真实场景 - 我有几个需要客户端表单验证的html页面.为此,我使用了一个jQuery插件,我将其包含在所有这些页面中.但问题是,我是否:
编写内联配置此脚本的代码位?
包括所有这些html页面中共享的一个文件中的所有位?
将每个位包含在一个单独的外部文件中,每个html页面一个?
谢谢.
在最初发布此答案时(2008年),规则很简单:所有脚本都应该是外部的.两者都用于维护和性能.
(为什么性能?因为如果代码是独立的,浏览器可以更容易地缓存它.)
JavaScript不属于HTML代码,如果它包含特殊字符(例如<
,>
),它甚至会产生问题.
如今,Web可扩展性已发生变化.由于发出多个HTTP请求的延迟,减少请求数已成为一个有效的考虑因素.这使答案更复杂:在大多数情况下,仍建议使用JavaScript外部.但是对于某些情况,特别是非常小的代码片段,将它们内嵌到网站的HTML中是有道理的.
可维护性绝对是将它们保持在外部的一个原因,但是如果配置是单行的(或者通常比将这些文件设置为外部的HTTP开销更短),那么在性能方面更好地保持它们内联.永远记住,每个HTTP请求在执行时间和流量方面都会产生一些开销.
当然,这一切都变得无关紧要,因为您的代码长度超过几行并且不是特定于单个页面.您希望能够重用该代码的那一刻,将其置于外部.如果不这样做,请查看其大小然后再决定.
外化javascript是雅虎性能规则之一:http: //developer.yahoo.com/performance/rules.html#external
虽然你应该总是外化脚本的硬性规则通常是一个不错的选择,在某些情况下你可能想要内联一些脚本和样式.但是,您应该只列出您知道会提高性能的内容(因为您已经对此进行了测量).
如果你只关心性能,那么这个线程中的大多数建议都是错误的,并且在SPA时代变得越来越错,我们可以假设在没有JS代码的情况下页面是无用的.我花了无数个小时来优化SPA页面加载时间,并使用不同的浏览器验证这些结果.通过重新编排你的html来提高性能可能会非常引人注目.
为了获得最佳性能,您必须将页面视为两级火箭.这两个阶段大致对应和
阶段,但将其视为
和
.静态部分基本上是一个字符串常量,您可以尽可能快地将响应管道向下移动.如果您使用大量设置cookie的中间件(这些需要在发送http内容之前设置),这可能有点棘手,但原则上它只是刷新响应缓冲区,希望在跳转到一些模板代码之前(razor,php,等)在服务器上.这可能听起来很难,但后来我只是解释错了,因为它几乎是微不足道的.正如您可能已经猜到的,这个静态部分应该包含内联和缩小的所有javascript.它看起来像
由于您无需花费任何费用即可将此部分发送到网络中,因此您可以预期客户端将在连接到您的服务器后开始接收大约5ms +延迟.假设服务器相当接近,则此延迟可能在20ms到60ms之间.浏览器会在收到后立即开始处理此部分,处理时间通常会占用传输时间20倍或更多,现在是服务器端处理该
部分的分摊窗口.
浏览器需要大约50毫秒(铬,休息可能慢20%)来处理内联jquery + signalr + angular + ng animate + ng touch + ng routes + lodash.这本身就很神奇.大多数网络应用程序的代码都比所有流行的库都要少,但是假设你的代码也很多,所以我们会在客户端上获得延迟+ 100毫秒的处理(这个延迟获胜来自第二个传输块).到第二个块到达时,我们已经处理了所有js代码和模板,我们可以开始执行dom变换.
您可能会反对此方法与内联概念正交,但事实并非如此.如果您不是内联链接到cdns或您自己的服务器,浏览器将不得不打开另一个连接并延迟执行.由于这个执行基本上是免费的(因为服务器端正在与数据库通信),所以必须清楚所有这些跳转的成本都比没有跳转要多.如果有一个浏览器怪癖说外部js执行得更快,我们可以测量哪个因素占主导地位.我的测量表明额外的请求在此阶段会导致性能下降.
我在优化SPA应用程序方面做了很多工作.人们普遍认为数据量是一个大问题,而事实上延迟,执行往往占主导地位.我列出的缩小的库增加了300kb的数据,这只是在2mbit 3g/4g手机上的68kb gzip或200ms下载,这正是在同一部手机上检查它是否具有相同数据所需的延迟已经在其缓存中,即使它是代理缓存,因为移动延迟税(电话到塔延迟)仍然适用.同时,具有较低第一跳延迟的桌面连接通常具有更高的带宽.
简而言之,就在现在(2014年),最好内联所有脚本,样式和模板.
编辑(2016年5月)
随着JS应用程序的不断增长,我的一些有效负载现在堆叠了3兆字节的缩小代码,很明显,至少应该不再内联公共库.
我认为具体到一个页面,短脚本案例是(仅)内联脚本的可辩护案例
实际上,使用内联javascript有一个非常可靠的案例.如果js足够小(单行),我倾向于选择javascript内联,因为有两个因素:
地方.无需导航外部文件来验证某些javascript的行为
AJAX.如果您通过AJAX刷新页面的某些部分,则可能会丢失该部分的所有DOM处理程序(onclick等),具体取决于绑定它们的方式.例如,使用jQuery
你可以使用live
或delegate
方法来规避这一点,但我发现如果js足够小,最好只将它放在内联中.
您应该始终使用外部脚本的另一个原因是为了更轻松地过渡到内容安全策略(CSP).CSP默认禁止所有内联脚本,使您的站点更耐XSS攻击.