likes
comments
collection
share

mock server端冗余模块优化next.js dev/build 性能

作者站长头像
站长
· 阅读数 75

随着项目的增加,运行next dev时候电脑越来越卡了,注意到 next-server这个进程随着热更新的次数增加内存也占用的越来越大。

进行一些排查之后,发现了一个优化点:

就是在server端导入了比较多的冗余module,可以通过mock某些不需要在server导入的依赖,优化 next.js dev/build 性能。

实现原理

举个例子

在某个页面需要调用依赖a,但是a不会在server中运行,运行a可能是在onClick中,或者某些强依赖browser的环境中。

那么此时对于server bundle来说,导入a就是多余的。

如果a的代码量非常大、模块数量非常多或者有很多a独有的依赖。势必会降低server 构建的性能以及可能的 server 运行的性能。

详见 example/next-js

在这个例子中,我们使用了 @web3modal/ethersethers,但是这两个依赖并不会在服务端运行,他们依赖的browser

所以我们可以尝试mock这两个依赖的导出,使得业务代码不用做任何更改,同时优化server端的性能。

如何 mock

通过指定webpack.resolve.alias来 mock 依赖。

例如:

在 server 构建时候,webpack 解析到如下代码:

import { createWeb3Modal } from "@web3modal/ethers/react"时。

通过 webpack.resolve.alias 指定 @web3modal/ethers/reactmock.js, 使其真正参与编译的时候被替换为 mock.js的实现。

// mock.js
function f() {}
function mockHooks() {
  return {};
}
const mock = new Proxy(f, {
  get(target, p, receiver) {
    if (typeof p === "string") {
      // 当做 react hooks 使用,确保返回值不是空的
      if (p.startsWith("use")) {
        return mockHooks;
      }
      if (p === "__esModule") {
        return false;
      }
    }
    // 默认返回自身,确保可以循环引用
    return mock;
  },
  construct(target, argArray, newTarget) {
    return mock;
  },
});

// 只会在 server 中被导入,使用 cjs 导出
// 并且 es module 不支持 动态导出,需要声明清楚需要导出的 member
// 这里用 cjs 能很好的完成 mock module 这个任务
exports = mock;
module.exports = exports;

对比

这里给出部分对比数据,感兴趣可以运行 example/next-js 查看。

next dev

module count

  • 常规 mock server端冗余模块优化next.js dev/build 性能
  • 优化 mock server端冗余模块优化next.js dev/build 性能

访问同一页面next构建的module数量有所下降,即在server端没有去构建@web3modal/ethersethers

memory usage

冷启动后

  • 常规 mock server端冗余模块优化next.js dev/build 性能
  • 优化 mock server端冗余模块优化next.js dev/build 性能

热更新多次后

  • 常规 mock server端冗余模块优化next.js dev/build 性能
  • 优化 mock server端冗余模块优化next.js dev/build 性能

next build

通过运行 node --heap-prof ./node_modules/next/dist/bin/next build 生成的 heapprofile 获取的内存数据

memory usage

  • 常规 mock server端冗余模块优化next.js dev/build 性能
  • 优化 mock server端冗余模块优化next.js dev/build 性能

bundle-analyzer

  • 常规 mock server端冗余模块优化next.js dev/build 性能
  • 优化 mock server端冗余模块优化next.js dev/build 性能

总结 从以上对比数据来看,mock掉在server中用不上的依赖确实能带来有效的性能提升。

最后

抛砖引玉,希望能看到更多的想法,当然也可能后续turbo pack稳定后也不需要乱七八糟的hack方法。

可以直接安装ssr-optimize试试咸淡。

转载自:https://juejin.cn/post/7353060906698014755
评论
请登录