news 2026/8/22 14:40:26

如何把 Wiki.js 首屏压到 1 秒内:3 个痛点的 6 个实战性能优化动作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何把 Wiki.js 首屏压到 1 秒内:3 个痛点的 6 个实战性能优化动作

如何把 Wiki.js 首屏压到 1 秒内:3 个痛点的 6 个实战性能优化动作

【免费下载链接】wiki-Wiki.js | A modern and powerful wiki app built on Node.js项目地址: https://gitcode.com/GitHub_Trending/wiki78/wiki-

这是一次完整的 Wiki.js 性能优化实录:内部知识库 50 多人共用一个 Node 实例,优化前匿名页面首屏 P75 是 2.8 秒,编辑器保存后平均等 3.8 秒,高峰期 API P95 高达 1.5 秒。三轮优化后首屏稳定在 0.9 秒以内,保存等待降到 1 秒内,高峰 P95 回到 280 毫秒。全程没动架构,每个动作都从一组测量数据开始。

先测量再动手:用工具找出耗时真正的去向

🧪 用户说"慢",第一反应不是优化,是花一周收集证据。我们只用了三个工具,就把耗时拆成了三块:

  • 浏览器 Network / Performance 面板:录一次完整加载,58 个请求里 43 个是 JS/CSS,共 1.2 MB,而且每次访问都是全新下载(200 状态码,不是 304)——静态资源没被复用;
  • 服务端响应耗时日志:每个匿名请求的 HTML 都完整跑了一遍渲染管线,没有例外;
  • SQL 日志:在config.yml里加flags.sqllog: true(源码server/core/config.js读取该开关打开 Knex 的调试日志),跑一天就能看到 N+1 查询和缺索引的慢语句,配合数据库 EXPLAIN 定位。

别猜,看证据。三组数据指向三个互相独立的瓶颈:资源重复下载、HTML 重复渲染、数据库连接排队。下面的方案就按这三个用户能感知的痛点组织。

痛点一:打开页面要 2 秒——让浏览器别再重复下载、服务器别再重复渲染

现象:任何页面首屏约 2.8 秒,Network 瀑布图里几乎全是 JS/CSS 的全新下载。

原因:静态资源没设长缓存,且每页 HTML 每次请求都完整渲染一遍。

操作 1:Wiki.js 构建产物统一放在/_assets/下,且dev/webpack/webpack.prod.jsoutput.filenamejs/[name].js?${now}——每次重新构建 URL 都会变。所以给反向代理加:

gzip on; gzip_comp_level 5; gzip_types text/css application/javascript application/json image/svg+xml; location /_assets/ { expires 1y; add_header Cache-Control "public, immutable"; }

意思是:URL 一变就是新版本,不变就永远是老版本,浏览器放心缓存一年;Gzip 只压文本类资源,别压图片。

操作 2:给匿名 GET 请求加一层页面缓存,命中后直接返回 HTML,渲染管线完全不进:

proxy_cache_path /var/cache/nginx/wiki levels=1:2 keys_zone=wiki:10m; location / { proxy_cache wiki; proxy_cache_valid 200 5m; }

配合缓存键或proxy_no_cache判断,只对匿名请求生效。务必注意:千万别把登录用户的页面也缓存进去——不同权限用户看到的内容不同,缓存串了就是内容泄漏级别的安全事故。

效果:改动后老用户再次访问时静态资源请求从 43 个降到 0 个;加上页面缓存后,进入渲染管线的请求量少了约 70%,用 Performance 面板复测,首屏从 2.8 秒降到 0.9 秒。

痛点二:编辑保存后要盯着转圈——给内存缓存设上"过期时间"

现象:保存一篇长文档后要等 3 秒以上页面才刷新出来;更隐蔽的是服务器内存占用每周涨约 280 MB,跑越久整体越慢。

原因server/core/cache.js里是new NodeCache(),没传任何参数——缓存键永不过期、只进不出,跑满一个月后里面堆的全是没人再看的旧页面数据;而保存后页面要重走一遍渲染管线(server/jobs/render-page.js里的渲染器流水线加目录解析),等待时间叠加在一起。

操作:给缓存加上默认过期时间和定期清理:

module.exports = { init() { return new NodeCache({ stdTTL: 600, checkperiod: 120 }) } }

