ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Wiki.js 性能优化完整复盘:我们把 2.9 秒首屏压到 0.8 秒

Wiki.js 性能优化完整复盘:我们把 2.9 秒首屏压到 0.8 秒 Wiki.js 性能优化完整复盘我们把 2.9 秒首屏压到 0.8 秒【免费下载链接】wiki-Wiki.js | A modern and powerful wiki app built on Node.js项目地址: https://gitcode.com/GitHub_Trending/wiki78/wiki-这是我们一次 Wiki.js 性能优化的完整复盘。Wiki.js 是基于 Node.js 的知识库应用团队部署给五十多号人用之后投诉开始变多首屏转圈两三秒、保存完长文档要干等、周一早高峰 CPU 拉满。第一反应我们怀疑是磁盘 I/O把整块盘换成了企业级 NVMe——换完之后首屏还是 2.9 秒分毫不差。 自查支持群里三个慢的抱怨把投诉原文整理成症状清单每条都带复现场景打开首页要等 3 秒——新人用新电脑、或者清完缓存后第一次打开内网 wiki首页要转圈两秒多保存长文档要盯转圈——编辑 5000 字的文档CtrlS 之后还要等 2~3 秒才算真正保存完早高峰服务器快冒烟——周一上午九点几十人同时刷文档单 Node 进程 CPU 能贴 90% 以上持续 5 分钟。 化验单Network 面板和日志不撒谎换盘救不了说明锅不在 I/O。接下来一周我们只做一件事取证。浏览器 Network 面板、服务端日志、SQL 日志三路并行三条症状各拿到一份证据症状 1 → 证据主 JS 包 2.4MB没开压缩且反代默认返回Cache-Control: no-cache。老用户每次刷新都要重新拉一遍re-request 耗时实测 1.8 秒。根因该缓存的没缓存、该压缩的没压缩。症状 2 → 证据每个匿名请求都在完整跑一遍 server/jobs/render-page.js 里的渲染管线renderer 串联 cheerio 解析目录单页平均 380ms再看 server/core/cache.jsnew NodeCache()没传任何参数——缓存键永不过期内存只进不出一个月后缓存常驻已经涨到 480MB。根因重复劳动 没有 TTL 的缓存。症状 3 → 证据在 server/app/data.yml 的 flags 里打开sqllog跑了一天SQL 日志显示高峰期数据库连接数打满后请求开始排队接口 p95 到 1.6 秒。根因config.sample.yml 里pool的 min/max 默认是注释掉的走的保守默认值。 处方四个位置从便宜到贵浏览器侧一行配置让/_assets/缓存一年Wiki.js 的前端产物输出到/_assets/文件名带时间戳见 dev/webpack/webpack.prod.js 的filename拼接${now}内容变 URL 必变天生适合长缓存。反代只加 6 行gzip on; gzip_types text/css application/javascript application/json image/svgxml; location /_assets/ { expires 1y; add_header Cache-Control public, immutable; }作用文本类资源压缩后走一年强缓存文件名不变就直接复用本地副本。实测静态资源传输体积降约七成老用户二次访问资源请求从 24 个掉到 1 个。成本纯 Nginx 配置不改代码、不重启、不重新打包。反向代理侧匿名 GET 加页面缓存登录态坚决不碰静态资源缓存到位后页面 HTML 每次还是走完整渲染管线。对匿名读者来说这是白算的我们在 Nginx 加一层 HTML 缓存proxy_cache_path /var/cache/wiki keys_zonewiki:10m max_size1g inactive60m; location / { proxy_cache wiki; proxy_cache_valid 200 10m; # 仅匿名 GET 生效请求带鉴权 Cookie 时不启用 proxy_cache }作用匿名页面 10 分钟内命中缓存直接吐 HTML渲染管线完全绕开。实测匿名页面 p95 从 1.1 秒降到 0.3 秒单页 380ms 的渲染开销命中时归零。红线提醒登录态页面必须排除权限不同的用户一旦串了缓存就是安全事故。成本Nginx 配置 reload。服务侧给 NodeCache 补 TTL连接池别再排队内存缓存这行改动只有一行把 server/core/cache.js 里的new NodeCache()改成return new NodeCache({ stdTTL: 600, checkperiod: 120 })作用缓存键 10 分钟自动过期NodeCache 每 2 分钟清一次过期垃圾。缓存常驻内存从 480MB 回落到 170MB 并稳住相当于给只进不出的垃圾桶装了定时清运。成本1 行代码重启生效。连接池在 config.sample.yml 的pool段取消注释pool: min: 2 max: 8作用连接池就像两车道的桥默认太窄高峰期全在桥头排队。改完重启高峰接口 p95 从 1.6 秒降到 0.5 秒。成本2 行配置。另外sqllog这个开关定位完慢查询就关掉日志太吵生产常开等于让引擎舱一直录音。构建侧vendor 独立成 chunk时区表收紧配置层的便宜占完最后动构建。dev/webpack/webpack.prod.js 里splitChunks默认参数偏保守改成显式把 node_modules 归入独立 vendoroptimization: { splitChunks: { chunks: all, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: vendor, priority: 10 } } } }作用vendor 包几乎不动长缓存命中率极高应用代码更新时只有小块需要重下。主包从 2.4MB 瘦到 1.5MB。顺带把MomentTimezoneDataPlugin的startYear/endYear从 2017 到 2031 收紧到 2024 到 2028又省约 120KB。编辑器这类重组件本来就已做成动态 import见 client/client-app.js 里Editor的import()保持这个懒加载模式别动它就行。构建时间也从 9 分 20 秒降到 4 分 40 秒——前提是别让.webpack-cache增量缓存被清理脚本误删。成本需要重新打包发布一次。 复查报告前后对比与验证方法指标优化前优化后平均首屏2.9 秒0.8 秒老用户二次访问资源请求24 个 / 约 1.9MB1 个仅 HTML高峰接口 p951.6 秒0.5 秒匿名页面 p951.1 秒0.3 秒缓存常驻内存480MB 且持续增长稳定在 170MB主 JS 包体积2.4MB1.4MB构建耗时9 分 20 秒4 分 40 秒怎么确认优化真的生效浏览器 Performance 面板录一次完整加载看瀑布图Lighthouse 跑性能分服务端开响应耗时日志盯 p95 一条线最后用压测工具打 300 并发持续 60 秒看吞吐和错误率没劣化。四道都过才允许把sqllog关掉收工。️ 走过的弯路回滚掉的五个优化全量开 Gzip 连图片一起压二进制压不动还吃 CPU回滚只压文本类页面缓存 TTL 拉到 1 小时编辑完文档一小时里全是旧版本回滚成 10 分钟 保存时主动失效chunk 拆得过碎HTTP/1.1 下请求数爆炸首屏反而慢 0.3 秒合并回去登录态页面也缓存两个权限不同的用户互相看到对方内容当天回滚只留匿名 GET无脑加实例4 个容器共享一个库各自内存缓存各管各的卡顿依旧——多实例必须把 config.sample.yml 的ha标志打开。日常保养药之后的三件小事缓存短 TTL 是底线内容保存后主动失效兜底sqllog生产保持关闭靠 p95 和缓存命中率两条监控曲线代替人肉盯日志每次重新打包后确认/_assets/文件名时间戳变了老用户才会拿到新包。⏱️ 如果只有十分钟最值的三件事按成本从低到高排反代给/_assets/加 Gzip 和一年长缓存——6 行配置不重启十分钟见效config.sample.yml 里把pool的 min/max 打开——2 行配置重启生效server/core/cache.js 给NodeCache补上stdTTL和checkperiod——1 行代码重启生效。性能优化是小步快跑先用配置层拿回可见的正反馈再深入缓存和构建全程用数据说话、用日志定位最后守住登录态缓存这条安全线。照这个节奏Wiki.js 完全可以从能用变成好用。【免费下载链接】wiki-Wiki.js | A modern and powerful wiki app built on Node.js项目地址: https://gitcode.com/GitHub_Trending/wiki78/wiki-创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表