优化前端性能
1. 压缩 (Minify) 代码
压缩代码是指从 HTML、CSS 和 JavaScript 中删除不需要加载的不必要的冗余数据。这包括消除代码注释和格式、空白字符、未使用的代码、换行符等。
缩小 HTML、CSS 和 JavaScript 能有效减少前端加载时间,因为它减少了需要从服务器请求的代码量。
下面是一些压缩代码资源相关的工具:
- HTML:PageSpeed Insights,HTML Minifier。
- CSS:cssmin.js, Coverage tool in Chrome Dev Tools, YUI Compressor.
- JavaScript: JSMin, Coverage tool in Chrome Dev Tools
2. 减少 HTTP 请求
通常,一个完整的 HTTP 请求需要经历 DNS 查找,TCP 握手,浏览器发出 HTTP 请求,服务器接收请求,服务器处理请求并发回响应,浏览器接收响应等过程。你的前端的 http 请求越多,相应的所需的花费时间就越多。但是其中真正的加载数据时间所占的百分比相当小,其余大部分时间都一次次用来用来查找以及与服务器通讯了。你可以采用多种方法来减少网站的 http 请求数。
- 使用 CSS Sprites 这是减少服务器调用次数的最简单方法之一。sprite 我们不再将多个图像单独加载到站点,而是加载一个使用图像集合组合的单个图像文件。你可以使用 CSS 中的 background-image 和 background-position 属性来展示所需的图像片段。通过这样做,你可以减少所需的服务器请求数量。
- 减少使用不可控的发出大量外部请求的第三方插件。
- 防止使用指向不存在的文件的无用链接。
除此之外,现如今 SPA 应用十分多,在单页面应用中我们还可以启用服务器端渲染以加快应用程序的首屏加载。往往首屏的加载速度是对用用户感知影响巨大的。
3. 删除不必要的自定义字体
自定义字体已经变得非常流行,因为它有助于为网站添加个性化。但是,它们也以性能为代价。
自定义字体的大小可能非常大(中文字体则会相当巨大!),并且诸如 Google 字体之类的 Web 字体会将 HTTP 请求添加到外部资源。这会增加页面的加载渲染的速度。
以下是你必须在网站中使用字体时可以采取的一些优化操作:
- 将字体转换为最有效的格式:加载像 WOFF2 这样的现代格式可以比其他格式减少约 30% 的文件大小。
- 使用字体子集,删除字体集中未使用的字符:一个大而全的字体文件中包含许多可能永远不会使用的语言的字符。 通过字体子集,我们可以从字体中删除不需要的字符,只保留我们在网站上编写内容所需的内容。
- 预加载页面中使用的字体。
对于网站使用自定义字体时,我们需要在性能与美观中不断权衡与评估。加载字体文件真的很慢。
4. 压缩文件
带宽量限制了在给定时间内传递的数据量,就像一个水管。文件越大,加载时间越长。现代网站通常具有大量 HTML、CSS 和 JavaScript 以及图片等资源。
通过使用合适的方法压缩文件,你可以轻松地对缩短文件加载时间。以下是你可以使用的的两个很好的文件压缩选项:
- Gzip 流行的数据压缩和解压方法,目前所有现代浏览器都支持。Gzip 在服务器端压缩站点的 HTML、CSS 和 JavaScript 包,然后将它们发送到浏览器,在客户端,它解压缩文件并交付内容。
- Brotli 当前压缩比最高的工具。根据 CertSimple 的研究,Brotli 压缩后的 JavaScript 文件比 Gzip 小 14%,而 HTML 和 CSS 压缩率比 Gzip 好 21% 和 17%。
5. 优化图片
对于大部分网站来说,图像是至关重要的部分。互联网上 93.7% 的网站使用至少一种图像文件格式,因为它们有助于丰富内容,提高用户参与度。 然而,图像的体积往往远大于代码,它会对前端加载时间产生不利影响,因此我们需要时刻记住优化图片尺寸。
有几种方法可以优化图像:
使用 WebP 或 AVIF
使用 WebP 和 AVIF 等新图像格式,他们比 JPEG 和 PNG 等旧格式能提供更好的性能。
WebP 比 PNG 小 26%,比 JPEG 小 25-35%。AVIF 比 JPEG 小 50%,比 WebP 小 20%。
但是,目前它们的浏览器支持还不是太好。WebP 最近获得了所有最新版浏览器的支持,旧版本可能不支持它。而 AVIF 仅在 Chrome 和 Opera 中受支持。因此,你需要使用 <picture>
元素来为不同的显示设备场景提供不同的图像版本。
提供正确尺寸的图像。
另一种减少图像加载时间和提高网站性能的方法是使用响应式图像。现如今超过 50% 的流量来自智能手机和平板电脑。将图像缩放到流行的设备尺寸并使用srcset是适应不同显示设备加载不同体积的图片。
你还可以通过其他几种方法通过图像优化来减少前端加载时间。以下是你可以使用的一些其他最佳实践:
- 图像压缩
- 使用渐进式 JPEG。
- 为连接速度较慢的用户提供较小的图像。
- 使用 HTTP/2 而不是 HTTP/1.1。
- 使用image-set。
6. 延迟加载(懒加载)
延迟加载有助于进一步改善前端加载时间。使用延迟加载,网页首先只加载需要的内容,然后在用户需要时加载剩余的内容。 例如,在 Google 图片搜索结果中,首先只加载一小部分图片,更多内容显示为占位符图像,而不是实际内容,从而减少加载时间。如果用户向下滚动页面,再加载呈现实际内容。
除了延迟占位符加载外,你还可以选择其他的方式,例如原生的懒加载loading="lazy"
和“模糊图像效果”。
7. 善用缓存
每次访问网站时,我们都需要从服务器上把 HTML、CSS、JavaScript、图片等资源下载下来再显示。每次加载都会很耗时。 防止此问题的最佳方法是使用缓存。如果配置得当,浏览器会将文件缓存在本地,避免了不停地加载相同的资源。
浏览器缓存,是我们最常用的也是最有效提升加载速度的方式!
- 缓存服务器:用户请求从缓存服务器集合中发送到最近的缓存服务器。(例如:内容交付网络。将在第 9 点中详细讨论)
- 内存缓存:通过将数据的某些部分存储在内存中(例如:JavaScript 变量)
- 磁盘缓存:类似于内存缓存,但它使用磁盘存储文件,绝大部分的缓存都来自磁盘缓存。
8. 预加载 Prefetching
资源预加载是一种可用于优化前端数据加载的性能增强技术。
作为开发人员,你比浏览器更了解你的应用程序。因此你可以使用预加载来告诉浏览器接下来可能需要的资源。
预加载用户接下来可能需要的资源以减少用户点击后的等待时间。预取主要有三种类型:链接预取(Link prefetching)、DNS 预取(DNS prefetch)、预呈现(prerender)
链接预取
链接预取是一种浏览器机制,其利用浏览器空闲时间来下载或预取用户在不久的将来可能访问的文档。网页向浏览器提供一组预取提示,并在浏览器完成当前页面的加载后开始静默地拉取指定的文档并将其存储在缓存中。当用户访问其中一个预取文档时,便可以快速的从浏览器缓存中得到。 但是,链接预取仅适用于图像和 JavaScript 等可缓存资源。
DNS 预取
DNS-prefetch (DNS 预获取) 是尝试在请求资源之前解析域名。当浏览器从(第三方)服务器请求资源时,必须先将该跨域域名解析为 IP地址,然后浏览器才能发出请求。此过程称为 DNS解析。DNS 缓存可以帮助减少此延迟,而 DNS解析可以导致请求增加明显的延迟。对于打开了与许多第三方的连接的网站,此延迟可能会大大降低加载性能。
DNS 预取允许浏览器在用户浏览当前页面时在后台对网页中的链接执行 DNS 查找,以最大限度地减少用户点击链接时的延迟。
预渲染
使用预渲染,内容被预取,然后由浏览器在后台渲染,就好像内容已经渲染到一个不可见的单独选项卡中一样。当用户导航到预呈现的内容时,当前内容会立即被预呈现的内容替换。
9. 使用 CDN (内容分发网络)
CDN 是指一种透过互联网互相连接的电脑网络系统,利用最靠近每位用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户,来提供高性能、可扩展性及低成本的网络内容传递给用户。
当用户在地理位置上远离服务器的地方访问网站时,网络链路变得复杂,延迟也会越高。这时我们就可以使用 CDN 优化前端内容的加载速度。CDN 将用户请求重定向到最近的服务器
服务端优化
1、减少网络请求
- 合并请求:js、CSS
- 精灵图:CSS Sprites
- 使用地图:HTML Map
- 内联小图片:Base64Encode
2、内容分发网络CDN
- 物理上更近
- 专业的人做专业的事
3、适当的使用缓存
- 为静态资源添加Expires响应头
- 为静态资源 添加Cache-Control响应头
- 配置Apache、Nginx、Express
4、启用GZIP压缩
- 压缩率可达到60%-90%
- 支持多种类型:HTML、JS、CSS、Image
5、减少DNS查找
- 单个站点不要用太多域名
- 单次DNS查找消耗20ms-120ms
- 增加域名又能增加服务器并发
6、避免重定向301、302
- 重定向对浏览器意味着重头再来
- 每次重定向至少多花费50ms
7、配置有效的Etag、Last-Modified
- 跟浏览器说明过期规则
HTTP/1.1 200 0K
Last-Modified: Tue,12 Dec 2006 03:03:59 GMT #最后修改时间
ETag: "10c24bc-4ab- 457e1c1f" #被请求变量的实体值(记号)
Content -Length: 12195
GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified- Since: Tue,12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab- 457e1c1f"
HTTP/1.1 304 Not Modified
8、使Ajax请求可缓存
- GZIP、内容压缩都可适用
9、尽快输出第一个字节
- 尽快输出头部,使浏览器能尽快工作
- 并行下载外链的CSS
10、使用无COOKIE的域名加载静态资源
- 减少网络传输量
- 静态资源通常不需要COOKIE
客户端优化
1、把CSS放在HEAD中加载
- 能让页面更早 的开始渲染,避免闪屏
- 最好能包含关键渲染路径的样式:比如首屏的CSS
2、把JS放在BODY末尾加载
- 因为JS会阻塞HTML解析和CSS渲染
3、不要使用CSS表达式
- 看似强大,实际性能开销很大,可能导致页面卡顿
4、用外链方式引用CSS和JS
- 有效减少HTML体积
- 设置合理的缓存响应头,合理利用浏览器缓存
5、压缩JS和CSS
- 上线之前删除不必要的注释和空白
- JS中变量名压缩,混淆压缩
6、不重复加载JS
- 在IE中还是会多个请求,不能发挥缓存优势
- 意味着更长的JS执行时间
7、用GET方式发起Ajax请求
- GET方式可以缓存
- 如果是获取信息,GET更语义化
- 如果是提交信息,PUT更语义化
8、组件延迟加载
- 保障关键页资源优先加载:因为并发数限制
- 延迟加载的典型手段:Lazyload
9、减少DOM节点数
- 更多节点数会让浏览器布局、渲染时计算量更大
10、避免使用 iframe
- 会阻塞父文档的onload
- 即使是空白也比较耗时
11、减少COOKIE的体积
- 因为COOKIE每次请求都会带上
12、减少js中的DOM访问
- 对于查找到的元素,缓存在变量中
- 节点增加是合理利用DocumentFragment
- 不要用JS去频繁修改样式
13、使用更智能的事件监听机制
- 基于事件冒泡委托机制,有效减少绑定的数量
14、使用常见的图片优化手段
- 相比代码,图片体积更大
- 压缩工具:PNGCrush、JPEGTRAN、PNGQUANT
- 渐进式编码:JPG
15、不要在HTML中缩放图片
- 徒增渲染开销,提供适当尺寸即可
16、不要把图片的SRC置空
- IE、CHrome、Firefox会发起额外的主文档请求
17、资源尽量控制在25k以内
-
- iphone无法缓存25k以上的资源