🚀闪电加载:博客性能优化全攻略

巴索罗缪·大熊

前言

这些年积累了很多前端性能优化的知识点和思路,日常工作很少涉及技术层极限优化,近期终于一点点把博客独立搭建并部署了,对之前的一些技术点进行了深度探索,最终结果也达到了预期效果,由于水平有限,写的不好的地方,敬请谅解

服务端优化

Nginx 添加压缩模块设置

gzip

Nginx 的 gzip 模块用于对 HTTP 响应进行 gzip 压缩,以减少传输数据量,提高页面加载速度,表示为 Content-Encoding 参数值为 gzip

使用

server 中添加 gzip 模块设置,如下示例中的内容,直接整个复制就能使用

    server {
        listen       443 ssl;
        server_name  yiwuan.xyz;

        ...

        # gzip
        gzip on;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
        gzip_proxied any;
        gzip_vary on;
    }
参数详解

gzip on; 启用 gzip 压缩

gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; 指定要压缩的 MIME 类型

gzip_proxied any; 启用对代理请求的响应进行压缩

gzip_vary on; 在响应头中添加 "Vary: Accept-Encoding",以便客户端和代理服务器能够缓存不同的压缩版本

gzip 模块的其他参数可以根据需要进行配置,以优化 Nginx 的 gzip 压缩功能

测试结果

添加 gzip 后的 完成 参数需要 3.03 秒

执行 5 次取平均值,最终结果为 3.02 秒

3.31  
3.24
3.03
2.79
2.77

Brotli

Brotli 是一种现代的压缩算法,通常比 gzip 提供更高的压缩率,表示为 Content-Encoding 参数值为 br

Brotli 需要单独手动安装,下面是操作步骤

安装必要依赖
sudo yum install -y epel-release
sudo yum install -y brotli brotli-devel gcc make pcre-devel zlib-devel openssl-devel git
下载 Nginx 源码和 Brotli 模块
wget http://nginx.org/download/nginx-<version>.tar.gz
tar -zxvf nginx-<version>.tar.gz
cd nginx-<version>

git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli
git submodule update --init
cd ..

注意

<version> 最好是跟本机安装的 nginx 版本保持一致,执行 nginx -v 查询版本号,然后替换 <version> 后执行上面命令

编译 Brotli 动态模块
./configure --with-compat --add-dynamic-module=./ngx_brotli
make modules
将编译好的模块复制到 Nginx 模块目录
sudo cp objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/
sudo cp objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
在 nginx.conf 文件中配置 Brotli 模块
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

http {
    brotli on;
    brotli_comp_level 11;
    brotli_buffers 16 8k;
    brotli_min_length 20;
    brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    brotli_static on;
    # brotli_vary on;
}

注意!

brotli_vary on; 这个参数是老版才有的参数,我查看了Github上的最新版文档,在新版官方似乎把这个参数去掉了

我在服务器上测试发现,如果安装的最新版模块,添加这个 brotli_vary on; 参数会报错,可能网上有些教程中有这个参数,遇到报错把这个参数去掉试试看

重启 Nginx
systemctl restart nginx
验证模块加载

在浏览器 开发者工具 中测试响应头 Content-EnCoding 值也已变成 br, 并且整体资源加载速度明显提升则说明这个模块正确安装并加载了

参数详解

brotli on; 启用 Brotli 压缩

brotli_comp_level 11; Brotli 压缩级别,范围 1-11,数字越大压缩率越高,但CPU使用率也越高

brotli_buffers 16 8k; 设置 Brotli 压缩缓冲区的数量和大小

brotli_min_length 20; 设置允许压缩的页面最小长度,单位是字节。通常设置较小的值以确保小文件也能被压缩

brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript 指定要压缩的 MIME 类型

brotli_static on; 启动对预压缩文件的支持

测试结果

注意!

load_module 加载配置必须要在 Nginx 配置文件的最顶层使用,否则会出现 load_module 指令过晚的错误

load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

开启 brotli 和 gzip 压缩两种配置, 执行 5 次取平均值,最终结果为 3.09 秒

3.92
3.11
2.95
2.63
2.84

只开启 brotli 压缩一种配置, 执行 5 次取平均值,最终结果为 3.15 秒

3.64 
2.65 
3.79 
2.76 
2.89

使用 brotli 和 gzip 压缩,以及两种压缩方式混用的方式,这三种情况结果似乎差距不大,可能和目前博客项目的资源体积不大也有关系

开启HTTP3

安装必要依赖

sudo yum install -y gcc gcc-c++ make zlib-devel pcre-devel openssl-devel

下载源码并编译

下载Nginx源代码

wget http://nginx.org/download/nginx-1.26.0.tar.gz
tar -zxvf nginx-1.26.0.tar.gz
cd nginx-1.26.0

下载quiche,下面命令是在 nginx-1.26.0 目录下执行的

quiche库是 Nginx 支持 HTTP/3 所需的库

git clone --recursive https://github.com/cloudflare/quiche

编译 Nginx

