tracker: optimize tag watcher intervals

This commit is contained in:
nick-delirium 2025-05-30 10:59:22 +02:00
parent 0d9c8d70c8
commit 25e98de6e2
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
4 changed files with 20 additions and 19 deletions

View file

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 398 B

View file

@ -1,7 +1,7 @@
{
"name": "@openreplay/tracker",
"description": "The OpenReplay tracker main package",
"version": "17.0.0",
"version": "17.0.0-beta.0",
"keywords": [
"logging",
"replay"

View file

@ -1,7 +1,7 @@
export const WATCHED_TAGS_KEY = '__or__watched_tags__'
class TagWatcher {
intervals: Record<string, ReturnType<typeof setInterval>> = {}
interval: ReturnType<typeof setInterval> | null = null
tags: { id: number; selector: string }[] = []
observer: IntersectionObserver
private readonly sessionStorage: Storage
@ -57,9 +57,12 @@ class TagWatcher {
setTags(tags: { id: number; selector: string }[]) {
this.tags = tags
this.intervals = {}
tags.forEach((tag) => {
this.intervals[tag.id] = setInterval(() => {
if (this.interval) {
clearInterval(this.interval)
this.interval = null
}
this.interval = setInterval(() => {
this.tags.forEach((tag) => {
const possibleEls = document.querySelectorAll(tag.selector)
if (possibleEls.length > 0) {
const el = possibleEls[0]
@ -67,23 +70,23 @@ class TagWatcher {
el.__or_watcher_tagname = tag.id
this.observer.observe(el)
}
}, 500)
})
}, 500)
}
onTagRendered(tagId: number) {
if (this.intervals[tagId]) {
clearInterval(this.intervals[tagId])
if (this.tags.findIndex(t => t.id === tagId)) {
this.tags = this.tags.filter((tag) => tag.id !== tagId)
}
this.onTag(tagId)
}
clear() {
this.tags.forEach((tag) => {
clearInterval(this.intervals[tag.id])
})
this.tags = []
this.intervals = {}
if (this.interval) {
clearInterval(this.interval)
this.interval = null
}
this.observer.disconnect()
}
}

View file

@ -52,8 +52,7 @@ describe('TagWatcher', () => {
{ id: 1, selector: 'div' },
{ id: 2, selector: 'span' },
])
expect(watcher.intervals).toHaveProperty('1')
expect(watcher.intervals).toHaveProperty('2')
expect(watcher.interval).not.toBeNull()
})
test('fetchTags sets tags and updates sessionStorage', async () => {
@ -85,7 +84,7 @@ describe('TagWatcher', () => {
)
})
test('setTags sets intervals for each tag', () => {
test('setTags sets interval', () => {
const watcher = new TagWatcher({
sessionStorage: sessionStorageMock, errLog: errLogMock, onTag
})
@ -93,8 +92,7 @@ describe('TagWatcher', () => {
{ id: 1, selector: 'div' },
{ id: 2, selector: 'p' },
])
expect(watcher.intervals).toHaveProperty('1')
expect(watcher.intervals).toHaveProperty('2')
expect(watcher.interval).not.toBeNull();
expect(mockObserve).not.toHaveBeenCalled() // No elements to observe initially
})
@ -121,7 +119,7 @@ describe('TagWatcher', () => {
])
watcher.clear()
expect(watcher.tags).toEqual([])
expect(watcher.intervals).toEqual({})
expect(watcher.interval).toBeNull()
expect(watcher.observer.disconnect).toHaveBeenCalled()
})
})