Wiki.js 提速实战:4 个真实卡顿场景,把首屏从 3 秒压进 1.5 秒
2026/9/24 14:12:07 网站建设 项目流程

Wiki.js 提速实战:4 个真实卡顿场景,把首屏从 3 秒压进 1.5 秒

【免费下载链接】wiki-Wiki.js | Next Generation Open Source Wiki项目地址: https://gitcode.com/GitHub_Trending/wiki78/wiki-

一次真实排障是这样的:某团队反馈 Wiki.js 页面"转圈慢",我们用 Lighthouse 一跑,TTFB 1.2s、JS 传输 1.8MB、编辑保存要 2s——三个瓶颈分属网络传输、静态资源和数据库三条链路。定位清楚后,没有动一行业务代码,首屏就落到了 1.5s 以内。

这篇文章按你实际会遇到的卡顿场景来组织:先讲这个症状对应的瓶颈在哪,再给解法。每个解法都标注了预期收益和落地成本,你可以按优先级挑选。全文涉及的核心路径都是仓库内真实存在的文件,方便直接定位。

场景一:首屏白屏 3 秒,卡在"传输"上

收益:减少 HTTP 往返与传输体积,首屏通常可快 30%~50%。

白屏久的第一嫌疑往往不是服务器慢,而是"路上堵":资源没压缩、没缓存、重复请求。按下面三步走:

1. 先确认 Gzip 是否生效。在 Nginx 等反向代理里打开对文本类资源的压缩,收益立竿见影(一段典型配置就是gzip on+ 把text/cssapplication/javascriptimage/svg+xml写进gzip_types,此处不贴全文,参数名对得上即可)。验证方式很简单:浏览器 DevTools 里 Network 面板看传输大小,压缩后 JS 体积一般降到原来的 1/3 左右。

2. 确认缓存失效策略。Wiki.js 的构建脚本dev/webpack/webpack.prod.js已经把资源文件名带上了构建时间戳(filename: js/[name].js?${now}),这意味着每次重新构建后浏览器一定会拉新资源——你只需要保证 CDN 或 Nginx 对/_assets/目录设置了足够长的Cache-Control,就能让"版本更新"和"日常命中缓存"两不误。

3. 关注产物体积。同一份 webpack 配置里,MinChunkSizePlugin把低于 50KB 的碎片 chunk 合并掉,图片小于url-loaderlimit: 8192时直接内联成 Base64。如果你要自己二次调优,只动两处:optimization.splitChunks(当前是name: 'vendor'+minChunks: 2)和 url-loader 的limit。例如:

optimization: { splitChunks: { name: 'vendor', minChunks: 2, maxInitialRequests: 3 }, runtimeChunk: 'single' }

改完重新构建,对比assets/js/下的 chunk 数量和体积即可验证。

场景二:匿名读者重复刷同一页,服务器 CPU 白忙

收益:热点页面请求不再穿透到数据库,CPU 占用可明显下降(压测常见 20%~40%)。

Wiki.js 的缓存分两层:

  • 内存层server/core/cache.js基于 NodeCache,进程内读写,速度最快;
  • 磁盘层config.sample.yml中的dataPath(默认./data)下会生成cache/目录,server/core/system.js启动时清空、运行中由模型层按需读写,主要给上传资源和渲染产物兜底。

三个可落地的动作:

动作怎么做难度
给内存缓存加默认 TTLNodeCache 初始化时传stdTTL(如 300 秒),防止脏数据常驻
集群部署换 Redis多实例(K8s 多 Pod、HA 模式)下内存缓存各存各的,可替换为共享的 Redis 层
定期清理磁盘缓存${dataPath}/cache做定时清理或随发布流程清理

HA 场景值得多说一句:config.sample.yml里的ha: true是给"多实例共享同一 PostgreSQL"的高可用部署准备的,此时本地内存缓存的命中率会因请求被负载均衡打散而下降,这一步换 Redis 的收益才真正显形。

场景三:编辑保存转圈,瓶颈在数据库

收益:消除慢查询与连接等待,保存/加载延迟通常降一半。

"转圈"这类写操作卡顿,十有八九发生在 SQL 层。排查分两步:

1. 打开 SQL 日志抓现行。在配置中启用flags.sqllog: true(实现见server/core/config.jsapplyFlags(),它把开关透传给 knex 的debug)。日志里按时间排序,超过 500ms 的语句基本就是元凶——常见的是缺索引的大表扫描。

2. 调连接池。config.sample.ymlpool段(注释态)对应 tarn.js 的池参数:

pool: min: 2 max: 10

原则:max不要盲目调大。它是"并发连接上限",超过 PostgreSQL 默认max_connections容量时反而会引发连接排队,把延迟推高。先观察日志里是否有"获取连接等待",再按 QPS 逐步上调。

另外,server/models/下每个模型对应一类数据访问,排障时按模型名 grep SQL 日志能快速锁定是哪条业务路径慢,这是读这份代码成本最低的方式。

场景四:高峰期偶发变慢,进程层面没留余量

收益:单实例扛住更多并发,避免 GC 抖动带来的偶发卡顿。

三个部署层的调整,都不需要改代码:

  1. 给 V8 留够堆:Node 启动参数加--max-old-space-size=2048(按容器内存配额定),减少堆满触发的 Full GC 停顿;
  2. 多核利用:用 PM2 的 cluster 模式起多实例(pm2 start-i max)——但注意这与 HA 场景二挂钩,多进程后建议同步评估 Redis 缓存与ha: true的设置,否则各实例缓存互不共享;
  3. 压测验证:用ab -n 100 -c 10 <你的页面 URL>跑一轮基准,记录 p95 延迟,再与调优后对比。

度量与固化:让提速不是一次性的

  • 建一个基线:调优前用 Lighthouse +ab各跑一次,把首屏时间、p95 延迟、CPU 占用记成三个数,之后每次改动后复测;
  • 看应用性能指标server/modules/analytics/下有 elasticapm、newrelic 等模块,启用任意一个即可拿到服务端 trace,比纯猜快得多;
  • 固化流程:把"重建前端资源 → 清dataPath/cache→ 压测对比"写成发布前的 checklist。

避坑三条

  1. 先测量再动手。没有基线数字的优化都是玄学——Gzip 是否生效、SQL 是否真的慢,都先验证再改,避免"改了一堆参数,快不快不知道"。
  2. 改 webpack 配置后必须完整重建并对比产物。dev/webpack/webpack.prod.js里时间戳缓存失效、excludeChunks按入口拆分视图模板(见dev/templates/master.pug的生成逻辑),改动 chunk 策略后确认server/views/下各模板仍能正确引用对应 JS。
  3. config.sample.yml对应配置前先备份数据库。连接池、HA 这类改动影响面是全局的,出问题时恢复成本很高。

更多安装与运行细节,可参考仓库内的 README.md。

【免费下载链接】wiki-Wiki.js | Next Generation Open Source Wiki项目地址: https://gitcode.com/GitHub_Trending/wiki78/wiki-

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询