• 请不要在回答技术问题时复制粘贴 AI 生成的内容
winterscott999
V2EX  ›  程序员

一个 Next.js WebGL 小游戏从 Lighthouse 40+ 到 97 的性能优化记录

  •  
  •   winterscott999 · 23h 10m ago · 774 views

    最近做了一个基于 Next.js 、React 和 PixiJS 的网页小游戏 Color Tiles

    页面看起来不复杂:一个 WebGL 棋盘、几个控制按钮,加上一些玩法介绍。但第一次跑移动端 Lighthouse 时只有四十多分。最初的报告没有保存下来,目前仓库里能复核的中间结果是 59 分:

    • LCP:11.36 s
    • TBT:625 ms
    • 首屏传输量:2.33 MB

    经过几轮优化后,生产构建的移动端 Lighthouse 达到 97 分,桌面端 100 分:

    • LCP:2.29 s ,下降约 80%
    • TBT:135 ms ,下降约 78%
    • 首屏传输量:509 KB ,下降约 78%
    • CLS:保持为 0

    这次比较有效的改动主要有这些:

    1. 不再整包引入 pixi.js-legacy,改为从 @pixi/core@pixi/display@pixi/sprite 等模块按需引入,并直接使用 WebGL Renderer 。
    2. 把只能在浏览器运行的游戏模块改成动态加载,同时保留尺寸稳定的 loading 界面,避免布局跳动。
    3. 把教程 GIF 转成 MP4 ,并延迟到用户真正打开教程时再加载。
    4. 图片转为 WebP ,补全响应式 sizes,并通过 Cloudflare Image Resizing 输出适合设备尺寸的版本。
    5. 把图片迁移到独立的 img.colortilesgame.net CDN 子域名,静态资源缓存延长到一年,并使用 immutable。同时用 preconnect 提前完成新域名的连接。
    6. 开启 Next.js 的实验性 inlineCss,把 CSS 放进 HTML ,减少首次渲染中的一次阻塞请求。
    7. 排行榜 API 改为接近视口或游戏结束后再请求,不再与棋盘初始化争抢首屏资源。

    过程中也踩了几个坑。例如,一开始 preload 了完整背景图,以为可以改善 LCP ,结果大图反而提前占用网络。后来只 preload 4.8 KB 的占位图,效果更合理。

    另一个体会是,不要只盯着 Lighthouse 总分。中间报告的 FCP 已经不到 1 秒,真正的问题是 11 秒的 LCP 、主线程阻塞和过大的资源量。把非关键工作移出首屏,比继续抠 FCP 更有效。

    线上版本:

    https://colortilesgame.net

    更完整的过程、代码片段、数据和取舍写在 Medium:

    https://medium.com/@winterscott999/from-the-40s-to-97-how-we-cut-the-initial-load-of-a-next-js-webgl-game-by-nearly-80-d04e803a27ac

    欢迎交流 WebGL 游戏、Next.js 或 Lighthouse 优化方面的经验。

    2 replies    2026-07-21 17:50:10 +08:00
    yinglian
        1
    yinglian  
       22h 46m ago
    这游戏滑动有点小延迟,其他还好
    winterscott999
        2
    winterscott999  
    OP
       22h 30m ago
    @yinglian 回头优化一下,应该是时间缩短就可以。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5367 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 08:21 · PVG 16:21 · LAX 01:21 · JFK 04:21
    ♥ Do have faith in what you're doing.