Skip to content

前端最佳实践(Frontend Performance Best Practices)

9293字约31分钟

前端优化

2024-11-22

前端最佳实践,总结了很多前端开发中,能够帮助我们提升代码质量,优化性能,提高用户体验的规则。

来源:Frontend Performance Best Practices

Github:developer-roadmap

前端最佳实践,总结了很多前端开发中,能够帮助我们提升代码质量,优化性能,提高用户体验的规则。我们可以日常开发中,尽量遵循这些规则,提升自己的开发水平和代码质量。

本文大部分内容 [ Frontend Performance Best Practices ] 文章翻译 ,部分内容根据个人理解添加。如有错误,欢迎留言指正,多谢!

PNG

对其他内容有兴趣的可以访问原网站查看更多。

高优先级

避免使用 iframes

尽量避免使用 iframe ,除非没有其他替代方案可用。 iframe 不仅会影响性能,还会影响可访问性和用户体验。此外,搜索引擎也无法对 iframe 内容进行索引。

压缩 CSS

  1. 在生产环境中,所有 CSS 文件都应该压缩,并且删除 注释、空格等。

  2. 压缩过的 CSS 文件更小,可以提高页面的加载速度。如果是访问量较大的网站,还可以有效降低带宽和服务器资源成本。

  3. 在构建或部署之前或期间,可以使用工具自动压缩文件。常用的 Vue 、React 项目,使用构建工具打包时,会自动压缩 CSS 文件。

如下,是常用的 CSS 压缩工具:

非阻塞 CSS

所有 CSS 文件都应非阻塞加载,以避免在加载 CSS 时阻塞 HTML 解析。我们可以通过将 CSS 文件放在 HTML 文档的 <head> 标签中,并使用 rel="preload" 属性来实现。

<link rel="preload" href="styles.css" as="style">
  • preload 指示浏览器在页面加载时提前加载指定的资源
  • as="style" 可以告诉浏览器这个预加载的资源是一个样式表,浏览器可以更好地优化加载过程。

相关文档:MDN-链接类型:preload

关键内联 CSS

将关键 CSS 内联到 HTML 中(比如首屏页面),可以避免在加载 CSS 文件时阻塞 HTML 解析。

  • 关键 CSS:关键 CSS 是指在用户首次加载页面时,浏览器需要立即渲染的 CSS。这些样式通常用于页面的首屏展示内容,即用户在首次进入页面不滚动的情况下可以看到的部分。

  • 内联关键 CSS:将关键 CSS 直接嵌入到 HTML 文档中,而不是通过外部 CSS 文件加载。这种做法可以减少 HTTP 请求的数量,因为浏览器不需要单独请求 CSS 文件,从而加快页面的渲染速度。

我们还可以借助压缩工具,进一步压缩内联 CSS,减少文件大小,提高加载速度。

<!-- 首屏 -->
<style>
 /* ... 这里写首屏使用CSS */
</style>
<body>
  <!-- 首屏内容 -->
</body>

可以借助工具,将首屏 CSS 提取出来,内联到 HTML 中。

避免嵌入/内联 CSS

分离 html 与 css 是一个良好的实践。有助于提高代码的可维护性,并保持网站的可访问性。可以减少 HTML 页面文件的大小和加载时间。

因此建议始终使用外部样式表或在 <head> 中嵌入 CSS(并遵循其他 CSS 性能规则)。避免在 <body> 内联 CSS 和 使用 行内式 CSS。

下面为详细说明:

  • 分离内容与设计:将 HTML(内容)与 CSS(样式)分开,可以使代码更清晰、更易于管理。这样,我们可以更方便地更新样式而不需要修改 HTML 结构。
  • 可维护性:当样式集中在外部样式表中时,维护和更新变得更加简单。我们只需修改一个文件,而不是在多个 HTML 文件中查找和替换内联样式。
  • 可访问性:良好的结构和分离的样式可以提高网站的可访问性,使得使用辅助技术的用户(如屏幕阅读器)能够更好地理解和使用网站。
  • 性能:内联 CSS 会增加 HTML 文件的大小,从而影响加载时间。使用外部样式表可以减少 HTML 文件的大小,因为样式只需在一个地方定义,并且可以被多个页面共享。
  • HTTP/2 的例外:虽然在 HTTP/2 中,内联 CSS 的性能影响有所减小,但仍然建议遵循最佳实践,以保持代码的整洁和可维护性。

