什么时候应该使用内联和外部 Javascript?

我想知道在性能和易于维护方面,什么时候应该包含外部脚本或者使用 html 代码内联编写它们。

这方面的一般做法是什么?

真实场景-我有几个需要客户端表单验证的 html 页面。为此,我使用了一个包含在所有这些页面中的 jQuery 插件。但问题是,我有吗:

  • 编写内联配置这个脚本的代码位?
  • 包括所有的位在一个文件中共享所有这些 html 页面?
  • 包括每一位在一个单独的外部文件,每一个 html 页面?

谢谢。

62142 次浏览

在这个答案最初发布的时候(2008) ,规则很简单: 所有的脚本都应该是外部的。无论是维护还是性能。

(为什么是性能? 因为如果代码是独立的,浏览器可以更容易地缓存它。)

JavaScript 不属于 HTML 代码,如果它包含特殊字符(如 <>) ,它甚至会产生问题。

如今,Web 可伸缩性已经发生了变化。由于发出多个 HTTP 请求的延迟,减少请求的数量已成为一个有效的考虑因素。这使得问题的答案更加复杂: 在大多数情况下,建议使用 还是外部 JavaScript。但是对于某些情况,特别是非常小的代码片段,将它们内联到站点的 HTML 中是有意义的。

在您的场景中,将外部内容写入页面之间共享的一个文件中似乎对您有好处。我同意上面所说的一切。

在早期的原型开发中,为了获得快速迭代的好处,将代码保持在内联状态,但是一定要在到达生产环境时将其全部外部化。

我甚至敢说,如果您不能将所有 Javascript 放在外部,那么您的设计就很糟糕,您应该重构数据和脚本

可维护性肯定是将它们保持在外部的一个原因,但是如果配置是一行程序(或者通常比将这些文件保持在外部的 HTTP 开销要短) ,那么从性能角度来说,将它们保持在内部更好。请始终记住,每个 HTTP 请求都会在执行时间和流量方面产生一些开销。

当您的代码超过几行并且不是特定于某一个页面时,这一切自然就变得无关紧要了。一旦您希望能够重用该代码,请将其设置为外部的。如果你没有,看看它的大小,然后再决定。

外部化 javascript 是雅虎的性能规则之一: Http://developer.yahoo.com/performance/rules.html#external

虽然应该始终外部化脚本的硬性规则通常是一个很好的选择,但在某些情况下,您可能需要内联一些脚本和样式。然而,您应该仅仅内联那些您知道会提高性能的内容(因为您已经度量过了)。

我会看一下所需的代码,然后根据需要将其分成许多单独的文件。每个 js 文件只包含一个函数的“逻辑集”,例如所有登录相关函数的一个文件。

然后在每个 html 页面的站点开发过程中,您只包含那些需要的。 当您使用您的站点时,您可以通过将页面需要的每个 js 文件组合到一个文件中来进行优化。

三点考虑:

  • 您需要多少代码(有时候库是一流的消费者) ?
  • 具体性: 此代码是否只在此特定文档或元素的上下文中起作用?
  • 文档中的每个代码都会使文档变长,从而变慢。除此之外,搜索引擎优化的考虑显而易见,你最小化内部脚本..。

我认为 具体到一个页面,简短的脚本案例是(唯一)内联脚本可以辩护的情况

使用 Firebug 调试外部脚本也更容易。我喜欢对我的 JavaScript 进行单元测试,这样可以得到外部的帮助。我讨厌在 PHP 代码和 HTML 中看到 JavaScript,在我看来这是一团糟。

关于保持 JavaScript 的外部性:

NET 3.5 SP1最近引入了创建 Composite 脚本资源的功能(将一堆 js 文件合并到一个脚本资源中)。这样做的另一个好处是,当打开 Webserver 压缩时,下载一个稍大一点的文件会比许多小文件有更好的压缩比(也更少的 http 开销,往返等。.).我想这样可以节省初始页面加载,然后浏览器缓存就会像上面提到的那样启动。

除了 ASP.NET,这段视频还详细解释了它的好处: Http://www.asp.net/learn/3.5-sp1/video-296.aspx

外部脚本的另一个隐藏好处是,您可以通过像 Jslint这样的语法检查器轻松地运行它们。这样可以避免许多令人心碎、难以找到的 IE6 bug。

实际上,使用内联 javascript 有一个很好的例子。我倾向于使用内联的 javascript,因为有两个原因:

  • Locality . 不需要导航外部文件来验证某些 javascript 的行为
  • AJAX .如果您通过 AJAX 刷新页面的某些部分,那么 将失去该部分的所有 DOM 处理程序(onclick 等) ,这取决于您如何绑定它们。例如,使用 jQuery,您可以使用 livedelegate方法来规避这个问题,但是我发现,如果 js 足够小,最好将其内联。

