概览Profiler 能采集渲染的开始/结束时间与开销,结合 INP 可定位输入到响应的瓶颈,从而采取任务切分与过渡更新策略提升体验。采集渲染开销'use client'

import React, { Profiler, useState, useTransition } from 'react'

function onRender(id: string, phase: 'mount' | 'update', actualDuration: number) {

navigator.sendBeacon('/api/render', JSON.stringify({ id, phase, actualDuration }))

}

export default function App() {

const [list, setList] = useState<string[]>([])

const [pending, startTransition] = useTransition()

function add(v: string) {

startTransition(() => setList((prev) => [...prev, v]))

}

return (

<Profiler id="List" onRender={onRender}>

<input onChange={(e) => add(e.target.value)} />

{pending && <p role="status">更新中…</p>}

<ul>{list.map((s) => (<li key={s}>{s}</li>))}</ul>

</Profiler>

)

}

INP 采集关联'use client'

let maxEvent = 0

const po = new PerformanceObserver((list) => {

for (const e of list.getEntries() as PerformanceEventTiming[]) {

if (e.name === 'click' || e.name === 'pointerdown' || e.name === 'keydown') {

maxEvent = Math.max(maxEvent, e.duration)

}

}

})

po.observe({ type: 'event', buffered: true, durationThreshold: 16 })

addEventListener('beforeunload', () => {

navigator.sendBeacon('/api/vitals', JSON.stringify({ inp: maxEvent }))

})

治理要点将昂贵更新标记为过渡,避免阻塞输入路径;对超大列表采用分页与虚拟化。切分长任务并让渡主线程;与缓存策略协作减少重复计算。使用 `role="status"` 提示挂起状态,兼顾可访问性。验证与指标React:19.0+;Next.js:15.0+渲染开销与 INP 关联清晰;输入响应与列表更新稳定

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部