分析样式表的复杂性

分析 CSS 文件的大小和复杂性,去除可能存在的冗余和重复性选择器,以及可能验证错误。

  • 分析样式表:定期分析 CSS 文件可以帮助我们识别潜在的问题,例如冗余的代码、重复的选择器和验证错误。这种分析可以提高代码的质量和性能。

  • 冗余和验证错误:冗余指的是重复的样式定义,这不仅增加了文件的大小,还可能导致样式冲突。验证错误则是指不符合 CSS 规范的代码,这可能导致样式在不同浏览器中的表现不一致。

  • 提高性能:通过去除冗余和复杂性,CSS 文件的大小可以减小,从而提高加载速度。浏览器在解析和渲染页面时,处理更简洁的 CSS 文件会更高效。

  • 组织 CSS:良好的组织结构使得 CSS 更易于维护和理解。使用 CSS 预处理器(如 SASS 或 LESS)可以帮助我们更好地组织样式,提供变量、嵌套和模块化等功能,从而提高开发效率。

我们可以在线工具帮助我们分析和修正 CSS 代码。这些工具可以自动检测冗余、错误和不符合规范的代码,帮助开发者优化样式表。

CSS 代码质量检测:可以输入网址,自动分析 CSS 代码,并给出优化建议。

PNG

除此之外,我们还可以借助定义常用样式表帮我们分离常用样式,减少冗余。可以查看相关内容:前端开发中的CSS优化 - 使用常用样式类

压缩图片/减少图片数量

尽量使用经过优化的图片,并且压缩后对用户没有直接影响。优化后的图片可以显著减少页面加载时间,从而提高用户体验。

  • 图像优化:优化图像是指通过压缩和调整图像格式来减少文件大小,而不显著影响图像质量。这可以提高网页加载速度,改善用户体验。

  • 加载速度和数据消耗:优化后的图像可以更快地加载,减少用户在浏览网页时的数据消耗。这对于移动设备用户尤其重要,因为他们的网络带宽可能有限。

  • 使用 CSS3 效果:在可能的情况下,使用 CSS3 效果(如渐变、阴影和动画)可以替代小图像。这不仅可以减少图像数量,还可以提高页面的灵活性和可维护性。

  • 使用字体代替图像文本:如果图像中包含文本,尽量使用网页字体而不是将文本嵌入图像中。这样可以提高可访问性和搜索引擎优化(SEO),同时减少图像文件的大小。

  • 使用 SVG:SVG(可缩放矢量图形)是一种基于 XML 的图像格式,适合用于图标和简单图形。SVG 文件通常比位图图像(如 JPEG 或 PNG)更小,并且可以无损缩放,适应不同的屏幕尺寸。

  • 使用 WebP:WebP 是一种现代图像格式,可以提供比 JPEG 和 PNG 更好的压缩效果。WebP 文件通常比其他格式更小,但仍然保持高质量。许多现代浏览器都支持 WebP 格式,因此可以考虑使用它来优化图像。(需用时,可以单独判断是否支持,如果不支持,则使用其他格式)

在线图片优化工具-支持 WebP、PNG、JPEG:tinyjpg.com

选择合适图片格式

根据不同的内容和需求选择合适的图片格式,以优化加载时间和性能。

  • 图像格式的选择:不同的图像格式适用于不同类型的图像。JPEG格式通常适合照片,因为它在保持较好图像质量的同时,能够有效压缩文件大小。而PNG和GIF格式则更适合需要透明背景或动画的图像。

  • 现代格式:还可以选择现代图像格式,如WebP,它提供了比JPEG和PNG更好的压缩效果,同时保持较高的图像质量。或者其他更好的格式。

