Skip to content

Commit 58454f7

Browse files
committed
notebook layout optimization memo.
1 parent a915eeb commit 58454f7

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Notebook Layout
2+
3+
The notebook editor is a virtualized list view rendered in two contexts (mainframe and webview/iframe). Since most elements' positions are absoulte and there is latency between the two frames, we have multiple optimizations to ensure smooth (we try our best) perceived user experience. The optimizations are mostly around:
4+
5+
* Ensure the elements in curent viewport are stable when other elements dimensions update
6+
* Fewer layout messages between the main and iframe
7+
* Less flickering and forced reflow on scrolling
8+
9+
While we continue optimizing the layout code, we need to make sure that the new optimization won't lead to regression in above three aspects. Here is a list of existing optimziations we already have and we want to make sure they still perform well when updating layout code.
10+
11+
## Executing code cell followed by markdown cells
12+
13+
Code cell outputs and markdown cells are both rendered in the underling webview. When executing a code cell, the list view will
14+
15+
1. Request cell output rendering in webview
16+
2. Cell output height change
17+
2.1 in the webview, we set `maxHeight: 0; overflow: hidden` on the output DOM node, then it won't overlap with the following markdown cells
18+
2.2 broadcast the height change to the list view in main frame
19+
3. List view received the height update request
20+
3.1 Send acknowledge of the output height change to webview
21+
3.2 Push down code cells below
22+
3.3 Webview remove `maxHeight: 0` on the output DOM node
23+
24+
Whether users would see flickering or overlap of outputs, monaco editor and markdown cells depends on the latency between 3.2 and 3.3.
25+
26+
## Re-executing code cell followed by markdown cells
27+
28+
Re-exuecting code cell consists of two steps:
29+
30+
1. Remove old outputs, which will reset the output height to 0
31+
2. Render new outputs, which will push elements below downwards
32+
33+
The latency between 1 and 2 will cause the UI to flicker (as cells below this code cell will move upwards then downwards in a short period of time. However a lot of the time, we just tweak the code a bit and the outputs will have the same shape and very likely same rendered height, seeing the movement of cells below it is not pleasant.
34+
35+
For example say we have code
36+
37+
```py
38+
print(1)
39+
```
40+
41+
it will generate text output `1`. Updating the code to
42+
43+
```py
44+
print(2)
45+
```
46+
47+
will genrate text output `2`. The re-rendering of the output is fast and we want to ensure the UI is stable in this scenario, to archive this:
48+
49+
1. Clear existing output `1`
50+
1.1 Remove the output DOM node, but we reserve the height of the output
51+
1.2 In 200ms, we will reset the output height to `0`, unless there is a new output rendered
52+
2. Received new output
53+
2.1 Re-render the new output
54+
2.2 Calcuate the height of the new output, update layout
55+
56+
57+
If the new output is rendered within 200ms, users won't see the UI movement.
58+
59+
## Scrolling
60+
61+
Code cell outputs and markdown cells are rendered in the webview, which are async in nature. In order to have the cell outputs and markdown previews rendered when users scroll to them, we send rendering requests of cells in the next viewport when it's idle. Thus scrolling downwards is smoother.
62+
63+
However, we **don't** warmup the previous viewport as the cell height change of previous viewport might trigger the flickering of markdown cells in current viewport. Before we optimize this, do not do any warmup of cells before current viewport.
64+
65+

0 commit comments

Comments
 (0)