# 代码优化:JavaScript代码性能优化
根据性能分析结果,优化下载页性能。
# 性能优化的准则
- 减少不必要的计算
- 空间换时间:提前保存计算结果,复用计算结果
- 提前计算:将HTTP服务阶段的计算,提前到启动阶段执行。
app.use(
mount('/', async (ctx) => {
ctx.body = fs.readFileSync(__dirname, 'source/index.html', 'utf-8')
})
)
上面的代码中,对于每次HTTP请求,都会执行一遍中间件逻辑。通过Chrome devtool性能分析,我们可以得到 fs.readFileSync
导致了大量的CPU性能消耗。通过提前执行一次 fs.readFileSync
操作,后面复用该函数的执行结果可以达到很好的性能优化。优化代码如下:
const str = fs.readFileSync(__dirname, 'source/index.html', 'utf-8');
app.use(
mount('/', async (ctx) => {
ctx.body = str
})
)
如果在 mount
里,也就是中间件里使用 fs.readFileSync
,相当于每一次请求都是从文件系统中取模板内容。因为每一个 http
请求进来都会重新调用这堆中间件的。
通过提前执行 fs.readFileSync
,相当于提前把文件系统中的内容读取到内存中。中间件里是从内存中取得模板内容。
相对于从硬盘文件中获取数据,肯定是内存更快。并且避免了多次重复计算。
通过上面的优化,通过Chrome devtool性能分析,我们可以得到 byteLengthUtf8
导致了大量的CPU性能消耗。
实际上,由于上面的代码传递给 ctx.body
的是一个字符串,NodeJS底层返回 http body
还是会将 字符串
转换成 Buffer
。在这个过程中会调用 byteLengthUtf8
方法。通过提前将结果转成 Buffer
,可以达到性能优化。
// 默认获取 buffer 数据
const buffer = fs.readFileSync(__dirname, 'source/index.html');
app.use(
mount('/', async (ctx) => {
ctx.status = 200;
ctx.type = 'html';// 需要指定 html 格式,否则koa可能会解析 buffer 为一个下载链接
ctx.body = buffer;
})
)