我们可以通过 LightHouse 等工具,自动检测和优化图片格式。

通过 Google Chrome 打开开发者工具,进入 Lighthouse 界面, 选择相关内容,进项检测。

PNG

可以看到,Lighthouse 给出的优化建议。

PNG

压缩 JavaScript

与 CSS 同理,需要确保 生产环境 中的所有 JavaScript 文件都经过压缩,并且去除掉注释、空格和换行符。

  • 压缩 JavaScript:压缩JavaScript文件是指通过去除文件中的注释、空格和换行符来减小文件的大小。这种做法不会影响代码的功能,因为JavaScript引擎在执行时会忽略这些空白字符。
  • 性能提升:通过减少文件大小,压缩可以显著提高网页的加载速度。这对于用户体验来说至关重要,因为更快的加载时间通常会导致更高的用户满意度和更低的跳出率。
  • HTTP/2的兼容性:即使在使用HTTP/2的情况下,压缩仍然是有效的。HTTP/2具有更好的多路复用和流控制能力,但压缩仍然可以进一步优化性能。

可以使用 工具,如 UglifyJS、Terser 来压缩 JavaScript 代码。如果 使用 Webpact、vite 等工具,打包构建时可以自动压缩 JavaScript 文件。

  • terser:适用于 ES6+ 的 JavaScript 压缩器/压缩工具包。terser
  • UglifyJS:一个 JavaScript 解析器、缩小器、压缩器和美化器工具包。 UglifyJS

非阻塞 JavaScript

JavaScript 会阻塞 HTML 文档的正常解析,因此当解析器遇到 <script> 标签(特别是在 <head> 中时),它会停止解析,去获取并执行该脚本。

我们可以通过按需添加 asyncdefer 属性来非阻塞地加载 JavaScript 文件。

<script src="script.js" async></script>
<script src="script.js" defer></script>

async

当使用 async 属性时,脚本会异步加载,浏览器在下载脚本的同时继续解析 HTML 文档。一旦脚本下载完成,浏览器会立即执行该脚本,这可能会打断文档的解析顺序。

使用场景:

  • 独立脚本:当JavaScript文件不依赖于其他脚本或不需要在特定顺序下执行时,可以使用 async 。例如,第三方库(如分析工具、广告脚本等)通常可以独立加载。
  • 不影响页面渲染:如果脚本的执行不影响页面的初始渲染,可以使用 async 。因为它会在下载完成后立即执行,可能会打断HTML的解析。

defer

使用 defer 属性时,脚本也会异步加载,但它会等到整个 HTML 文档解析完成后再执行。这确保了脚本的执行顺序与它们在文档中的出现顺序一致。

使用场景:

  • 依赖顺序:当有多个脚本需要按照特定顺序执行时,使用 defer 是更合适的选择。所有带有 defer 属性的脚本会按照它们在文档中出现的顺序执行。
  • DOM完全加载后执行:如果脚本需要在DOM完全加载后执行(例如,操作DOM元素),使用 defer 是理想的选择,因为它会在文档解析完成后再执行。

JavaScript 文件的位置也会页面的加载。如果脚本放在页面的顶部,使用 asyncdefer 属性可以显著提高性能,因为它们可以避免阻塞HTML解析。而如果脚本放在 </body> 标签之前,使用这些属性的效果就不那么明显,因为此时 HTML 文档已经基本解析完成。

无论脚本的位置如何,始终使用 asyncdefer 属性都是一种良好的实践。

使用 HTTPs

HTTPS(超文本传输安全协议)是一种加密的通信协议,用于在客户端和服务器之间安全地传输数据。使用 HTTPS 可以保护用户数据免受窃听、篡改和中间人攻击。