我可以为内联 javascipt 提供的唯一防御是,当使用强类型视图。Net MVC 你可以在 javascript 中参考 c # 变量,我发现它很有用。

为什么总是使用外部脚本的另一个原因是为了更容易地过渡到 内容安全策略(CSP)。CSP 默认禁止所有内联脚本,使您的站点更能抵抗 XSS 攻击。

如果您只关心性能,那么这个线程中的大多数建议都是完全错误的,并且在 SPA 时代正变得越来越错误,在 SPA 时代,我们可以假设没有 JS 代码的页面是无用的。我花了无数个小时优化 SPA 页面加载时间,并用不同的浏览器验证这些结果。通过重新编排您的 html,整体性能的提高可能是相当戏剧性的。

为了获得最好的性能,你必须把页面想象成两级火箭。这两个阶段大致对应于 <head><body>阶段,但是可以将它们看作是 <static><dynamic>。静态部分基本上是一个字符串常量,您可以尽可能快地将其推入响应管道。如果你使用了很多设置 cookie 的中间件(在发送 http 内容之前需要设置这些) ,这可能有点棘手,但是原则上它只是刷新响应缓冲区,希望在跳入服务器上的模板代码(剃须刀,php 等)之前。这可能听起来很困难,但我只是解释错了,因为它几乎是微不足道的。正如您可能已经猜到的,这个静态部分应该包含所有内联和缩小的 javascript。看起来像是

<!DOCTYPE html>
<html>
<head>
<script>/*...inlined jquery, angular, your code*/</script>
<style>/* ditto css */</style>
</head>
<body>
<!-- inline all your templates, if applicable -->
<script type='template-mime' id='1'></script>
<script type='template-mime' id='2'></script>
<script type='template-mime' id='3'></script>

由于通过网络发送这部分内容几乎不需要花费任何成本,因此可以预期客户机在连接到服务器之后将在5ms + 延迟左右开始接收这部分内容。假设服务器相当接近,这个延迟可能在20毫秒到60毫秒之间。浏览器一旦得到这个部分就会开始处理,处理时间通常会占据传输时间的20倍或更多,这就是现在服务器端处理 <dynamic>部分的摊销窗口。

浏览器处理内联 jquery + signalr + angle + ng animate + ng touch + ng path + loash 大约需要50毫秒(chrome,休息时间可能慢20%)。这本身就很神奇。大多数 web 应用程序的代码比所有流行的库加起来还要少,但是假设你的代码一样多,那么我们将在客户端赢得延迟 + 100ms 的处理时间(这个延迟的胜利来自第二个传输块)。当第二个块到达时,我们已经处理了所有 js 代码和模板,可以开始执行 dom 转换了。

您可能会反对这个方法与内联概念是正交的,但它不是。如果您链接到 cdns 或您自己的服务器,而不是内联,浏览器将不得不打开另一个连接并延迟执行。由于这种执行基本上是免费的(因为服务器端正在与数据库进行对话) ,所以必须清楚,所有这些跳转都比完全不跳转要花费更多的成本。如果有一个浏览器的怪癖,说外部 js 执行得更快,我们可以衡量哪个因素占主导地位。我的测量结果表明,在这个阶段,额外的请求会影响性能。

我在 SPA 应用程序的优化方面做了很多工作。人们通常认为数据量是一个大问题,而事实上,延迟和执行往往占主导地位。我列出的缩小库加起来有300kb 的数据,这只是68kb 的 gzip,或2mbit 的3g/4g 手机上的200ms 下载,这正是同一部手机检查是否已经在缓存中有相同的数据所需要的延迟,即使它是代理缓存,因为移动延迟税(手机到发射塔的延迟)仍然适用。同时,具有较低的第一跳延迟的桌面连接通常具有较高的带宽。

简而言之,现在(2014年) ,最好是内联所有的脚本,样式和模板。

编辑(二零一六年五月)

随着 JS 应用程序的不断增长,我的一些有效负载现在已经堆积到了3兆以上的缩小代码,很明显,至少公共库不应该再内联。

谷歌已经将加载时间纳入到它的页面排名测量中,如果你内联了很多,蜘蛛爬行通过你的页面将需要更长的时间,这可能会影响你的页面排名,如果你有很多包括。在任何情况下,不同的策略可能会影响你的排名。

我认为,你应该使用内联时,作为脚本单页网站将不需要共享跨多个网页

总是尝试使用外部 Js,因为内联 Js 总是难以维护。

此外,使用外部 js 是专业要求,因为大多数开发人员建议在外部使用 js。

我自己使用外部 js。

拥有内部的 JS 优势: 更容易管理和调试 你可以看到发生了什么

内部 JS 弊端: 人们可以改变它的周围,这真的可以烦扰你。

外部 JS 优点: 不能改变 你可以看起来更专业(至少我是这么认为的)

外部 JS 缺点: 更难管理 很难知道发生了什么事。