前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【腾讯云前端性能优化大赛】WordPress 首屏极限优化探索

【腾讯云前端性能优化大赛】WordPress 首屏极限优化探索

原创
作者头像
上山打老虎了
修改2022-01-05 16:02:03
1.2K1
修改2022-01-05 16:02:03
举报
文章被收录于专栏:Article

这是当前的 Lighthouse 评分,在此基础上探索一些细节优化。

当前现状

性能的好坏永远只是阶段性的,非永久的,随着一个项目的迭代,性能也会随之产生变化。

配置

  • 1核 1GB 1Mbps
  • 系统盘:普通云硬盘
  • 网络:基础网络

同时运行了 6 个容器,Nginx 开启了 HTTPS

  • nginx
  • php:fpm
  • egg:v1
  • cnpmjs.org
  • gitea/gitea:latest
  • mysql:5.5

站点是基于 WordPress 的,所以非纯静态,动态站点。抛开环境去谈目标不切实际,在此基础上我尝试去做一些优化:

本地测试环境: MacBook Pro 8G + Chrome 无痕模式 + 每次刷新页面 disabled cache

监测数据情况

优化内容

静态资源

三大类中首先关注静态资源,资源的加载有大小和懒加载这两个优化方向,看了一下服务器是开启了 GZIP 压缩的。

问题:

  • main.js 没有压缩,虽然加上注释也就只有 42 行代码,体积 1.3K
  • jquery 压缩后的代码体积 86K
  • lightbox.js 9.3K,首屏也是加载的
  • 文章图片没有懒加载

原始静态资源大小

优化方案

  1. main.js 压缩后 281B
  2. 首屏 JQ 会用到,可以引用公共CDN的路径,这样的好处是首次访问的用户有概率可以命中该版本的 JQ ,从而走本地缓存,同时也可以降低我的服务器带宽压力
  3. 鉴于博客的群体访问采用的浏览器版本不低,因此移除 lazyload.js,直接使用原生的的 lazyload 属性。Chrome 支持 ~
  4. 文章图片使用原生 lazyload

API 报错 来源于 Google Adense 广告模块,这个无解,属于第三方功能,需要整体移除,但观察后发现实际不影响首页的加载速度,本身是异步执行。

结果

隔了一天再看统计数据,发现首屏访问速度并没有多少提升,从资源统计数据上来看,依旧存在静态资源访问耗时较长的问题。这里面有一大部分图片是文章内容的图片,由于访问量不大,图床又想要额外费用,因此直接存本地了。这里没有使用 CDN 直接优化,因为这是外物,不能因为优化而优化,在没有找到优化点之前去一顿操作非明智之举。

细分一下我看到静态资源的加载耗时,发现普遍集中在图片资源中:

于是我按照排序拿了一个耗时相对较长的链接访问看看,确实挺长

有时候 TTFB 可以达到 1S 以上,那 TTFB 是一个优化方向。因为 TTFB 是反映服务端响应速度的重要指标,但其他的静态资源有时候并没有这么慢。

SSL 连接配置

鉴于我的服务器配置较低,TTFB 值又很高,参照之前的瀑布图觉得 SSL 耗时占用了一定的比重,可以优化,于是调整了默认的配置

代码语言:javascript
复制
ssl_session_cache        shared:SSL:1m;
ssl_session_timeout      60m;
ssl_session_tickets      on;
ssl_stapling             on;
ssl_stapling_verify      on;

resolver                 8.8.4.4 8.8.8.8  valid=300s;
resolver_timeout         5s;
ssl_prefer_server_ciphers on;

ssl_protocols  TLSv1.2 TLSv1.3;

ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload";
add_header  X-Frame-Options  deny;

但是根据结果反馈是负增长…. SSL 连接耗时反而增长了,但是本地测试数据并没有延长。

优化前:

优化后:

Nginx 耗时日志

由于 SSL 配置并没有效果,所以还是要结合日志查看具体的耗时链路

设置日志输出:

代码语言:javascript
复制
log_format apm '"$time_local" client=$remote_addr '
               'method=$request_method request="$request" '
               'request_length=$request_length '
               'status=$status bytes_sent=$bytes_sent '
               'body_bytes_sent=$body_bytes_sent '
               'referer=$http_referer '
               'user_agent="$http_user_agent" '
               'upstream_addr=$upstream_addr '
               'upstream_status=$upstream_status '
               'request_time=$request_time '
               'upstream_response_time=$upstream_response_time '
               'upstream_connect_time=$upstream_connect_time '
               'upstream_header_time=$upstream_header_time';

值得关注的是下面几个参数:

  • $upstream_response_time : Time between establish a connection to the upstream server and receiving the last byte of the response body.
  • $request_time : This is the Full request time , Starting from , the nginx reading the bytes from the client , till Nginx sends the last byte of the response body to the client.
  • $upstream_connect_time : The time spent establishing a connection with the upstream server
  • $upstream_header_time : Time between establishing a connection to an upstream server and receiving the first byte of the response header.

取两条日志观察:

代码语言:javascript
复制
"28/Dec/2021:14:42:53 +0000" client=114.85.34.238 method=GET request="GET /%e7%ae%97%e6%b3%95-practice-day-1.html HTTP/2.0" request_length=464 status=200 bytes_sent=6306 body_bytes_sent=5886 referer=- user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" upstream_addr=unix:/tmp/php7-fpm.sock upstream_status=200 request_time=0.206 upstream_response_time=0.204 upstream_connect_time=0.000 upstream_header_time=0.200
"28/Dec/2021:14:42:53 +0000" client=114.85.34.238 method=GET request="GET /wp-content/themes/neat/ajax-comment/app.css?ver=1.0.0 HTTP/2.0" request_length=140 status=200 bytes_sent=783 body_bytes_sent=520 referer=https://www.noxxxx.com/%e7%ae%97%e6%b3%95-practice-day-1.html user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" upstream_addr=- upstream_status=- request_time=0.000 upstream_response_time=- upstream_connect_time=- upstream_header_time=-

第一条是需要执行 PHP 代码的,所以需要连接 php-fpm 的容器,可以看到 upstream_response_time 有 200ms 以上。

通过查阅资料,PHP-FPM 一共有三种工作模式:ondemand,static,dynamic(内存优先、静态池、服务优先)。

静态和内存优先的方式我调试了一下,发现耗时最低只能在200上下,而服务优先的这种模式,最低能到 140ms 的延时。

配置如下:

代码语言:javascript
复制
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 6

测试截图:

然而这种模式对于小内存的机器来说是灾难,因为当我想关闭容器的时候发现内存不够,无法关闭。

内存占用直线飙升,通过占用内存换取低延时高处理性能,但是整体会影响服务器的稳定。默认 php-fpm 走的是 dynamic 模式

采用 static 模式,经过测试 pm.max_children = 5 对于 1G 内存的机器来说相对合适一点,测试下来,普遍稳定在 400 ms上下,最高不超过 1.3s,最低可以到 207ms,而 max_children 设置为 5 10 20,在内存占用上差距不大,不过考虑到小流量的访问场景,5 的取值对应的耗时目前可以接受。

PHP 版本升级

7.3.6 升级到 7.4.27 从结果上来看,提升不大,如果是 5 => 7 ,那是一个质变,小版本的升级暂时看不出太多的性能问题,期待 8 版本的镜像后续能带来的性能变化。

Nginx 缓存

优化到这里的时候我思考了一下,首先静态资源是有缓存的,那么是否可以对动态语言进行缓存?也就是说我避开每次重复执行 PHP 代码来提高页面直出的速度。

首先在 /etc/nginx/nginx.conf: 添加如下代码,设置 fastcgi 缓存路径和缓存 key。

代码语言:javascript
复制
fastcgi_cache_path /etc/nginx-cache levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

然后在处理 PHP 的配置文件中加入缓存配置

代码语言:javascript
复制
location ~ [^/]\.php(/|$) {
    fastcgi_cache phpcache; # The name of the cache key-zone to use
    fastcgi_cache_valid 200 30m; # What to cache: 'Code 200' responses, for half an hour
    fastcgi_cache_methods GET HEAD; # What to cache: only GET and HEAD requests (not POST)
    add_header X-Fastcgi-Cache $upstream_cache_status; # Add header so we can see if the cache hits or misses
}

带来的效果非常可观:

文章内页速度:

降幅达 15倍,而仅仅需要配置一下 Nginx,收益很高。

未来可以优化的点:

Mysql 版本,目前使用的是 5.5,但就像大多数的公司项目面临的问题,不太可能升级所有的依赖,风险是其中一个因素,更何况还没有做过相关测试,改动代价太高,暂时不准备动了。

总结:

在利用内存的情况下,可以将之前的 300 多 ms 降低到 150ms 再到 15 ms,可以在低内存的机器上兼顾服务器的利用率和网站体验感。

还有一种优化思路就是利用语言、框架、依赖、服务器、http1.1 ->2 等周边,通过版本提升来试图提高性能,或者替换性能更优服务来降低首屏耗时。这种方式在现实项目中有的成本会高一些,但是相对的收益也高,比起纯前端去做资源的打包压缩合并,见效来的更快,就好比切换到http2,原先的雪碧图方案重要性就会降低很多。

但这不是说不要做前端的性能优化,而是要权衡性价比,而不是忽略本身的问题。

所以说性能优化这件事,在某种程度上依旧是空间换时间的方式,通过内存消耗来换取更快的响应速度,只不过针对具体问题要具体分析,要到问题结合实际再做适度优化,以最少的成本换取最快的速度,没有银弹这件事同样适用于性能优化,不能眉毛胡子一把抓。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 当前现状
  • 配置
  • 监测数据情况
  • 优化内容
    • 静态资源
      • 结果
        • SSL 连接配置
          • Nginx 耗时日志
            • PHP 版本升级
              • Nginx 缓存
                • 未来可以优化的点:
                • 总结:
                相关产品与服务
                云服务器
                云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档