下面为更为详细的介绍:

  • HTTPS的适用范围:最开始,HTTPS主要是为了保护网上购物时用户的支付信息和个人数据而设计的。如今,任何需要交换数据的网站都应该使用HTTPS。这包括社交媒体、博客、新闻网站等,只要涉及到用户数据的网站,都应该用上HTTPS。
  • 数据安全:HTTPS就相当于给我们的网站加了一层保护,确保用户和网站之间传输的信息是安全的。这对于保护用户的隐私和防止信息被黑客窃取来说非常重要。
  • 浏览器的限制:如今的浏览器对没有使用HTTPS的网站会有一些限制。未设置 HTTPS 会无法使用一些功能,比如获取用户的地理位置、发送推送通知,或者使用一些高级功能。这意味着,如果未设置HTTPS,可能会影响用户体验网站的完整功能。
  • SSL证书的易用性:现在设置 SSL 证书(网站开启HTTPS)比以前简单方便。还有很多免费的 SSL 证书使用,我们可以轻松地为自己的网站启用HTTPS,而不需要额外的花费。

总的来说,HTTPS是保护用户数据和提升网站安全性的关键。现在 Web 环境下,很多浏览器对没有使用 HTTPS 的网站会有一些限制,比如不能使用地理位置服务或推送通知等。并且还有会有一些安全警告提示,影响用户体验。

因此,使用HTTPS已经成为建立和维护网站的基本要求。

保持页面大小

尽可能减少页面及其资源的大小。

理想情况下,我们应该尽力将页面大小控制在 500KB 以下。根据目前网络的实际情况显示,页面的中位数大小大约在2000KB(截止到 24年11月 为 2600 KB)。根据网站的目标用户、网络连接和设备,尽可能减少总的页面的 KB 数,以提供给用户最佳的体验。

该文档中的大部分建议都旨在帮助我们减少页面大小。例如,使用压缩的图像、压缩的 JavaScript、压缩的 CSS 等。

主页面,可以设置筛选。

PNG

可以查看统计出的各种资源大小。

PNG

页面加载时间

尽可能减少页面加载时间,以求快速将内容展现给用户。一般情况下,我们希望页面在 3 秒内加载完成。

事实证明,网站或应用程序的加载速度越快,用户跳出率就越低,换句话说,失去用户或潜在客户的机会就越小。

我们可以借助在线工具,如 PageSpeed Insights 或 WebPageTest ,分析可能导致网站加载缓慢的因素,并根据 本篇文档-前端最佳实践 的清单来改善加载时间。

  • PageSpeed Insights: Google 提供的网页性能分析工具,可以帮助我们优化网页加载速度。
  • WebPageTest: 一个开源的网页性能测试工具,可以提供详细的性能报告,帮助我们找出并解决性能瓶颈。

TTFB 时间

TTFB(Time To First Byte)是浏览器从发出请求到接收到来自服务器的第一个字节所花费的时间。TTFB 时间是衡量服务器响应速度的重要指标,它直接影响到网页的加载速度。

TTFB 时间越短,服务器响应越快,用户等待的时间就越少,网页加载速度也就越快。相反,如果 TTFB 时间较长,服务器响应速度较慢,用户等待的时间就会增加,网页加载速度也会受到影响。

减少 TTFB 时间的方法有很多,比如优化服务器配置、减少服务器负载、使用 CDN、优化网络连接等。

我们需要尽可能减少 TTFB 时间 达到 1.3s 以内。

减少HTTP请求次数

每当用户访问网页时,浏览器会向服务器发送请求以获取所需的文件(如HTML、CSS、JavaScript、图像等)。每个请求都会增加加载时间,因此减少请求数量可以显著提高页面加载速度。

为了减少HTTP请求次数,我们需要始终确保每个请求的文件对网站或应用程序都是必需的。

