JavaScript
可选优化
Maybe you don’t need Rust and WASM to speed up your JS
过早优化是万恶之源
- 调用函数时传递和声明一样多的参数,不使用可选参数。
- 单态化函数,简单来说让每个参数的形状(对象的结构(包括属性值)、或者函数本身)都永远不变(像是immutable?)。
- 克制地使用缓存 —— 除非查找它比计算它容易。
- 想办法减少 GC 的压力,例如申请一个大的 TypedArray 存储定长数据。
- 如果只是在 ASCII 范围内工作,用 Uint8Array 代替 String。
还有一些常识:
- 用 class 维护对象的形状,不去改变 prototype。
- 从维护形状考虑,不要用 Record
当 Map/Set 使 —— 直接用 Map 即可。
Tools
pnpm
pnpm 在处理 bin 的方式上跟 yarn 不同,在unix系统下,yarn 会直接在 .bin 文件夹下 .js 文件的软链接(package.json 中bin项中列出的文件):
"bin": {
"esno": "esno.js",
"esmo": "esmo.mjs"
},
作为可执行脚本,而 pnpm 会改成嵌套后的 sh:
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -z "$NODE_PATH" ]; then
export NODE_PATH="..."
else
export NODE_PATH="$NODE_PATH: ..."
fi
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../esno/esmo.mjs" "$@"
else
exec node "$basedir/../esno/esmo.mjs" "$@"
fi
#!/usr/bin/env node
import spawn from 'cross-spawn'
import { resolve } from 'import-meta-resolve'
const spawnSync = spawn.sync
const argv = process.argv.slice(2)
resolve('esbuild-node-loader', import.meta.url).then((path) => {
process.exit(spawnSync('node', ['--loader', path, ...argv], { stdio: 'inherit' }).status)
})
按照官方说法
- Binstubs (files in node_modules/.bin) are always shell files, not symlinks to JS files. The shell files are created to help pluggable CLI apps in finding their plugins in the unusual node_modules structure. This is very rarely an issue and if you expect the file to be a JS file, reference the original file directly instead, as described in #736.
https://pnpm.io/limitations
https://github.com/pnpm/pnpm/issues/1282
windows中 yarn 也都是 shell,所以pnpm这种反而是正确的做法。
pnpm 这样的做法带来的问题在于,原先 vscode 可以直接 node 执行 .bin 中文件,pnpm安装后,只能去依赖地址里找bin的原始文件执行,或使用 npx / yarn/pnpm 执行器 等来执行 bin 文件。