2025年|实际问题考查
为什么Jimp会打穿内存?
- Jimp 会把整张图片 decode 到 JS heap
例如一张 6000×4000 的 JPEG,解码后是 6000×4000×4 ≈ 96MB 内存!
连续 10 张 → 960MB → Node.js 默认最大 heap 是 4GB(老版本是 1.4GB),很容易打穿。 - Jimp是纯JS,不能把位图放到native内存
Sharp、libvips 这类库都把 decode 交给 native → 不占 JS heap、GC 压力低。 - GC不会立即回收
你就算 img = null,也不保证马上回收,于是 Heap 在上传高峰时被撑爆。
浏览器端:文件数量和尺寸做限制,前端压缩,分片上传。
🌟(最推荐)方案 1:完全替换 Jimp → 用 sharp
如果你的业务允许,请 立刻换 sharp。
sharp 基于 libvips,不吃 JS heap,不会 OOM。
使用 Worker Threads + 限制并发
用 p-limit 限制 Jimp 处理的并发:
1 | img = null; |
🚨 为什么处理图片会 OOM?
无论 Jimp / Sharp / 自己 decode,只要你:
一次上传太多文件
文件太大(10MB+)
多张图片同时 decode
Node 没限制处理并发
中间对象没有及时释放
就会触发 Out Of Memory,Node 进程就会:
内存飙到上限
V8 抛 FATAL ERROR: Reached heap limit
进程崩溃
PM2 / Docker 自动重启
首屏500ms以下
首屏 500ms 以下,需要关注 关键渲染路径(Critical Rendering Path):
最小化关键请求:减少首屏必须加载的 JS/CSS/图片。
优先渲染关键内容:Critical CSS 内联,JS 延迟加载。
服务端优化:SSR / SSG 或 Edge 缓存。
网络优化:HTTP/3、CDN、压缩、缓存。
浏览器渲染优化:避免 render-blocking 资源、减少重排重绘。
预加载关键资源:
1 | <link rel="preload">、<link rel="prefetch"> |
HTTP/3 对 SPA 性能的优势主要体现在
首屏渲染更快 → 减少握手延迟,减少队头阻塞
动态资源加载优化 → JS/CSS 分片加载更快
API 请求响应更低延迟 → AJAX/fetch 性能提升
移动端高丢包环境更稳健 → 网络切换不中断
useEffect, useLayoutEffect的区别
useLayoutEffect 在 DOM 更新后、浏览器绘制前同步执行;
useEffect 在浏览器绘制完成后异步执行。
1 | Render |
用 useLayoutEffect
适合 “必须在 paint 前完成” 的场景:
1️⃣ 测量 DOM(width / height / position)
useLayoutEffect(() => {
const rect = ref.current.getBoundingClientRect()
setWidth(rect.width)
}, [])
2️⃣ 防止视觉闪烁(tooltip / modal / 动画起点)
useLayoutEffect(() => {
el.style.transform = ‘translateX(0)’
}, [])
3️⃣ 与第三方 UI 库强耦合
D3
老 jQuery 插件
imperative 动画库
闭包
闭包就是:函数在定义时记住了它所在的词法作用域,即使在这个作用域之外执行,也能访问当时的变量。
react的hooks为什么不能写到if的判断语句中
Hooks必须在组件的最外层、以固定顺序调用,因为React是靠“调用顺序”来关联Hook状态的;
写进if会破坏顺序,导致状态错位。
1 | Fiber |