以下为一些减少HTTP请求次数的方法:

  • 确保请求的必要性:在开发网站时,应该仔细审查每个请求的文件,确保它们都是必需的。定期审查和清理网站上的资源,去掉那些不再使用或不必要的文件,可以进一步减少HTTP请求的数量。

  • 合并文件:将多个 CSS 或 JavaScript 文件合并成一个文件,可以减少请求的数量。这意味着浏览器只需发送一次请求来获取多个资源,从而加快加载速度。

  • 启用缓存:通过启用浏览器缓存,用户在再次访问网站时可以直接从本地缓存中加载资源,而不必每次都向服务器请求。可以显著减少HTTP请求的数量,对于优化面页加载速度非常重要。

  • 使用内容分发网络(CDN):CDN可以将网站的静态资源分发到全球各地的服务器上,用户可以从离他们最近的服务器获取资源,从而加快加载速度并减少请求延迟。

使用相同的协议

避免在使用 HTTPS 的网站上加载来自 HTTP 源的文件。

如果一个使用 HTTPS 的网站加载来自 HTTP 源的文件,这种情况被称为“混合内容”。混合内容会导致安全风险,因为 HTTP 传输的数据是未加密的,可能被黑客截获或篡改。

很多现代浏览器会对混合内容发出警告,甚至可能阻止加载这些不安全的资源。有可能会影响网站的功能和用户体验。

因此,我们应该始终确保网站上的所有资源都使用相同的协议(HTTP或HTTPS)。如果网站使用HTTPS,那么所有资源(包括CSS、JavaScript、图像等)都应该使用HTTPS协议。这样可以确保用户数据在传输过程中是安全的,同时也可以避免混合内容的问题。

避免请求无法访问的文件(404)

404请求会降低您网站的性能,并对用户体验产生负面影响。除此之外,还可能导致搜索引擎爬虫抓取和索引不存在的页面,从而对网站的搜索引擎排名产生不利影响。

避免404请求的方法:

  • 定期检查网站上的链接,确保它们都是有效的。
  • 使用工具(如网站爬虫)来识别和修复损坏的链接。
  • 在删除或移动页面时,设置301重定向,将用户引导到相关的有效页面。

HTTP缓存

HTTP缓存是一种提高网站性能的技术,它允许浏览器在本地存储网站资源,以便在后续访问时快速加载。使用HTTP缓存可以减少服务器负载,加快页面加载速度,并节省带宽。

以下是一些使用HTTP缓存的要点:

  • 设置合适的缓存头:在服务器端设置合适的缓存头,如Cache-Control、Expires等,告诉浏览器哪些资源可以缓存,以及缓存多长时间。
  • 使用版本控制:为静态资源(如CSS、JavaScript、图像等)添加版本号,当资源更新时,浏览器会自动下载新的版本,而不是使用缓存的旧版本。

示例:使用 Nginx 配置缓存:

location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    expires 30d; # 设置缓存时间为30天
    add_header Cache-Control "public, no-transform"; # 允许缓存
}

有效的HTTP缓存策略可以显著提高网站的性能,减少加载时间,改善用户体验,并减轻服务器的负担。

启用 GZIP 压缩

启用Gzip压缩可以显著提高网站的性能,减少文件大小,从而加快页面加载速度。

示例: 在Nginx中启用Gzip压缩:

http {
  gzip on;  # 启用Gzip压缩
  gzip_vary on; # 启用Vary: Accept-Encoding响应头
  gzip_proxied any; # 启用代理服务器缓存Gzip压缩文件
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # 设置需要压缩的文件类型
  gzip_comp_level 6; # 设置压缩级别,级别越高压缩率越高,但CPU消耗也越高
}

中优先级

压缩 HTML

与 JavaScript 和 CSS 一样,HTML 文件通常也需要优化和压缩,只是优先级较低。

我们需要确保生产环境中的HTML文件已经被压缩和优化,并且删除注释、空格和换行符,以减少文件大小。

现在大部分的框架和构建工具,如Webpack、Gulp、Vite等,都提供了HTML压缩和优化的插件,可以帮助我们自动完成这些内容。

使用 CDN

CDN(内容分发网络)是一种将网站资源分发到全球各地的服务器上的技术,用户可以从离他们最近的服务器获取资源,从而加快加载速度并减少请求延迟。

