Skip to content

Commit e42f85d

Browse files
committed
chore: 为动态监控加可选性能埋点
通过 localStorage __sp_observer_debug__='1' 开关在 MutationObserver 回调、节点批处理、PerformanceObserver、快照发送处加 performance.mark/measure,便于线上调试卡顿来源、默认关闭无成本。将版本号提升到 1.2.80。
1 parent dabe617 commit e42f85d

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "stackprism",
33
"private": true,
4-
"version": "1.2.79",
4+
"version": "1.2.80",
55
"type": "module",
66
"description": "StackPrism 用于检测网页前端、后端、CDN、SaaS、广告营销、统计、登录、支付、网站程序和主题模板线索。",
77
"scripts": {

src/content/content-observer.ts

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,40 @@
5252
let mutationBurstCount = 0
5353
let mutationCooldownUntil = 0
5454

55+
// ----- 调试埋点(默认关闭,开启:localStorage.setItem('__sp_observer_debug__','1') + 刷新) -----
56+
57+
const PERF_DEBUG = (() => {
58+
try {
59+
return localStorage.getItem('__sp_observer_debug__') === '1'
60+
} catch {
61+
return false
62+
}
63+
})()
64+
const noop = () => {}
65+
const perfMark = PERF_DEBUG
66+
? name => {
67+
try {
68+
performance.mark(name)
69+
} catch {
70+
// ignore
71+
}
72+
}
73+
: noop
74+
const perfMeasure = PERF_DEBUG
75+
? (name, startMark, detail) => {
76+
try {
77+
performance.measure(name, { start: startMark, detail })
78+
} catch {
79+
// ignore
80+
}
81+
try {
82+
performance.clearMarks(startMark)
83+
} catch {
84+
// ignore
85+
}
86+
}
87+
: noop
88+
5589
// ----- 底层 helper -----
5690

5791
const trimList = (list, max) => {
@@ -256,6 +290,7 @@
256290
}
257291

258292
const sendSnapshot = () => {
293+
perfMark('sp:send-start')
259294
const runtime = getRuntime()
260295
if (stopped || !runtime) {
261296
stopObserver()
@@ -282,6 +317,13 @@
282317
} catch (error) {
283318
handleSendFailure(error)
284319
}
320+
perfMeasure('sp:send-snapshot', 'sp:send-start', {
321+
resources: state.resources.length,
322+
scripts: state.scripts.length,
323+
stylesheets: state.stylesheets.length,
324+
iframes: state.iframes.length,
325+
domMarkers: state.domMarkers.length
326+
})
285327
}
286328

287329
const scheduleSend = () => {
@@ -386,8 +428,10 @@
386428
try {
387429
const observer = new PerformanceObserver(list => {
388430
if (stopped) return
431+
perfMark('sp:po-start')
389432
let added = 0
390-
for (const entry of list.getEntries()) {
433+
const entries = list.getEntries()
434+
for (const entry of entries) {
391435
if (SKIP_INITIATOR_TYPES.has(entry.initiatorType)) continue
392436
if (SKIP_RESOURCE_EXT.test(entry.name)) continue
393437
if (addUrl('resources', entry.name)) added += 1
@@ -398,6 +442,7 @@
398442
performanceObserver = null
399443
}
400444
if (added) scheduleSend()
445+
perfMeasure('sp:perf-observer', 'sp:po-start', { entries: entries.length, added })
401446
})
402447
performanceObserver = observer
403448
observer.observe({ type: 'resource', buffered: true })
@@ -412,15 +457,19 @@
412457
const nodes = pendingMutationNodes
413458
pendingMutationNodes = []
414459
if (!nodes.length) return
460+
perfMark('sp:flush-start')
415461
let changed = false
462+
let processed = 0
416463
for (const node of nodes) {
417464
if (!node.isConnected) continue
465+
processed += 1
418466
changed = collectFromElement(node) || changed
419467
}
420468
if (changed) {
421469
state.updatedAt = Date.now()
422470
scheduleSend()
423471
}
472+
perfMeasure('sp:mutation-flush', 'sp:flush-start', { queued: nodes.length, processed, changed })
424473
}
425474

426475
const scheduleMutationFlush = () => {
@@ -443,10 +492,12 @@
443492
if (stopped) return
444493
const now = Date.now()
445494
if (now < mutationCooldownUntil) return
495+
perfMark('sp:mo-start')
446496
if (now - mutationBurstWindowStart > MUTATION_BURST_WINDOW_MS) {
447497
mutationBurstWindowStart = now
448498
mutationBurstCount = 0
449499
}
500+
const pendingBefore = pendingMutationNodes.length
450501
let pendingFull = false
451502
outer: for (const mutation of mutations) {
452503
for (const node of mutation.addedNodes) {
@@ -462,15 +513,23 @@
462513
}
463514
}
464515
}
516+
const accepted = pendingMutationNodes.length - pendingBefore
465517
if (pendingFull || mutationBurstCount >= MUTATION_BURST_THRESHOLD) {
466518
triggerMutationCooldown(now)
519+
perfMeasure('sp:mutation-callback', 'sp:mo-start', {
520+
mutations: mutations.length,
521+
accepted,
522+
cooldown: true,
523+
pendingFull
524+
})
467525
return
468526
}
469527
if (state.mutationCount >= MAX_MUTATION_COUNT) {
470528
observer.disconnect()
471529
mutationObserver = null
472530
}
473531
if (pendingMutationNodes.length) scheduleMutationFlush()
532+
perfMeasure('sp:mutation-callback', 'sp:mo-start', { mutations: mutations.length, accepted, cooldown: false })
474533
})
475534
mutationObserver = observer
476535
observer.observe(root, { childList: true, subtree: true })

0 commit comments

Comments
 (0)