![](/img/trans.png)
[英]Ordering of javascript execution (inline and external), IE vs. Firefox
[英]When should I use Inline vs. External Javascript?
我想知道在性能和易于维护方面,我什么时候应该包含外部脚本或将它们与 html 代码内联编写。
这方面的一般做法是什么?
真实世界场景 - 我有几个需要客户端表单验证的 html 页面。 为此,我使用了一个包含在所有这些页面上的 jQuery 插件。 但问题是,我是否:
谢谢。
在这个答案最初发布时(2008 年),规则很简单:所有脚本都应该是外部的。 无论是维护还是性能。
(为什么是性能?因为如果代码是分开的,它可以更容易地被浏览器缓存。)
JavaScript 不属于 HTML 代码,如果它包含特殊字符(例如<
、 >
),它甚至会产生问题。
如今,Web 的可扩展性已经发生了变化。 由于发出多个 HTTP 请求的延迟,减少请求数量已成为一个有效的考虑因素。 这使得答案更加复杂:在大多数情况下,仍然建议使用外部 JavaScript。 但对于某些情况,尤其是非常小的代码片段,将它们内联到站点的 HTML 中是有意义的。
可维护性绝对是将它们保持在外部的一个原因,但是如果配置是单行的(或者通常比将这些文件放在外部所获得的 HTTP 开销更短),那么将它们保持内联在性能方面更好。 永远记住,每个 HTTP 请求都会在执行时间和流量方面产生一些开销。
当您的代码长于几行并且不是真正特定于一个页面时,这一切自然变得无关紧要。 当您希望能够重用该代码时,将其设为外部。 如果你不这样做,看看它的大小然后再决定。
如果你只关心性能,这个线程中的大部分建议都是错误的,并且在 SPA 时代变得越来越错误,我们可以假设没有 JS 代码的页面是无用的。 我花了无数个小时来优化 SPA 页面加载时间,并使用不同的浏览器验证这些结果。 总体而言,通过重新编排您的 html 可以显着提高性能。
为了获得最佳性能,您必须将页面视为两级火箭。 这两个阶段大致对应于<head>
和<body>
阶段,但可以将它们视为<static>
和<dynamic>
。 静态部分基本上是一个字符串常量,您可以尽可能快地将其推入响应管道。 如果您使用大量设置 cookie 的中间件(这些需要在发送 http 内容之前设置),这可能有点棘手,但原则上它只是刷新响应缓冲区,希望在跳入某些模板代码(razor、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>
由于通过网络发送这部分内容几乎不需要任何费用,因此您可以预期客户端在连接到您的服务器后大约 5 毫秒 + 延迟时间开始接收此内容。 假设服务器合理关闭,此延迟可能在 20 毫秒到 60 毫秒之间。 浏览器一收到它就会开始处理它,处理时间通常比传输时间高出 20 倍或更多,这现在是服务器端处理<dynamic>
部分的分摊窗口。
浏览器(chrome,rest 可能慢 20%)处理内联 jquery + signalr + angular + ng animate + ng touch + ng routes + lodash 大约需要 50 毫秒。 这本身就非常了不起。 大多数 Web 应用程序的代码少于所有那些流行库的总和,但假设您有同样多的代码,那么我们将在客户端上赢得延迟 + 100 毫秒的处理(这个延迟胜利来自第二个传输块)。 当第二个块到达时,我们已经处理了所有的 js 代码和模板,我们可以开始执行 dom 转换。
您可能反对此方法与内联概念正交,但事实并非如此。 如果您不是内联,而是链接到 cdns 或您自己的服务器,则浏览器将不得不打开另一个连接并延迟执行。 由于此执行基本上是免费的(因为服务器端正在与数据库对话),所以必须清楚所有这些跳转的成本比根本不进行跳转要高。 如果有一个浏览器怪癖说外部 js 执行得更快,我们可以衡量哪个因素占主导地位。 我的测量表明,额外的请求会降低此阶段的性能。
我在 SPA 应用程序的优化方面做了很多工作。 人们通常认为数据量很重要,但实际上延迟和执行往往占主导地位。 我列出的缩小库加起来有 300kb 的数据,这只是 68kb gzip 压缩,或者在 2mbit 3g/4g 手机上下载 200ms,这正是在同一部手机上检查是否有相同数据所需要的延迟已经在其缓存中,即使它是代理缓存的,因为移动延迟税(电话到塔延迟)仍然适用。 同时,具有较低第一跳延迟的桌面连接通常无论如何都具有较高的带宽。
简而言之,现在(2014 年),最好内联所有脚本、样式和模板。
编辑(2016 年 5 月)
随着 JS 应用程序的不断增长,我的一些有效负载现在堆叠到 3 兆字节以上的缩小代码,很明显至少不应再内联公共库。
外部化 javascript 是雅虎性能规则之一:http: //developer.yahoo.com/performance/rules.html#external
虽然您应该始终外部化脚本的硬性规定通常是一个不错的选择,但在某些情况下您可能希望内联一些脚本和样式。 但是,您应该只内联您知道会提高性能的东西(因为您已经对此进行了测量)。
我认为特定于一页的短脚本案例(仅)是内联脚本的防御案例
应始终使用外部脚本的另一个原因是为了更容易过渡到内容安全策略 (CSP) 。 CSP 默认禁止所有内联脚本,使您的站点更能抵抗 XSS 攻击。
我会看一下所需的代码,并根据需要将其分成尽可能多的单独文件。 每个 js 文件只会包含一个“逻辑集”的功能等。 所有登录相关功能的一个文件。
然后在每个 html 页面上的网站开发过程中,您只包括需要的那些。 当您开始使用您的网站时,您可以通过将页面需要的每个 js 文件合并到一个文件中来进行优化。
我可以为内联 javascipt 提供的唯一防御是,在将强类型视图与 .net MVC 一起使用时,您可以在我发现有用的 javascript 中引用 c# 变量。
三个注意事项:
关于将 JavaScript 保持在外部:
ASP.NET 3.5SP1 最近引入了创建复合脚本资源的功能(将一堆 js 文件合并为一个)。 这样做的另一个好处是,当打开 Web 服务器压缩时,下载一个稍大的文件将比许多较小的文件有更好的压缩率(也更少的 http 开销、往返等...)。 我想这可以节省初始页面加载时间,然后浏览器缓存就会像上面提到的那样启动。
除了 ASP.NET,这个截屏视频更详细地解释了好处: http ://www.asp.net/learn/3.5-SP1/video-296.aspx
使用 Firebug 也更容易调试外部脚本。 我喜欢对我的 JavaScript 进行单元测试,并让所有外部帮助。 我讨厌在 PHP 代码和 HTML 中看到 JavaScript,这对我来说是一团糟。
外部脚本的另一个隐藏好处是您可以轻松地通过jslint等语法检查器运行它们。 这可以使您免于遇到许多令人心碎的、难以发现的 IE6 错误。
在您的场景中,听起来将外部内容写在页面之间共享的一个文件中对您有好处。 我同意上面所说的一切。
在早期原型制作期间,为了快速迭代的好处,请保持代码内联,但一定要在生产时将其全部放在外部。
我什至敢说,如果你不能把你所有的 Javascript 放在外部,那么你手下的设计就很糟糕,你应该重构你的数据和脚本
Google 已将加载时间纳入其页面排名测量中,如果您内联很多,蜘蛛将需要更长的时间来抓取您的页面,如果您必须包含很多内容,这可能会影响您的页面排名。 在任何情况下,不同的策略都可能影响您的排名。
好吧,我认为在制作单页网站时应该使用内联,因为脚本不需要跨多个页面共享
拥有内部 JS 专业人员:更容易管理和调试您可以看到发生了什么
内部 JS 缺点:人们可以改变它,这真的会让你烦恼。
外部 JS 专业人士:不改变周围你可以看起来更专业(或者至少我是这么认为的)
外部 JS 缺点:更难管理,很难知道发生了什么。
始终尝试使用外部 Js,因为内联 js 总是难以维护。
而且,专业要求你使用外部js,因为大多数开发人员建议使用外部js。
我自己使用外部js。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.