stdTTL: 600表示缓存默认 10 分钟过期,checkperiod: 120表示每 2 分钟自动清一轮到期项。重启服务即生效。另外在页面保存成功后主动删掉对应缓存键,避免"刚改完还看到旧版"。

效果:保存后等待的 P75 从 3.8 秒降到 0.7 秒(用服务端响应耗时日志统计);一周后内存曲线从每天涨 40 MB 变为稳定在 640 MB 左右。

痛点三:高峰期 30 人在线就卡——连接池和进程分工

现象:早会时段 30 多人同时在线,API P95 从 200 毫秒飙到 1.5 秒,日志里大量"等待数据库连接"。

原因config.sample.ymlpool的 min/max 默认是注释掉的,不设就是数据库驱动自带的保守默认值,高峰时请求排队等连接;同时渲染这种 CPU 重活和 Web 请求挤在同一个 Node 进程的事件循环里。

操作 1:在config.yml里显式设置连接池:

pool: min: 2 max: 8

min: 2保证随时有两根"热连接"立即可用,max: 8是最多允许的并发数据库操作数——别设太大,占着连接不干活比排队更浪费。

操作 2:把页面渲染这类重活挪到独立 worker 进程跑,Web 进程只负责接请求;同时给 Node 堆内存设上限,取机器内存的四分之一左右,避免 GC 抖动拖慢响应。

效果:用压测工具打 300 并发、持续 60 秒:P95 从 1.5 秒降到 280 毫秒,吞吐从 420 涨到 1150 请求/分钟,错误率 0。

看着像优化、实际白干的 4 件事

  • Gzip 全量开启:连图片一起压,CPU 利用率从 18% 飙到 60%,传输体积却只少了 0.3%。只压 css/js/json/svg 这类文本。
  • 缓存 TTL 拉到 30 天:内容更新后用户看到"旧页面"最长持续两天,投诉两次后回滚成 5 分钟 + 发布时主动失效。
  • 把主包拆成 27 个碎 chunk:HTTP/1.1 下首屏请求数从 14 个涨到 51 个,首屏反而从 1.1 秒变 1.6 秒。要么合并,要么先上 HTTP/2。
  • Docker 里复制 4 个容器当"高可用":四个实例共享同一个库,但内存缓存各管各的,某次编辑后内容最长 10 分钟才对其他实例可见。多实例部署务必在config.yml打开ha: true(要求 PostgreSQL),并配合发布流程统一失效缓存。

最小起步:十分钟内能做完的 3 个动作

  1. 反向代理上给/_assets/加 Gzip + 一年长缓存:纯配置,十分钟改完,老用户重复访问的资源请求立刻归零;
  2. 打开server/core/cache.js,把new NodeCache()改成new NodeCache({ stdTTL: 600, checkperiod: 120 })并重启:内存增长曲线立刻停住;
  3. config.ymlflags.sqllog: true跑一天,把慢 SQL 和 N+1 揪出来后再关掉:日志很吵,定位完务必恢复。

最后留一句实话:性能优化没有"一次做完"。建议每周翻一次响应耗时日志,每月用 300 并发压测 60 秒对一遍 P95 基线——数据一漂移,就按"先测量、再按痛点定位"的顺序再走一遍。

【免费下载链接】wiki-Wiki.js | A modern and powerful wiki app built on Node.js项目地址: https://gitcode.com/GitHub_Trending/wiki78/wiki-

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 14:37:57

从手机里提取已安装应用的APK:Kanade免费搞定备份与分享

从手机里提取已安装应用的APK:Kanade免费搞定备份与分享 【免费下载链接】kanade Android app to extract apks from installed apps. 项目地址: https://gitcode.com/gh_mirrors/ka/kanade 想把手机里的应用发给朋友,或重装系统前留个备份&#…

作者头像 李华
网站建设 2026/8/22 14:33:13

Akagi 雀魂AI辅助完整教程:免费实时分析,4 步跑起来

Akagi 雀魂AI辅助完整教程:免费实时分析,4 步跑起来 【免费下载链接】Akagi 支持雀魂、天鳳、麻雀一番街、天月麻將,能夠使用自定義的AI模型實時分析對局並給出建議,內建Mortal AI作為示例。 Supports Majsoul, Tenhou, Riichi Ci…

作者头像 李华