19.1 加载外部脚本
脚本主要有两种类型,一种是从外部文件(使用纯文本格式)加载的脚本,另一种是嵌入在页面中的脚本(这一种将在下一节讲解)。这同外部样式表和嵌入样式表的概念是类似的。
同为页面添加样式表一样,从外部文件加载脚本通常比在HTML中嵌入脚本要好一些(如图19.1.1所示)。这样做的好处也是类似的,即可以在需要某一脚本的每个页面加载同一个JavaScript文件。需要对脚本进行修改时,就可以仅编辑一个脚本,而不是在各个单独的HTML页面更新相似的脚本。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8" />
- <title>Loading an External Script</title>
- <link rel="stylesheet" href="css/base.css" />
- </head>
- <body>
- ... All of your HTML content is here ...
- <script src="behavior.js"></script>
- </body>
- </html>
图19.1.1 script
元素的src
属性引用脚本的URL。在大多数情况下,最好在页面的最末尾加载脚本,即结束标记的前面。也可以在页面的
head
元素中加载脚本,如图19.1.2所示,但这样做会影响页面显示的速率。更多信息参见“脚本和性能的最佳实践”
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8" />
- <title>Loading an External Script</title>
- <!-- 在加载任何JS文件之前加载样式表 -->
- <link rel="stylesheet" href="base.css" />
- <script src="behavior.js"></script>
- </head>
- <body>
- …… 所有HTML内容写在这里 ……
- </body>
- </html>
图19.1.2 在这个例子中,脚本是在head
中加载的。它位于link
元素的后面,因此不会影响CSS文件先于脚本开始加载。关于为什么要尽可能地避免在head
中加载脚本,参见“脚本和性能的最佳实践”
无论是加载外部脚本还是嵌入脚本,均使用script
(脚本)元素。
加载外部脚本的方法
输入,这里的
script.js
是外部脚本在服务器上的位置及文件名。应该尽可能地将脚本元素放在结束标记之前(参见图19.1.1),而不是放在文档的
head
元素里(参见图19.1.2)。
提示 一个页面可以加载多个JavaScript文件,可以包含多个嵌入的脚本(参见图19.2.1)。在默认情况下,浏览器会按照脚本在HTML中出现的顺序对它们进行加载(如果需要的话)和执行。关于为什么需要尽可能地避免加载多个脚本,参见“脚本和性能的最佳实践”。
提示 不理解JavaScript的浏览器(数量很少)或用户禁用了JavaScript的浏览器会忽略JavaScript文件。因此要确保页面不依赖于JavaScript为用户提供对内容的可访问性和基本体验。
提示 为了保持组织文件良好,通常将JavaScript文件放在一个子文件夹中(常用的名称包括
js
、scripts
等)。src
属性需要反映这一点,就像指向某一资源的其他URL一样。例如,如果图19.1.1中的文件位于名为assets/js/
的文件夹内,则应输入。(这只是一个示例,还有其他表示URL的方式,参见1.7节。)
提示 图19.1.1和图19.1.2中的JavaScript文件名为behavior.js,也可以指定其他有效的名称,只要以.js为扩展名。
提示 从技术上说,为页面添加JavaScript还有第三种方式:内联脚本。内联脚本是直接在HTML中特定元素属性上指定的JavaScript片段。在这里提到这种方式是为了告诉你,应该避免使用它们,就像避免使用内联样式表一样。正如内联样式表将HTML和CSS混合在一起,内联脚本则将HTML和JavaScript纠缠在一起,这与将它们分开的最佳实践不符。
脚本和性能的最佳实践
关于脚本和页面性能最佳实践的详细讨论超出了本书的范围,不过这里仍会提到几个影响较大的要点。
最重要的一点,理解浏览器如何处理脚本是很有用的。随着页面的加载,在默认情况下,浏览器会按照脚本在HTML中出现的顺序依次对每个脚本进行下载(对于外部脚本)、解析和执行。在处理脚本的过程中,浏览器既不会下载该
script
元素后面出现的内容(哪怕是文本),也不会呈现这些内容。这称为阻塞行为(blocking behavior)。这条规则对嵌入脚本和外部脚本都有效。可以想象,这会影响页面的呈现速率,影响的程度取决于脚本的大小和它执行的动作。
大多数浏览器都会这样做,因为JavaScript可能包含其他脚本所依赖的代码、立即生成内容的代码或对页面进行调整的代码。浏览器需要在结束呈现之前考虑所有这些问题。
那么如何避免这一点呢?消除JavaScript阻塞的最简单的方法就是将所有的
script
元素放置在HTML结束之前,即结束标记的前面。随便花点儿时间浏览一下其他人的网站,不难发现脚本是在
head
元素中加载的。除了少数必须这样做的情况,通常认为这是一种过时的做法,应当尽可能地避免。(必须这样做的一种情况就是加载第11章所述的HTML5剃刀。)如果确实需要在head
中加载脚本,也要将它们放置在所有加载CSS文件的link
元素之后(这也是出于性能的考虑)。另一种简单的加快脚本加载速率的方法就是将JavaScript放在同一个文件中(或尽可能少的一些文件中)并压缩代码。通常,压缩代码会去除换行、注释及额外的空格(以及其他同未压缩的代码存在差异的地方)。你可以想象一下只在一个很长的行内编写代码,而永远不敲回车键。
可以使用以下工具压缩脚本:
- Google Closure Compiler
http://code.google.com/closure/compiler/(供下载的版本及文档)
http://closure-compiler.appspot.com(在线版本)
- YUI Compressor
http://developer.yahoo.com/yui/compressor/(供下载的版本及文档)
http://refresh-sf.com/yui/(非官方的在线版本)
上述每个工具都能减小文件的大小,而压缩的结果则因脚本而异。通常,浏览器加载一个文件比加载两个文件(或更多的文件)要快一些,即便单个文件的大小比不同文件的总大小还要大一些(除非大得多)。
这是两种常用且强大的方法,但真正说起来,它们也只是一些皮毛的东西。关于脚本加载的方法及其优化,强烈推荐Steve Souders所著的Even Faster Web Sites1(O'Reilly Media,2009)一书,以及他的网站www.stevesouders.com。不过有言在先,Souders的某些讨论相对技术一些。
1 中文版《高性能网站建设进阶指南》已由电子工业出版社出版。——译者注