使用 CDN 可以显著提高网站的性能,减少服务器负载,并改善用户体验。我们可以将静态资源(如CSS、JavaScript、图像等)托管在CDN上,以便用户可以从离他们最近的服务器获取资源。

初次之外,CDN还可以提供其他一些功能,如负载均衡、缓存、安全防护等。

优先使用矢量图(SVG)

矢量图(SVG)是一种基于数学公式生成的图像,它可以在任何分辨率下无限放大而不失真。与位图相比,矢量图通常较小,加载速度更快,占用内存更少。并且还可以使用 CSS 和 JavaScript 进行动画和交互设计。

矢量图(Vector Graphics)

定义:矢量图是由数学公式和几何形状(如点、线、曲线和多边形)构成的图像。它们不依赖于像素,因此可以在任何尺寸下无损缩放。

特点:

  • 可缩放性:矢量图可以无限放大或缩小而不会失去清晰度或质量。这使得它们非常适合用于标志、图标和插图等需要不同尺寸的图像。
  • 文件大小:通常,矢量图的文件大小较小,因为它们只存储图形的数学描述,而不是每个像素的信息。
  • 编辑灵活性:矢量图可以轻松编辑和修改,用户可以改变颜色、形状和大小,而不影响图像的质量。
  • 动画和交互:矢量图(如SVG格式)可以通过CSS和JavaScript进行动画和交互设计,适合现代网页设计。

常见格式:SVG、AI、EPS。

位图(Bitmap Graphics)

定义:位图是由像素组成的图像,每个像素都有特定的颜色和位置。位图图像的质量和细节取决于其分辨率(像素密度)。

特点:

  • 分辨率依赖性:位图图像在放大时会失去清晰度,出现模糊或锯齿状边缘。这是因为放大时,像素被拉伸,无法保持原有的细节。
  • 文件大小:位图图像的文件大小通常较大,尤其是在高分辨率下,因为它们需要存储每个像素的信息。
  • 编辑限制:位图图像的编辑相对复杂,修改颜色或形状可能会导致质量下降,尤其是在大幅度修改时。
  • 适用场景:位图图像适合用于照片和复杂的图像,因为它们能够捕捉细腻的色彩和细节。

常见格式:JPEG、PNG、GIF、BMP。

设置图片宽高

尽量设置 图像 元素标签的宽度和高度属性。

如果设置了高度和宽度,页面加载时会为图像保留所需的空间。然而,如果没有这些属性,浏览器就会由于不知道图像的大小,无法为其保留适当的空间。这将导致页面布局在加载过程中发生变化(布局抖动)。

避免使用 Base64 图像

尽量避免使用 Base64 编码的图像。

原因如下:

  • 增加文件大小:Base64编码会使图像文件的大小增加。这意味着使用Base64编码的图像会比直接使用二进制图像更大,从而增加页面的加载时间。
  • 初始加载延迟:由于Base64图像嵌入在HTML或CSS中,它们会在页面初次加载时被下载。这对于网络速度较慢的用户来说,可能会导致页面加载延迟,影响用户体验。
  • 缓存问题:使用Base64编码的图像无法利用浏览器的缓存机制。每次用户访问页面时,图像都会被重新下载,而不是从缓存中获取。不管是对用户还是对服务器来说,这都很不友好。

避免较大的 Base64 图像。对于较小的图像,也可可以使用更加友好的 SVG 格式。

图片懒加载

图片懒加载是一种优化网页性能的技术,它允许网页在用户滚动到页面底部时才开始加载图片,而不是在页面加载时就加载所有图片。

使用图片懒加载可以减少初始页面加载时间,节省带宽,并提高用户体验。我们可以使用 JavaScript 或现有的库(如LazyLoad.js)来实现图片懒加载。

懒加载:只有在用户需要时(例如,当图像即将进入视口时)才加载图像。这意味着离屏图像(即当前视口之外的图像)不会在页面加载时立即下载,从而提高页面的响应速度。

我们可以借助 Lighthouse 分析识别哪些图片是离屏的。从而确定哪些图像可以实施懒加载。

