为什么要避免内联脚本编写?


47

一位知识渊博的朋友最近浏览了我帮助启动的网站,并评论了诸如“非常酷的网站,对源代码中的内联脚本感到羞耻”之类的内容。

我绝对可以删除发生内联脚本的位置;我隐约意识到这是“一件坏事”。我的问题是:内联脚本的真正问题是什么?是否存在重大的性能问题,还是仅是良好风格的问题?当还有其他事情需要处理时,我可以证明对上级的内联脚本方面立即采取行动是合理的吗?如果您打开一个网站并看了一眼源代码,什么因素会导致您说“嗯,在这里从事专业工作”,什么原因会使您从显然业余的工作中退缩?

好的,在写作中那个问题变成了多个问题。但是基本上,内联脚本-有什么关系?


3
重复使用和将设计与实现分开是两个不让我精打细算的原因。
Michael Todd

1
这里缺少一些上下文-“内联脚本”是什么意思?
greyfade11年

是的,是页面内的CSS,页面内的JS还是其他?
Michael K

2
@greyfade,迈克尔:好吧,我的朋友没有指定,所以我们假设两者都是。我们说更多的JS,因为这通常更接近我的职责范围...
thesunneversets 2011年

2
除非您要创建冗余代码,否则不会出现问题。尽管如果您有大量的内联代码,它可能看起来很笨拙。但是我只使用内联的Confirms而不是在脚本块中编写函数来调用。
SoylentGray 2011年

Answers:


36

内联脚本的真正问题是什么?是否存在重大的性能问题,还是仅是良好风格的问题?

优点不是基于性能的,而是(如Michael在其评论中指出的)更多与视图和控制器的分离有关。理想情况下,HTML / CSS文件应仅包含演示文稿,而单独的文件应用于脚本。这使您(和您的同伴)更容易阅读和维护视觉和功能方面。

当还有其他事情需要处理时,我可以证明对上级的内联脚本方面立即采取行动是合理的吗?

不,可能不会。要说服纯维修工作的力量可能非常困难,即使您认为从长远来看将为他们省钱。但是,在这种情况下,我认为停止所有操作并摆脱内联脚本并不重要。相反,只要确保您出于其他原因在对这些区域进行工作时有意识地进行纠正即可。重构代码应该是您经常执行的事情,但一次只做一点点。

如果您打开一个网站并看了一眼源代码,什么因素会导致您说“嗯,在这里从事专业工作”,什么原因会使您从显然业余的工作中退缩?

告诉我它不专业的第一个因素是表或div的过度使用。这是一篇文章,解释为什么都不应过度使用。


48

我不会成为恶魔的拥护者,但是业余工作和内联JavaScript之间没有严格的关系。让我们看一下几个最知名网站的源代码:

  • 谷歌,
  • 维基百科,
  • 微软,
  • Adobe,
  • 戴尔,
  • IBM。

他们的每个主页都使用内联JavaScript。这是否意味着所有这些公司都会雇用业余人员来创建他们的主页?


我是无法将JavaScript代码放入HTML的那些开发人员之一。我从不在我从事的项目中做这件事(除了一些调用,例如<a href="javascript:...">那些从一开始就不需要非侵入性JavaScript的项目,并且在重构其他人的代码时,我总是删除内联JavaScript。但是这样做值得吗? ?不太确定。

在性能方面,将JavaScript放在单独的文件中时,并非总是有更好的性能。通常,我们倾向于考虑内联JavaScript浪费带宽,因为它无法缓存(除非您处理静态可缓存HTML时除外)。相反,一个extern .js文件仅加载一次。

实际上,这只是另一种过早的优化:您可能会以为外部化JavaScript会加快您的网站速度,但您可能是完全错误的:

  • 如果您的大多数用户都带有一个空的缓存该怎么办?
  • 您是否认为如果外部网站配置不正确(通常不是),那么在使用extern .js文件时,每次页面请求都会对此文件进行请求,
  • .js文件是否真的被缓存了(使用IIS,可能不是那么容易)?

因此,在过早进行优化之前,请收集有关访问者的统计信息,并在使用和不使用嵌入式JavaScript的情况下评估性能。

然后是最后一个论点:您在源代码中混合了JavaScript和HTML,因此很烂。但是谁说你把两者混在一起?浏览器使用的源代码并不总是您编写的源代码。例如,源代码可以被压缩,精缩,或几个CSS或JS文件可以被连接到一个文件中,但是这并不意味着你真的叫你的变量abc... a1等,或者你写了一巨大的CSS文件,没有空格或换行符。同样,您可以在编译时或稍后通过模板轻松地将外部JavaScript源代码注入HTML。


总而言之,如果您在编写的源代码中混合使用JavaScript和HTML,则应考虑在以后的项目中不要这样做。但这并不意味着如果发送到浏览器的源代码包含内联JavaScript,那就总是很糟糕。

  • 可能不好。
  • 相反,这可能表明该网站是由专业人士编写的,他们关心性能,进行了特定的测试,并确定其客户内联JavaScript的部分会更快。
  • 否则可能根本没有任何意义。

因此,只看发送到浏览器的源代码,而对网站的运作一无所知,这让说“非常酷的网站,对源代码中的内联脚本感到羞耻”的人感到羞耻。


1
为进行研究和体贴而+1。实际情况是,有一些构建工具可以使在单独文件中开发的代码在事实发生后组合为内联。HTML + CSS + JS是网络的汇编语言。事物的交付方式(最小化,复合化)与它们的制造方式无关。
埃文·莫兰

21

通常最好将HTML和JS分开。HTML用于视图,JS用于应用程序逻辑。但是以我的经验,html和javascript的极端分离(出于纯净的考虑)并不能使其更易于维护。它实际上很难维护。

例如,有时在设置事件处理程序时会使用以下模式(从ASP.net借用):

<input type="button" id="yourId" onclick="clickYourId()" />

要么

<input type="button" id="yourId" onclick="clickYourId(this)" />

触发事件发生的原因并不神秘。原因是六个月后,您可以检查该元素(例如,在Chrome中),并立即查看触发了哪些javascript事件。

另一方面,假设您正在阅读别人的代码(十万行),并且遇到了触发javascript事件的神奇元素:

<input id="yourId"  />

您如何轻松地告诉我这是在调用什么javascript方法?Chrome简化了此过程,但事件可能绑定到ID,或者绑定到容器的第一个子对象。可能事件已附加到父对象。谁知道?祝你好运。:)

