编写快速加载 HTML 页面的小贴士

这些小贴士基于通用知识和实验。

优化的网页不仅为您的访问者提供更快的响应网站,还能减少 Web 服务器和互联网连接的负载。这对高流量网站或由于突发事件(例如突发新闻报道)而出现流量激增的网站至关重要。

优化页面加载性能不仅适用于窄带拨号或移动设备访问者浏览的内容。这对宽带内容同样重要,即使对于拥有最快连接的访问者,也能带来显著的改进。

小贴士

减轻页面重量

页面重量是影响页面加载性能的最重要因素。

通过消除不必要的空格和注释(通常称为最小化),以及将内联脚本和 CSS 移动到外部文件,可以减轻页面重量,从而在无需对页面结构进行大量更改的情况下提高下载性能。

诸如 HTML Tidy 之类的工具可以自动从有效的 HTML 源代码中删除前导空格和额外的空行。其他工具可以“压缩” JavaScript,方法是重新格式化源代码或通过混淆源代码并将较长的标识符替换为较短的版本。

最小化文件数量

减少网页中引用的文件数量,可以减少下载页面所需的 HTTP 连接次数,从而缩短发送请求和接收响应的时间。

根据浏览器的缓存设置,它可能会为每个引用的文件发送一个带有 If-Modified-Since 标头的请求,询问该文件是否自上次下载后已修改。花费太多时间查询引用的文件的上次修改时间会导致网页的初始显示延迟,因为浏览器必须在渲染页面之前检查每个文件的修改时间。

如果您在 CSS 中大量使用背景图像,可以通过将图像合并成一张称为图像精灵的图像来减少所需的 HTTP 查询次数。然后,您只需在每次需要背景图像时应用相同的图像,并相应地调整 x/y 坐标即可。此技巧最适合尺寸有限的元素,并不适用于所有背景图像的使用场景。但是,更少的 HTTP 请求和单图像缓存有助于缩短页面加载时间。

使用内容分发网络 (CDN)

对于本文而言,CDN 是一种缩短服务器与访问者之间物理距离的方法。随着服务器源和访问者之间距离的增加,加载时间也会增加。假设您的网站服务器位于美国,而访问者来自印度;与美国访问者相比,印度访问者的页面加载时间将长得多。

CDN 是一组地理分布式服务器,这些服务器协同工作,缩短用户与您网站之间的距离。CDN 会存储您网站的缓存版本,并通过最靠近用户的网络节点向访问者提供这些版本,从而减少 延迟

进一步阅读

减少域名查询

由于每个独立的域名都会在 DNS 查询中花费时间,因此页面加载时间会随着 CSS 链接和 JavaScript 以及图像 src 中出现的独立域名数量的增加而增加。

这可能并不总是可行的;但是,您应该始终注意仅在页面中使用必要的最小数量的独立域名。

缓存重复使用的内容

确保所有可以缓存的内容都已缓存,并设置适当的过期时间。

尤其要注意 Last-Modified 标头。它允许高效地缓存页面;通过此标头,可以向用户代理传达有关其想要加载的文件的信息,例如上次修改时间。大多数 Web 服务器会根据文件系统中存储的上次修改日期,自动将 Last-Modified 标头附加到静态页面(例如 .html.css)。对于动态页面(例如 .php.aspx),当然无法这样做,并且不会发送该标头。

因此,对于动态生成的页面,对此主题进行一些研究将大有裨益。这可能有点复杂,但它会在通常不可缓存的页面上节省大量页面请求。

更多信息

  1. HTTP 条件获取用于 RSS 黑客
  2. HTTP 304:未修改
  3. 维基百科上的 HTTP ETag
  4. HTTP 中的缓存

以最佳顺序排列页面组件

首先下载页面内容,以及初始显示可能需要的任何 CSS 或 JavaScript,以便用户在页面加载期间获得最快的明显响应。此内容通常是文本,因此可以在传输过程中从文本压缩中获益,从而为用户提供更快的响应。

任何需要页面完全加载后才能使用的动态功能,都应该先禁用,然后仅在页面加载完毕后启用。这会导致 JavaScript 在页面内容之后加载,从而改善页面的整体加载外观。

减少内联脚本的数量

内联脚本可能会导致页面加载速度变慢,因为解析器必须假设内联脚本可能会在解析过程中修改页面结构。通常减少内联脚本的使用,尤其减少 document.write() 用于输出内容的使用,可以提高页面的整体加载速度。使用 DOM API 操作页面内容,而不是 document.write()

使用现代 CSS 和有效的标记

使用现代 CSS 可以减少标记量,可以减少对(间隔)图像的需求(在布局方面),并且通常可以替换带有样式化的文本的图像——这些图像的“成本”远高于等效的文本和 CSS。