./configure --with-http_v3_module --with-cc-opt='-I../quiche/deps/boringssl/include' --with-ld-opt='-L../quiche/deps/boringssl/build/ssl -L../quiche/deps/boringssl/build/crypto' --with-http_ssl_module --with-http_v2_module --with-http_v3_module
make
sudo make install

不同版本HTTP协议的区别

HTTP/1
  • 使用多个串行的 TCP 连接来处理请求和响应

  • 每个请求都需要建立新的连接,存在头部阻塞(Head-of-Line Blocking)问题

  • 不支持请求和响应的多路复用,导致性能较低

HTTP/2
  • 引入了二进制分帧层,允许多个请求和响应在同一个连接上并行传输

  • 支持请求和响应的多路复用,减少了头部开销和提高了性能

  • 使用头部压缩和优先级控制来提高效率

HTTP/3
  • 基于 UDP 协议,使用 QUIC 传输协议

  • 解决了 TCP 连接的慢启动问题,减少了连接建立时间

  • 支持零RTT连接恢复和数据传输,提高了性能和安全性

  • 具有更好的拥塞控制和流量控制机制,适应了现代网络环境

HTTP/3 在性能上相对于 HTTP/2 和 HTTP/1 有更好的表现,主要体现在连接建立速度、并行传输、头部压缩和拥塞控制等方面。因此,推荐在现代网络环境中使用 HTTP/3 来获得更好的性能和用户体验

注意!

HTPP/3 是实验性的


客户端优化

资源优化

移除引入的第三方文件

typeface-source-code-pro

测试发现这个 https://cdn.jsdelivr.net/npm/typeface-source-code-pro@0.0.71/index.min.css css 文件用国内网络正常访问有的访问不了,单文件加载失败需要时间高达20s+,移除这个文件后发现样式变化不大,索性直接删掉

fancybox

图片预览器,并且支持各种小功能,这是它的官网 Fancyapps UI - 强大的 JavaScript UI 组件库

文章插图可以通过右键菜单 在新标签页中打开图像 满足个人需求,这个功能有点鸡肋,主要还引入了一个库,也删掉吧

改一下 landscape 主题下的 _config.yml 中的 fancybox 设置为 false,同时删除 source 目录下的 fancybox 相关文件

图片压缩

首页背景图压缩

具体操作方式为把 png 转为 webp 并压缩,由原来的 296KB 压缩成 138KB

底部 police svg 图标压缩

svg 图标从 21KB 压缩到 19KB,效果不大,这种图标其实也可以直接去掉

主页文章展示方式调整

目前博客站点首页是默认展示 10 篇文章,并且文章是自动全部展示的,由于文章首发是某金平台,然后再后期手动同步到博客站点平台,文章中的图片资源是外链形式,虽然图片资源服务器用了HTTP2进行了优化,但是资源分析中发现大量的外链图片资源也占用了相当比例的时间加载,如下

设置成文章只显示摘要的形式,在文章的 md 文件头部添加 excerpt 摘要属性

注意!

这是 landscape 主题,其他主题可能是别的参数名,思路都一样

设置好摘要后的展示效果

文章中的图片资源不额外加载了,文字比例看着有点少,再完善一下摘要内容,接下来把所有文章的摘要属性都加上

先测试一下

本地 Edge 浏览器无痕模式,禁用缓存情况下,首次加载 完成 需要 256ms

继续优化请求资源

分析请求资源大小发现 jquery-3.6.4.min.js 文件占用了单独一个请求,并且请求资源体积最大,分析 jquery 文件的使用场景,结合页面功能和代码引入,只有在 script.js 中用了

分析目前页面上用到的功能,只有 script.js 中只有一个分享按钮代码有用,而且效果还不太好,把整个 js 文件不用的功能代码删掉,后面需要什么功能单独加代码

把分享功能先去掉,这个功能没有配置选项,在 article.ejs 中把 footer 标签注释掉就行了,这时候 jquery 引入代码也注释掉

再测试一下

本地无痕模式,禁用缓存情况下,基本秒开了,完成 用时 100ms 左右

发布到云服务器测试一下

https://yiwuan.xyz 线上地址和本地 localhost 测试效果差不多,多次测试,平均用时 100ms 多一点,视觉效果上也是秒开了

测试环境参数

  • 操作系统: Win11家庭版
  • 处理器:12th Gen Intel(R) Core(TM) i5-12400 2.50 GHz
  • 机带RAM: 32.0 GB (31.7 GB 可用)
  • 系统类型:64 位操作系统, 基于 x64 的处理器
  • 浏览器:Microsoft Edge 120.0.2210.7 (正式版本) dev (64 位)
  • Nginx:1.26.0
  • Hexo: 7.1.1

小结一下

好了,目前为止博客性能优化基本就差不多了,由于极限压缩资源,删除代码,导致样式现在太丑了,还有一些小功能的莫名其妙不太好使,例如搜索,后面如果时间允许会把整个页面样式优化和功能完善的操作过程完整记录并分享出来

欢迎讨论交流,技术探索和文章整理不易,如果喜欢可以点赞支持一下 ^_^

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容