另外,我认为完全不向设计人员隐藏javascript可能实际上增加了他们在更新时破坏它的可能性。如果有人为一个魔术有效元素编辑代码,那么他们在代码中有什么指示会告诉他们这是页面上的有效元素?

简而言之,最佳实践是将HTML和Javascript分开。但也要了解,将经验法则推到极致有时会适得其反。我主张采用中间方法。避免大量的内联js。如果确实使用内联,则函数签名应该非常简单,例如:

1. emptyFunction()
2. doCallWithThis(this)
3. atTheExtremOnlyPassOneNumber(2)

3
好点子!好答案。
朱利安2014年

1
确实,很好的答案。只要JS使得很难找到连接的侦听器,内联脚本将继续易于维护。
JohnK

我认为这是最好的答案。极端的事情通常都是“过度执行”。
deebs 2015年

10

我在这里缺少的一个论点是可能增强针对跨站点脚本攻击的保护。

通过Content Security Policy可以禁用现代浏览器中的内联JavaScript的执行。这减少了您的站点成为XSS受害者的风险。这可能是使您的管理层投资于删除内联脚本的更有说服力的论据。


2
我认为这是最好的答案现在
Supersharp

2
以我的拙见,这值得更多的批评和关注。
帕特里克·罗伯茨

有效点!
Anshul

内联脚本是静态的不是这种情况,对吗?
КонстантинВан

9

这是一些原因。

  1. 无法缩小内联脚本(通过减少符号将其转换为较短的版本)。与宽带无关,但考虑低带宽区域中的移动设备或正在进行全球数据漫游的用户-每个字节都可以计数。

  2. 除非页面本身是可缓存的,否则内联脚本无法被浏览器缓存(这会使页面变得很沉闷)。即使页面内容每次更改,外部Javascript文件也只需要检索一次。会严重影响低带宽连接的性能。

  3. 内联脚本更难调试,因为与任何错误关联的行号是没有意义的。

  4. 据说内联脚本会干扰可访问性(508 / WAI)注意事项,尽管这并不意味着所有内联脚本都会引起问题。如果最终使用屏幕阅读器来宣布脚本内容,那么您有问题!(虽然从未见过这种情况)。

  5. 内联脚本不能独立于其页面进行测试;外部Javascript文件可以通过独立的测试(包括自动化测试)运行。

  6. 内联脚本可能导致关注点分离不佳(如此处许多其他答案所述)。


2
有些页面可能是静态的,但仍然有价值。今天早些时候,我在使用带有计算器的页面。可缓存,但有用。我同意非平凡的Javascript不属于任何动态页面。
罗伦·佩希特尔

3

有多种原因可以证明不包括内联脚本:

  • 首先,显而易见的答案-它使代码更简洁,更简洁,更易于理解和阅读。

  • 从更实际的角度来看,您经常想重用脚本/ CSS / etc。在您的整个网站上-对这些部分进行内联将意味着每次您进行小的更改时都必须编辑每个页面。

  • 如果您在项目中使用SCM,那么将不同的组件分开就可以使跟踪更改和提交工作对每个参与人员而言都更加容易。

据我所知,性能不是问题。这将取决于与您的网站的性质,服务器的规格等相关的许多事情。例如,如果您的网页使用了大量的javascript,则您的浏览器可能会缓存脚本,这将在以下情况下提高性能:该代码分为多个文件。另一方面,我很想说某些服务器处理单个大文件的速度可能比处理多个较小文件的速度要快-在这种情况下,人们可能会认为不分离代码在性​​能上会更好。

尽管很可能有人进行了测试,但我不知道这方面的任何正式测试。