使用有效的标记还有其他优势。首先,浏览器在解析 HTML 时无需执行错误更正(这与是否允许用户输入格式变化,然后以编程方式“更正”或规范化它;或者是否应该强制执行严格的、不容忍的输入格式这一哲学问题无关)。

此外,有效的标记允许自由使用可以预处理您的网页的其他工具。例如,HTML Tidy 可以删除空格和可选的结束标签;但是,它会拒绝在标记错误严重的页面上运行。

将内容分块

用于布局的表格是一种遗留方法,现在应该不再使用。应该使用利用 浮动定位Flexbox网格 的布局。

表格仍然被视为有效的标记,但应该用于显示表格数据。为了帮助浏览器更快地渲染您的页面,您应该避免嵌套表格。

而不是像以下代码一样深度嵌套表格

html
<table>
  <table>
    <table></table>
  </table>
</table>

应该使用非嵌套表格或 div,如以下代码所示

html
<table></table>
<table></table>
<table></table>

另请参阅:CSS 弹性盒子布局CSS 网格布局 规范。

最小化和压缩 SVG 资源

大多数绘图应用程序生成的 SVG 通常包含不必要的元数据,可以将其删除。配置您的服务器,对 SVG 资源应用 gzip 压缩。

最小化和压缩您的图像

大型图像会导致页面加载时间更长。请考虑在将图像添加到页面之前压缩您的图像,使用 Photoshop 等图像处理工具中的内置压缩功能,或使用专用的工具,如 Compress JpegTiny PNG

为图像和表格指定尺寸

如果浏览器可以立即确定图像和表格的高度和/或宽度,它将能够在无需重新排列内容的情况下显示网页。这不仅加快了页面的显示速度,还防止了页面加载完成后页面布局出现恼人的变化。因此,在可能的情况下,应该为图像指定 heightwidth

表格应该使用 CSS 选择器:属性组合

css
table-layout: fixed;

并且应该使用 <col><colgroup> 元素指定列的宽度。

对图像使用延迟加载

默认情况下,图像以急切方式加载;也就是说,图像会在 HTML 中处理后立即获取并渲染。所有急切加载的图像都在窗口的 load 事件发送之前渲染。切换到图像延迟加载会告诉浏览器等到需要绘制 视觉视窗 时再加载图像。

要对图像进行延迟加载,请将其 loading 属性指定为 lazy。设置后,图像只会在需要时加载。

html
<img src="./images/footerlogo.jpg" loading="lazy" alt="MDN logo" />

请注意,延迟加载的图像可能在触发 load 事件时不可用。您可以通过检查其布尔值 complete 属性的值是否为 true 来确定给定图像是否已加载。

明智地选择您的用户代理需求

为了在页面设计中获得最大的改进,请确保为项目指定合理的用户代理需求。不要要求您的内容在所有浏览器中都以像素完美的方式显示,尤其是在低版本浏览器中。

理想情况下,您的基本最低要求应基于对支持相关标准的现代浏览器的考虑。这可能包括 Firefox、Google Chrome、Opera 和 Safari 的最新版本。

但是请注意,本文中列出的许多技巧都是适用于任何用户代理的常识技术,并且可以应用于任何网页,而与浏览器支持需求无关。

如果可能,使用 async 和 defer

使 JavaScript 脚本与 asyncdefer 属性兼容,并在可能的情况下使用 async,尤其是在您有多个脚本元素时。

这样,页面可以在 JavaScript 仍在加载时停止渲染。否则,浏览器将不会渲染任何在没有这些属性的脚本元素之后的元素。

注意:虽然这些属性在页面首次加载时确实非常有用,但您应该使用它们,但不要假设它们会在所有浏览器中都能正常工作。如果您已经遵循所有 JavaScript 最佳实践,则无需更改您的代码。

示例页面结构

  • <html>
    • <head>
      • <link> 页面外观所需的 CSS 文件。为提高性能,请将文件数量降至最低,同时将不相关的 CSS 保留在单独的文件中以进行维护。
      • <script> 页面加载期间 **需要** 的函数的 JavaScript 文件,但任何与交互相关的 JavaScript 只能在页面加载后运行。为提高性能,请将文件数量降至最低,同时将不相关的 JavaScript 保留在单独的文件中以进行维护。
    • <body> 用户可见的页面内容,以小块的形式(<header>/ <main>/ <table>),可以在不等待整个页面下载的情况下显示。
      • <script> 用于执行交互性的任何脚本。交互脚本通常只能在页面完全加载且所有必要的对象都已初始化后才能运行。在页面内容之前加载这些脚本没有必要。这只会减慢页面加载的初始外观。为提高性能,请将文件数量降至最低,同时将不相关的 JavaScript 保留在单独的文件中以进行维护。

另请参阅