Add checkpoints during replay
See original GitHub issueWe need to improve the ‘play at any time’ feature which supports rrweb-player’s DND interactions.
Currently, we do this by introducing sync
mode which will rebuild snapshot before time offset synchronously and then play under the timer. But this may cause a performance issue when we try to play at a large time offset.
For example, if we have 100 snapshots and we play in the third snapshot’s time offset, we need to rebuild 3 snapshots synchronously which is fine. When we are trying to play at the 99th snapshot’s time offset, we need to rebuild 99 snapshots synchronously which will block everything.
So the solution is to build checkpoints when we create a replayer. We may cache the result of rebuilding every 50 snapshots, so the maximize synchronously snapshots rebuilding number is 50.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (2 by maintainers)
Top GitHub Comments
When this is being refactored, it might be valuable to separate three distinct concepts here?
Right now we have the “storage of events”, which are then converted in “playback” actions, which are then executed by timing logic. However, these three are tightly integrated, which makes it a bit hard to use one of the specific elements but not the others.
In the current code,
replay/timer.ts
is both concerned with storing a list of actions, and timing their playback, whilereplay/index.ts
mostly handles generating actions which modify a output iframe but is also dependant on certain timer functions.For example for the case of live streaming it’d be nice if I was able to reuse the event storage and playback action generation, but supply my own timing logic. Or, another example, if I wanted to output to multiple iframes, I’d like to still use the event store but have multiple replay functions use it. I’m also interested in allowing the use of a more abstracted clock for the timing logic so that other time-bound elements may tie in to it.
Splitting the concepts up might look like this:
render(time: number)
which renders the replay in its output element for the given timestamp.requestAnimationFrame
loop which calls therender(time: number)
method of the replay renderer to actually make it play back. This would then also be the only part to be connected to the playback controls in the interface.The event store would then be the place where these checkpoints (which would basically be full snapshots) are (pre)computed, so that it can return a small number of events for the replay rendererer to render to go to a certain point in time.
The replay renderer should remember the last timestamp it rendered, and only request a delta from that timestamp instead of having to render from the very first full snapshot. It might also do some higher level caching by storing a clones of rendered snapshots so it won’t have to reconstruct them.
I know this is only laterally related to this issue, but it might be useful to think about before effort is put into building the checkpoint logic so that if this is something we’d like and want to consider, one can somewhat account for it while tackling this issue.
This would be a great feature IMO. We plan to use rrweb for product demos and definitely take advantage of it.