示例:在 Vue2 中使用插件 vue-lazyload 实现图片懒加载:

import Vue from 'vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload, {
  preLoad: 1.3,
  error: 'dist/error.png', // 加载失败时显示的图片
  loading: 'dist/loading.gif', // 加载中显示的图片
  attempt: 1
})
<!-- 使用 v-lazy 替代 原 src 属性 -->
<img v-lazy="image.url" alt="Description">

响应式图片

响应式图片是一种允许网页根据不同设备和屏幕尺寸自动选择最合适的图片的技术。

使用响应式图片可以确保网页在不同设备和屏幕尺寸上都能提供最佳的用户体验。我们可以使用 <picture> 元素和 srcset 属性来实现响应式图片。

<picture>
  <source media="(max-width: 600px)" srcset="image-small.jpg"> 
  <source media="(max-width: 1200px)" srcset="image-medium.jpg">
  <img src="image-large.jpg" alt="Description">
</picture>
<img 
  src="image-small.jpg" 
  srcset="image-small.jpg 600w, image-medium.jpg 1200w, image-large.jpg 1800w" 
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw" 
  alt="Description">

避免使用内联 JavaScript

尽量避免在文档主体中嵌入多段 JavaScript 代码。需要将内联的 JavaScript 代码重新组织到外部文件中,或者放在 <head> 中或页面末尾(在 </body> 之前)。

  • 避免内联 JavaScript:内联 JavaScrip 是指将 JavaScript 代码直接嵌入到 HTML 文档的 <body> 部分。这种做法可能导致页面加载变慢,因为浏览器在构建 DOM 时会同时加载和执行这些脚本。

  • 使用外部文件:将 JavaScript 代码放在外部文件中是更好的做法。这样可以提高代码的可维护性和重用性,同时也可以减少HTML文件的大小。外部文件可以通过 <script> 标签引入。

  • 使用 async 或 defer 属性: 使用 async 或 defer 属性可以优化 JavaScript 的加载方式:

    • async:当脚本被下载时,HTML 解析会暂停,下载完成后立即执行脚本。这适用于不依赖于 DOM 的脚本。
    • defer:脚本会在文档解析完成后执行,确保 DOM 已经构建完毕。这适用于需要在DOM 构建后执行的脚本。
  • <head> 中放置小脚本:有些小脚本插件(如分析代码)可能需要在DOM主要处理之前加载,这些脚本可以放在 <head> 中。这样可以确保它们在页面加载时尽早执行。

依赖更新

确保项目中使用的所有 JavaScript 库都是必要的(对于简单功能,优先使用原生JavaScript),并且更新到最新版本。

大多数情况下,新版本会带来优化和安全修复。我们应该尽量在项目中使用最优的插件,并确保不会因为过时的插件而减慢网站或应用程序。

如果使用 NPM 包,可以使用工具来帮助管理和更新依赖项:

  • npm-check:这是一个库,可以帮助开发者检查和更新项目中的NPM依赖项,确保使用的是最新版本。
  • Greenkeeper:这是一个自动化工具,可以监控项目的依赖项,并在新版本发布时自动建议更新。这有助于保持项目的依赖项始终处于最新状态。

JavaScript 性能

JavaScript 性能对网页应用的用户体验至关重要。复杂或低效的 JavaScript 代码可能导致执行时间过长,从而影响页面的渲染速度和响应能力。因此,检查和解决 JavaScript 中的性能问题是非常重要的。

我们可以使用 Chrome DevTools 中的 Performance 面板来分析 JavaScript 性能。

Chrome Devtools 文档:Chrome DevTools 是一个强大的开发工具,可以帮助开发者调试和优化网页应用。它提供了多种面板,包括 Elements、Console、Sources、Network、Performance 等,可以帮助开发者查看和修改网页的 HTML、CSS、JavaScript、网络请求、性能等。

使用 Service Worker

Service Worker 是一种在浏览器后台运行的脚本,可以用于实现离线缓存、后台同步等功能,从而提高网页应用的性能和用户体验。

