You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: src/app/time-travel-intro/what-is-time-travel/page.md
+14-14
Original file line number
Diff line number
Diff line change
@@ -4,11 +4,11 @@ title: What is time travel?
4
4
5
5
The most common question we get is “how is time travel (or Runtime Replay) different from Session Replay?” At a high level, Session Replay tools replay the DOM and Runtime Replay tools re-run the runtime so that you can inspect the session with browser DevTools. That's a lot to unpack. Lets dive in!
6
6
7
-
## How Runtime Replay works?
7
+
## How Runtime Replay works
8
8
9
-
Runtime Replay refers to the act of recording the underlying runtime such that you can replay it later exactly as it ran before.
9
+
Runtime Replay refers to the act of recording the underlying runtime so you can replay it later exactly as it ran before.
10
10
11
-
When the browser is replaying, it should think it is running live for the first time and should have all of the same semantics. Functions should be called at the same time. Promises should be resolved in the same order. Network requests should be made at the same time and returned at the same time. If anything uservisible happens in a different order, you have failed.
11
+
When the browser is replaying, it should think it is running live for the first time and should have all of the same semantics. Functions should be called at the same time. Promises should be resolved in the same order. Network requests should be made at the same time and returned at the same time. If anything user-visible happens in a different order, you have failed.
12
12
13
13
Replaying your browser is similar to writing a good test. If you’re testing a deterministic function like `fibonacci`, there’s nothing you need to do. Every time the test is run, it will return the same value.
14
14
@@ -64,7 +64,7 @@ function fibonacci() {
64
64
}
65
65
```
66
66
67
-
Recording a runtime like Chrome is fairly similar in theory to recording our non-deterministic fibonacci function. The one caveat is that instead of writing a test function that mocks a single non-deterministic function, we need to write a little bit of inline assembly code that can intercept low level OS library calls and replaying them later.
67
+
Recording a runtime like Chrome is fairly similar in theory to recording our non-deterministic fibonacci function. The one caveat is that instead of writing a test function that mocks a single non-deterministic function, we need to write a little bit of inline assembly code that can intercept low level OS library calls and replay them later.
68
68
69
69
```asm
70
70
extern size_t
@@ -102,7 +102,7 @@ Once we’re able to intercept calls, and we know their signatures, the remainin
102
102
MACRO(open, SaveRvalHadErrorNegative) \
103
103
```
104
104
105
-
This approach might sound crazy, and in many ways it is, but there’s an elegance to it in that the libc level is fairly stable and welldefined. Also it turns out that intercepting libc calls is incredibly cheap.
105
+
This approach might sound crazy, and in many ways it is. But it's also elegant, because the libc level is fairly stable and well-defined, and intercepting libc calls is incredibly cheap.
106
106
107
107
**Additional reading**
108
108
@@ -112,21 +112,21 @@ This approach might sound crazy, and in many ways it is, but there’s an elegan
112
112
113
113
## Recording overhead
114
114
115
-
It’s counterintuitive, but recording the runtime’s essential non-determinism is actually very light weight. There are three reasons for that.
115
+
It’s counter-intuitive, but recording the runtime’s essential non-determinism is actually very lightweight. There are three reasons for that.
116
116
117
-
The first is that, 99.99% of compute is deterministic. There actually isn’t that many calls to the OS that need to be captured. On average, it’s about a Mb per second, which is nothing when you consider that computers execute billions of operations a second and traces are measured in GBs.
117
+
The first is that 99.99% of compute is deterministic. There actually aren't many calls to the OS that need to be captured. On average, it’s about a Mb per second, which is nothing when you consider that computers execute billions of operations a second and traces are measured in GBs.
118
118
119
-
The second reason is that the inline assembly needed to intercept the libc calls is highly optimized and only introduces about 3% of overhead. This is nothing when you consider that most instrumentation approaches introduce 10% or more overhead.
119
+
The second reason is that the inline assembly needed to intercept the libc calls is highly optimized and only introduces about 3% of overhead. This is nothing when you consider that most instrumentation approaches introduce 10% or more.
120
120
121
-
The third reason is that everything you see in Replay DevTools is computed at replay time and not record time. A great example is that is the video which is created the first time we replay the recording and can often be larger than the recording itself!
121
+
The third reason is that everything you see in Replay DevTools is computed at replay time and not record time. This is why, for example, the video created the first time we replay the recording is often larger than the recording itself!
122
122
123
123
## Replay protocol
124
124
125
125
Being able to deterministically replay the runtime is necessary, but not sufficient for being able to inspect the application with browser devTools. This is where the Replay protocol comes in.
126
126
127
127
There are several domains that are important for evaluating expressions, inspecting DOM elements, and viewing Console messages. Fortunately, they all bubble up to three core commands: run to execution point, pause at point, and evaluate expression.
128
128
129
-
**When you add a console log on a line of code three things happen:**
129
+
**Three things happen when you add a console log on a line of code:**
130
130
131
131
1. The client looks up the **hit points** for that line of code which was computed the first time the recording was replayed.
132
132
2. The client issues a `runEvaluation` command with the executions points and expression which triggers the backend to replay to these points and execute the eval.
@@ -148,11 +148,11 @@ The beautiful thing about this approach is that the browser behaves the same way
148
148
149
149
## Replay performance
150
150
151
-
One of the things you’ll notice when you open a replay, is that adding a console log is really fast. In fact, a good analogy is Hot Module Reloading where when you edit your code, your application immediately updates, without you having to refresh and re-run. Console logs in Replay work a similar way, you add the log, and the messages appear in the Console in under a second.
151
+
One of the things you’ll notice when you open a replay is adding a console log is really fast. A good comparison is Hot Module Reloading, which is when you can edit your code and your application immediately updates without you having to refresh and re-run. Console logs in Replay work a similar way. You add the log and the messages appear in the Console in under a second.
152
152
153
-
But, how is it so fast? The short answer is that we cheat. One of the fundamental laws of time travel, is that you cannot re-execute a program faster than you initially executed it. If the recording is 60s of compute, then it will take approximately 60s to replay, but console logs will still return in under a second! How?
153
+
But how is it so fast? One of the fundamental laws of time travel is you cannot re-execute a program faster than you initially executed it. If the recording is 60s of compute, then it will take approximately 60s to replay, but console logs will still return in under a second! How? The short answer is that we cheat.
154
154
155
-
The answer is that when you’re inspecting a replay, you’re not interacting with a single browser process running the cloud, you’re interacting with potentially hundreds. We’ve invented two mechanisms which make this possible. The first is the ability to fork a browser process. The second is the ability to snapshot a browser process.
155
+
When you’re inspecting a replay, you’re not interacting with a single browser process running the cloud, you’re interacting with potentially hundreds. We’ve invented two mechanisms which make this possible. The first is the ability to fork a browser process. The second is the ability to snapshot a browser process.
156
156
157
157
{% figure
158
158
alt="Time travel protocol performance"
@@ -161,7 +161,7 @@ The answer is that when you’re inspecting a replay, you’re not interacting w
161
161
width=870
162
162
/%}
163
163
164
-
These two mechanisms make it possible to efficiently keep a pool of browser processes available during the lifetime of the debugging session and efficiently restore them the next time. This means that when you add the console log, we’re able to find the closest browser processes, fork them, run to the relevant points, and evaluate the expression. And because all of the work is done in parallel, and there’s never a point more than 100ms away from a browser process, we’re able to return the results in low logarithmic time.
164
+
These two mechanisms make it possible to efficiently keep a pool of browser processes available during the lifetime of the debugging session and efficiently restore them the next time. This means that when you add the console log, we’re able to find the closest browser processes, fork them, run to the relevant points, and evaluate the expression. Because all of the work is done in parallel, and there’s never a point more than 100ms away from a browser process, we’re able to return the results in low logarithmic time.
0 commit comments