这是一个加载慢慢慢慢慢到不行的网站,据说是由一位低级程序员鱼皮开发的,等了几分钟都没加载完:
你能想到多少种办法,来拯救这个网站的加载速度呢?
我能想到 至少 12 种,如果你能想到更多方法,先受我一拜,你真的很厉害;如果你想到的方法比我少,那么这期内容,一定会让你有收获。
下面我们就来聊聊《网站性能优化》。
如何测量网站性能?
衡量网站性能的指标非常多,比如首屏加载时间、白屏时间、可交互时间等等。
但这里为了帮助大家理解,我们主要关注用户最直观能感受到的 网站加载时长。
怎么测量网站加载时长呢?
最简单的方法就是按 F12 打开浏览器的开发者工具,切换到 Network 网络面板,刷新页面就能看到每个资源的加载时间了。
当然,还有更专业的网站性能分析工具,在本期的最后会分享。
网站性能优化的关键
虽然网站性能优化的方法非常多,但思路很简单。
问个问题,大家都收过快递吧?快递是怎么送到你家的呢?
首先,商家从仓库把商品打包,然后通过物流网络和快递员配送到你手里,你拆开包裹就能使用了。
访问网站也是一样的:从服务器获取到网站文件,然后在浏览器中加载。
要让网站访问更快,我们可以从三个方向来优化:
网站传输更快 网站体积更小 网站加载更快
下面我们就按照这些方向,来优化现在这个要加载 3 分多钟的辣鸡网站,看看最后能优化到多少秒。
一、网站传输优化
想要更快获取到网站文件,我们可以按照网站文件传输的路径 服务器 => 网络传输 => 客户端 进行优化。
升级服务器配置
毫无疑问,从服务器获取网站文件是需要网络的,服务器带宽越大,网速越快,网站文件下载越快。
所以如果你不知道怎么优化网站性能,最简单粗暴的方法就是加钱!升级服务器的带宽!
比如我把 2M 带宽的小水管升级到 8M,网站加载时长就从 3 分钟优化到了 40 秒,速度优化了 4 倍多!
不过一般来说,对于个人小网站,1-5M 就够用了,毕竟带宽挺贵的。
有同学会问了,光升级带宽就够了么?升级内存、CPU、硬盘有没有用?
这就要看你网站的类别了,对于纯静态网站来说,服务器要做的就是把网站文件发送出去,这个过程主要受带宽限制。但如果你的网站有复杂的后端逻辑,那 CPU 和内存就很重要了。
CDN 缓存加速
如果用户离我们的网站服务器较远,传输网站文件的时间就会更长,很影响体验。
如何解决这个问题呢?我们不妨类比一下网购,平台会在全国建立区域仓库,提前把热门商品分配到各地仓库,用户下单后从最近的仓库发货,而不是都从总仓发货,就能更快收货。
这就是 CDN 内容分发网络的原理,提前从源服务器获取到网站文件并缓存到全国各地的节点,用户访问时就可以直接从最近的节点获取资源。不仅延迟更低,而且能同时支持更多用户的访问。
我们使用云服务平台配置一下 CDN,指定原始网站服务器作为源站。
然后设置缓存,可以只缓存图片等媒体资源,也可以缓存整套网站文件,这里我全都要。
试一下效果,首次访问会比较慢,因为 CDN 节点还没有缓存,需要从网站服务器拉取文件;之后速度就飚起来了,直接从 40 秒优化到了 6 秒,性能优化了 6 倍多!效果显著。
不过 CDN 可是把双刃剑,按流量计费,鉴于我被刷了上万元流量费的血泪经验,建议 CDN 能不用就不用,即使要用 CDN 也要做好访问频率限制、用量封顶配置和监控告警。
浏览器缓存
除了 CDN 外,但还有一个更彻底的优化方案:让网站文件根本不用传输!
这就是 浏览器缓存 的作用,将已经请求过的网站文件存储到用户本地,下次再访问网站时,都不用去找服务器了,直接从本地加载资源。
我们可以通过 Web 服务器的 HTTP 缓存头配置或者 CDN 的浏览器缓存过期配置来更改缓存策略,更新不频繁的网站缓存时间可以设置长一些。
我这里设置为 1 小时,效果很明显,直接从 6 秒优化到了 1.69 秒,不过理论上还可以更快。
这样一来,我们就形成了一个完整的网站缓存体系:CDN 缓存解决地理距离问题,浏览器缓存解决重复访问的问题。实际情况下两种方法建议结合使用。
升级 HTTP 协议
此外,想要升级网站传输的速度,可以升级请求协议到 HTTP/2。
相比于 HTTP/1.1,HTTP/2 最大的改进是 多路复用。HTTP/1.1 虽然可以建立多个连接,但每个连接内的请求必须按顺序处理,容易产生队头阻塞问题。而 HTTP/2 在单个连接上就能同时处理多个请求,真正实现了并行传输。
升级 HTTP/2 的方式很简单,只需要在 Web 服务器(比如 Nginx)添加配置:
server {
listen 443 ssl http2; # 开启HTTP/2支持
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 其他配置...
}
如果你用的是 CDN,只需要在 CDN 配置页面一键开启 HTTP/2 即可:
测试一下效果,这次没有用到本地缓存,网站加载时长也从 6 秒缩短到了 1.6 秒,性能优化了 3 倍多!
仅仅点了一下按钮,速度就上来了,是不是没想到?
那你可能问了,现在不是还有 HTTP/3 吗?
HTTP/3 确实更先进,它基于 QUIC 协议,有更快的连接建立速度、更好的多路复用性能和更少的队头阻塞问题,但兼容性和稳定性还需要时间验证,选用 HTTP/2 就足够了。
至此,在没有改变网站本身的情况下,我们就已经把网站加载时间优化到了秒级!
二、网站体积优化
如果把网站文件当做货物,体积越小,自然传送越快。
如何优化网站文件体积呢?
核心就 2 个字 —— 压缩。
网站资源压缩
首先可以压缩网站引用的媒体资源,比如图片、音视频、字体文件等等。
很多朋友都知道这个道理,但是经常忽略。不信打开浏览器控制台看看你们自己的网站,有哪些资源可以进一步优化呢?
对很多网站来说,图片是消耗流量较多的一类资源,因此我们性能优化时,要重点关注图片。
只需要把 JPG 和 PNG 的图片统一压缩为 WebP(或 AVIF)格式,这样就能减少 20% 以上的文件体积;想追求更高的压缩比例,还可以调整图片压缩的质量,一般 80% 左右对原图的影响是可以接受的。
举个例子,我让 AI 通过编写 Python 脚本批量压缩网站内的图片,总体积直接减少了 20 多倍!
再次访问网站时,相比之前从服务器加载耗时 40 秒,这次直接缩短到了 2 秒!竟然跟使用 CDN + HTTP 2 的效果旗鼓相当,优化了 20 倍!
而且不仔细看的话,你能分辨出来优化前后图片的区别么?
需要注意的是,如果你的网站允许用户自主上传图片,一定要在后端服务器对这些图片进行压缩,否则可能就会出现下图这种惨状:一个用户头像都消耗了 5M 流量。
网站代码压缩
除了引用的资源外,网站代码本身也是可以压缩的。
代码压缩的原理很好理解,去掉代码中的空格、注释、换行,把变量名缩短就可以了。举个例子:
虽然网站代码压缩的工具网上一抓一大把(比如 Minifier 和 JSCompress),但一般我们不需要手动压缩代码。对于独立的 CSS 和 JS 脚本文件,可以直接使用 官方提供的 Min 压缩版本。
而对于目前主流的 Vue / React 前端工程化项目,一般会使用打包工具(比如 Vite / Webpack)自动对代码文件进行优化、压缩和打包。
比如经典的 Tree Shaking(摇树优化),就像摇树一样,通过静态分析,把代码中没用到的地方 “摇” 掉,从而减小 JS 文件体积。
来试试看,我的网站项目使用了 Vite 作为打包工具,添加这么一段配置,然后构建和部署项目。
对比一下,效果立竿见影!原本 363 KB 的代码,压缩后只有 159 KB,减少到了一半!
网站加载时长也进一步缩短到了 1.62 秒,又优化了 20%。
Gzip 传输压缩
除了手动压缩外,还可以在网站传输时利用 Gzip 实现自动压缩。
它的原理也很简单,浏览器和服务器之间有个约定:
1)浏览器请求网站时通过请求头告诉服务器:“我支持 gzip 压缩”。
示例 Accept-Encoding 请求头:
GET /index.html HTTP/1.1
Host: codefather.cn
Accept-Encoding: gzip, deflate, br
2)服务器收到这个请求,如果开启了 gzip 压缩,会把文件压缩后再发送,并且通过响应头告诉浏览器:“这是压缩过的”。
示例 Content-Encoding 响应头:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Encoding: gzip
Content-Length: 1024
3)浏览器收到文件后,会自动进行解压。
让我们测试一下,开启 gzip 的方式很简单,只需要在 Web 服务器中添加配置:
# 开启gzip压缩
gzip on;
# 启用gzip压缩的HTTP版本
gzip_http_version 1.1;
# 压缩级别 (1-9)
# 1: 最快压缩,压缩率最低
# 9: 最慢压缩,压缩率最高
# 6: 平衡压缩速度和压缩率的推荐值
gzip_comp_level 6;
# 小于1KB的文件不压缩
# 小文件压缩后可能反而变大,且消耗CPU资源
gzip_min_length 1024;
然后我们利用 CURL 工具分别发送不开启 Gzip 和开启 Gzip 的两个请求:
# 开启 Gzip - 详细版
curl -H "Accept-Encoding: gzip" -w "Gzip: %{size_download} bytes" -o /dev/null -s http://love.codefather.cn/assets/index-d746a13e.js
# 不开启 Gzip - 详细版
curl -H "Accept-Encoding: identity" -w "原始: %{size_download} bytes" -o /dev/null -s http://love.codefather.cn/assets/index-d746a13e.js
发现开启 Gzip 压缩后,文件大小能减少一半多!
但由于我们网站的代码文件体积本来就不大,所以开启 gzip 后的优化效果不会那么明显,但仍然建议开启。
三、网站加载优化
前面我们优化了网站传输和网站体积,HTML 等网站文件能更快到达用户浏览器。但浏览器接下来还需要加载脚本、图片等大量资源,并且动态请求后端数据。
这个过程也是可以优化的,也是最有意思的,我们可以通过很多策略来优化网站的加载速度。
加载策略
首先是几种典型的加载策略,目标是 让用户在合适的时机获得合适的内容。
1、延迟加载
懒加载 是最常用的延迟加载技术,核心思想很简单:用户看不到的内容就先不加载。这种策略特别适合长页面和图片较多的网站。
比如我们通过 HTML 图片标签自带的 lazy 属性实现懒加载:
<img src="image.jpg" loading="lazy" alt="懒加载图片">
如果想实现更严格的懒加载,可以采用 Intersection Observer 来观察图片是否进入视窗
测试一下效果,首屏只用了 339 毫秒就加载完成了,加载时长又缩短了 5 倍!
当用户滚动页面到对应的位置时,图片才开始加载,不仅大幅减少了首屏加载时间,而且节约了流量。
2、按需加载
利用 代码分割 技术,可以把原本庞大的代码包拆分成多个小模块,根据用户实际需要的功能来加载对应代码。
比如之前网站所有页面的 CSS 和 JS 文件是合并在一起的,现在可以按照页面分割成多个小文件,访问哪个页面就加载哪个页面的代码:
// 传统方式:一次性加载所有页面代码
import UserProfile from './UserProfile.vue'
// 代码分割:访问页面时才加载对应代码
const UserProfile = () => import('./UserProfile.vue')
这样一来,访问网站首页时,只按需加载和首页有关的部分代码,减少了网站首次加载的文件体积,首屏加载速度就能大幅提升,缩短到 162 毫秒,又优化了 1 倍!
之后当访问其他页面时,才会加载对应的网站文件。
3、分层加载
这个策略的核心是 先快后好,先让用户立即看到内容,再根据情况提升质量,避免用户等待的焦虑感。常见的实现方式有 2 种。
首先是 缩略图。在列表页显示低清小图,用户点击某个感兴趣的内容后再加载高清大图,这样几乎不影响用户体验,又节省了流量。实现方法很简单,为每个高清原图额外生成一个缩略图,不同的页面加载不同的图片就好。
这样一来,首屏加载的资源更小,加载时长缩短到了 118 毫秒,又优化了 25%!
还有一种更高级的策略 —— 渐进式加载,先加载低质量内容,再自动加载高质量内容。比如图片会先显示一个模糊的预览,然后逐渐变清晰。这样用户不会看到空白区域和页面错位,浏览体验更丝滑。
4、预加载
这个策略的核心是 预判用户需求,在用户需要访问之前就把资源准备好,让体验更流畅。
只需要一行代码,就能指定预加载的资源:
<link rel="prefetch" href="next-page.js">
举个典型的场景,比如用户浏览博客网站的文章列表时,可以预加载几篇文章详情页,这样用户点击时几乎秒开。
但我建议使用预加载前,最好先对网站的结构和访问情况进行分析,关键是要把握好度。预加载太少效果不明显,预加载太多又会产生流量浪费。就像你提前为客人准备了第二天的饭,结果人家当天就走了。
请求优化
除了几种加载策略外,还有个比较高级的技巧 —— 请求合并。
当你要多次调用后端接口来请求数据时,由于浏览器对同一域名有并发请求数限制(一般是 6 个左右),可能会产生请求排队和阻塞,导致数据加载耗时过长。这时,我们可以让后端提供一个聚合接口,一个接口返回某个页面需要的所有数据。不过这需要你跟后端关系不错,否则你就只能自己搭个 Node.js 中间层来做请求聚合了。
请求网站小图标也是类似的,与其一个个请求图标文件,不如利用 CSS 雪碧图 特性,把所有小图标合并为一张图片,然后在前端利用 CSS 的 background-position
来加载图片的指定位置。
这样只需要请求 1 次,就达到了同样的效果,网站的加载时长也会进一步缩短。
性能分析关键
通过前面分享的这些网站优化技巧,最终我们网站的加载时间竟然 从 180 秒优化到了 118 毫秒,性能提升了 1500 多倍!效果还是非常炸裂的,弱网环境也能很快访问网站。
但这就是极限了么?
可别忘了,我们的体积优化和加载优化并没有使用 CDN 进行演示,那如果我们同时开启 CDN 和 HTTP 2,效果又如何呢?
结果可能让大家失望了,经过我的多次测试,性能并没有明显的提升。我们对网站本身的优化越多,传输数据量就更小,再加上各种不稳定因素,CDN 在提速方面的效果可能就没那么明显了。这就是为什么我建议大家先对网站本身进行优化,CDN 还是要谨慎使用。
虽然方法教给大家了,怎么合理运用这些方法进行优化,是需要大家持续探索的。记住,性能优化一定是 “针对具体场景,先分析再优化”。因此我们也一定要准备一些网站性能分析的工具,我一般会优先使用浏览器开发者工具内置的 Lighthouse,使用很方便。点击一键分析,就能帮你进行全面的网站性能评估,还给出了很多优化建议,有一些不正是我们今天分享到的方法么?
此外,还有一些免费工具也可以试试看:
GTmetrix - 详细的瀑布图分析 WebPageTest - 全球多节点测试

优网科技秉承"专业团队、品质服务" 的经营理念,诚信务实的服务了近万家客户,成为众多世界500强、集团和上市公司的长期合作伙伴!
优网科技成立于2001年,擅长网站建设、网站与各类业务系统深度整合,致力于提供完善的企业互联网解决方案。优网科技提供PC端网站建设(品牌展示型、官方门户型、营销商务型、电子商务型、信息门户型、微信小程序定制开发、移动端应用(手机站、APP开发)、微信定制开发(微信官网、微信商城、企业微信)等一系列互联网应用服务。