最后,我要说的是,良好实践比什么都重要,并且在可读性和组织性方面的优势(特别是wrt point 2)使得将代码分离在不同的文件中是一个更好的选择。


可以异步下载外部文件,以便在访问者阅读时将其缓存到下一个页面,或者在下载脚本时允许页面,图像等下载-因此,如果这些技术在使用中,则可以提高性能。使用(下载时间而不是执行速度)。
FinnNk 2011年

2

答案实际上取决于如何使用内联代码(假设使用javascript)。

我们使用内联代码,SSI(服务器端包含),js文件和css文件的组合来创建所需的效果,并减少onClick事件的服务器返回次数。

因此,如果有人在未完全了解如何使用“内联代码”的情况下做出笼统的声明,那是一种误导。

话虽如此,如果每个页面都具有相同的副本和粘贴的javascript代码,而不是使用js文件,那么我认为这很不好。

如果每个页面都有它自己的副本并粘贴CCS部分,而不是使用CSS文件,我认为这很糟糕。

在每个页面上都包含整个js库也很麻烦,尤其是如果该页面上没有使用任何功能时。


1

我将在这里假设嵌入式javascript。

没有看到代码,就很难确定。我怀疑他指的是两件事之一:

  1. <script>分散在整个页面中
  2. 您所有的JS位于页面标题中,而不位于外部文件中

首先是一个错误的设计决定。整个源文件传播的脚本使得页面太多难以维持,因为你必须寻找一个给定的脚本。最好将所有代码都放在一个位置(我更喜欢在源文件的顶部)。

至于第二点-不一定是坏事。页面特定代码在该页面中。如果页面之间有重复的代码,则应使用进行外部化<script src>。然后,当您创建一个新页面时,只需包含该文件即可,而不必重新检查在此修复的任何错误。


1
请注意,脚本会阻止其他内容的下载,通常最好将它们放在页面的底部(尽管有时您希望它们被阻止,在这种情况下,它们应放在头部)。在所有脚本引用之前,可以并行下载的CSS最好放在顶部。
FinnNk 2011年

1
在这里不同意。针对特定页面的javascript(不是唯一的一种)的一种更好的设计是在单独的.js文件中包含特定于页面的javascript,该文件仅包含在该页面中。这样一来,该文件会从缓存中受益,可以精缩等
SamStephens

1

不使用InLine Javascript(甚至不使用按钮上的onclick =“ DoThis(this)”)的原因之一是,如果您打算将Web应用程序设置为Chrome应用程序。因此,如果您打算将Web应用程序移植到本机Chrome应用程序中,请先不包含任何内联JavaScript。如果您打算“ Chrome-etize”它,那么在您需要(强制性)从Web应用程序进行更改的一开始就对此进行了说明。


0

内联脚本的真正问题是什么?

内联脚本是不好的,应该避免使用内联脚本,因为它会使代码更难阅读。

难以阅读的代码难以维护。如果您不容易阅读并理解正在发生的事情,则将无法轻松发现错误。如果难以维护,则会在出现问题时浪费更多时间。

困难通常来自嵌套编码。在下一行代码中有问题,您能发现吗?

<a onclick='alert("What\'s going wrong here?")'>Alert!</a>

理想情况下,代码的编写方式可以使发现错误时易于发现。乔尔·斯波斯基(Joel Spolsky)于2005年撰写了一篇精彩的文章,强调了这一点。这些代码示例可以证明他们的年龄已经达到9岁,因此可能会进行一些重大改进,但是其基本概念仍然很强大:以易于发现错误的方式编写代码。

是否存在重大的性能问题,还是仅是良好风格的问题?

内联脚本导致重复。您可能无需单独更改100页,而不必更改一行代码来影响100页。加上可读性差,严重影响了维护人员的性能。编程时间的实际成本比大多数代码优化所花费的几毫秒要快,影响企业的底线。当然,优化瓶颈很重要,但是在这种情况下,代码的性能差异可以忽略不计。

当还有其他事情需要处理时,我可以证明对上级的内联脚本方面立即采取行动是合理的吗?

不。如果它很愚蠢并且有效,那么它不是愚蠢的。

对此的编程推论是:如果它是愚蠢的代码并且可以工作,那么它不是愚蠢的代码。在尝试解决未损坏的问题之前,请先关注实际问题。当内联代码最终需要更新时,无论是在6个小时,6个月还是6年内,请以某种方式修复代码,以使以后的维护更加容易。

什么因素会导致您说“嗯,在这里从事专业工作”,什么因素会使您从显然是业余的工作中退缩?

我倾向于只将“专业”定义为有报酬执行某项任务的人,而不是假设他们在获得报酬方面具有任何重要能力。当然,许多专业人士都能胜任出色的工作,但我常常发现自己对其他专业人士所做的可怕工作而不是业余人员提出的可怕工作感到恐惧。迄今为止,我的大部分工作都涉及挽救最初的开发人员所破坏的火车残骸项目,因此您的工作量可能会有所不同。

综上所述,选择企业质量编程通常很容易

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.