使用 Service Worker 可以减少网络请求,加快页面加载速度,并提高应用的响应能力。同时,Service Worker 还可以用于实现离线缓存,确保用户即使在离线状态下也能访问网页。

可以通过 Service Worker 实现 PWA (渐进式网页应用)。

Service Worker Service Worker 详细介绍文档。

Cookies 是一种在用户的浏览器中存储小型数据的机制,通常用于保存用户的会话信息、偏好设置和其他状态信息。

如果项目中使用 cookies,请确保每个 cookie 的大小不超过 4096 字节,并且当前的域名下的 cookies 数量不超过 20 个。

Cookies 在 Web 服务器和浏览器之间通过 HTTP 头部进行交换。保持 cookies 的大小尽可能小是很重要的,以最小化对用户响应时间的影响。

低优先级

使用预载

预加载是一种优化技术,它允许浏览器在用户需要之前就开始加载资源,从而提高页面的加载速度和响应能力。

预加载和预取:

  • 预加载(Preloading):指的是在页面加载时,浏览器主动加载某些资源,以确保这些资源在用户需要时能够快速提供。
  • 预取(Prefetching):是一种更为主动的策略,浏览器在用户可能会访问的链接上提前下载资源。这种方式可以减少用户等待时间,因为所需的资源已经在缓存中。

<link> 标签和 rel 属性:

  • 在 HTML 中,<link> 标签用于定义与文档相关的外部资源。通过设置 rel 属性,开发者可以指定资源的关系类型,例如 rel="prefetch"rel="preload"
  • 这些指令告诉浏览器在后台下载特定的资源,以便在用户需要时能够更快地加载。

总结

  • rel="prefetch" :用于提前下载用户可能会访问的资源,主要在用户空闲时进行,不影响当前页面的加载。
  • rel="preload" :用于优先加载当前页面所需的关键资源,以提高页面的加载性能。
<link rel="preload" href="style.css" as="style">
<link rel="prefetch" href="script.js" as="script">

合并 CSS

合并 CSS 文件可以减少 HTTP 请求的数量,从而提高页面的加载速度。

不过现在基本都使用HTTP/2 ,支持多路复用,可以同时加载多个资源。因此合并 CSS 文件的优先级较低。

我们可以通过插件(如 Webpack、Gulp 等)来合并 CSS 文件,或者手动将多个 CSS 文件合并为一个文件。记得合并之后,要压缩 CSS 文件以减少文件大小。

使用 Woff2 字体

如果使用了自定义字体,建议使用 WOFF2 格式,因为它具有更好的压缩率和更快的加载速度。

字体预连接

使用 rel="preconnect" 可以提前建立与字体服务器的连接,从而加快字体的加载速度。

<link rel="preconnect" href="https://fonts.googleapis.com"> 
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

预连接是一种优化技术,它允许浏览器在用户需要之前就开始建立与外部资源的连接,从而加快资源的加载速度。通过预连接,浏览器可以提前建立与字体服务器的连接(包括 DNS 查找和 TCP 连接的建立。),从而加快字体的加载速度。

字体文件大小

尽量使用较小的字体文件,以减少加载时间。如果需要使用自定义字体,可以考虑使用字体子集化,只包含需要的字符集,从而减小字体文件的大小。

中文字体文件普遍较大,需要尽量减少使用。

避免字体闪烁

字体闪烁(Flash of Unstyled Text,简称 FOUT)是指在页面加载时,由于字体文件尚未加载完成,导致文本以默认字体显示,然后突然切换到自定义字体。为了避免这种情况,可以使用 Web 字体加载技术,如 font-display 属性,来控制字体的加载和显示方式。

检查依赖库大小

在功能被实现的情况下,尽量选择体积较小的库,或者也可以使用原生的 JavaScript 代码来实现相同的功能。

总结

前端优化是一个持续的过程,需要不断地检查和改进代码,以提高页面的加载速度和用户体验。通过使用上述的最佳实践,可以有效地优化前端代码,提高页面的性能和响应能力。