@vernikr/size-report 2.7.0 → 2.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -55
- package/package.json +2 -2
- package/src/css.js +2 -2
- package/src/locales.js +0 -6
- package/src/page/app.css +15 -33
- package/src/page/app.js +29 -57
- package/src/page/build.js +14 -17
- package/src/page/payload.js +4 -5
- package/src/page/table.js +251 -293
- package/src/table.css +113 -67
- package/src/page/work.js +0 -55
package/src/table.css
CHANGED
|
@@ -1,70 +1,116 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
1
|
+
/* The report's table: a grid of plain elements rather than a `<table>`, and only the part of it the reader looks at is
|
|
2
|
+
* built (`src/page/table.js` says why, and what was measured).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Everything here hangs off `#grid`, and that is not a habit: this sheet is the package's **shared** part (`src/css.js`)
|
|
5
|
+
* while the page brings a `.panel .row` of its own, and an unscoped rule for the table's rows took that row out of the
|
|
6
|
+
* flow with it (the panel's switches stood on top of one another until the rules were scoped).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
#grid .
|
|
36
|
-
#grid
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
8
|
+
* Four figures are the whole geometry — a metric column, a row, the header and the commit column — and they are written
|
|
9
|
+
* twice, here and in the script that counts the window's ordinals in them. Two copies of a number are two answers waiting
|
|
10
|
+
* to happen, hence `test/page-grid.test.js` reads these four declarations and holds the script to them.
|
|
11
|
+
*
|
|
12
|
+
* One border: 1px of one colour — a row's bottom edge, a group's left edge, the lines of the header. A heavier line or a
|
|
13
|
+
* second colour would promise a hierarchy to be worked out rather than read.
|
|
14
|
+
*
|
|
15
|
+
* One type face for the whole table; numbers line up by their digits thanks to tabular-nums rather than through a
|
|
16
|
+
* monospaced font. Every column is the same width and fixed: the numbers are short and of one kind, and a width that came
|
|
17
|
+
* out of the text would have to be measured over every cell of the column — the very cost this step removed. The header is
|
|
18
|
+
* two lines of one row each — `--head` is exactly two `--row` — and a name too long for its group is cut with an ellipsis
|
|
19
|
+
* rather than wrapped (`appCaption`) or run over its neighbour.
|
|
20
|
+
*/
|
|
21
|
+
#grid {
|
|
22
|
+
--col: 70px;
|
|
23
|
+
--row: 25px;
|
|
24
|
+
--head: 50px;
|
|
25
|
+
--commit: 220px;
|
|
26
|
+
--grid-line: rgba(127, 127, 127, .25);
|
|
27
|
+
position: relative;
|
|
28
|
+
font-variant-numeric: tabular-nums;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* The window: the rows stand at their own `top` inside the scrolled content, so scrolling costs the browser nothing but
|
|
32
|
+
* painting — no layout and no script — while the width of the content gives the scrollbar its length and the script its
|
|
33
|
+
* ordinals. The cells of a row are one grid of fixed tracks (`grid-auto-columns`): a cell cannot change the width of a
|
|
34
|
+
* column, and it cannot push its neighbour. */
|
|
35
|
+
#grid .row { position: absolute; left: 0; width: 100%; height: var(--row); }
|
|
36
|
+
#grid .cells {
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 0;
|
|
39
|
+
display: grid;
|
|
40
|
+
grid-auto-flow: column;
|
|
41
|
+
grid-auto-columns: var(--col);
|
|
42
|
+
height: var(--row);
|
|
43
|
+
}
|
|
44
|
+
#grid .cells > span, #grid .hgroups > span, #grid .hmetrics > span { box-sizing: border-box; white-space: nowrap; }
|
|
45
|
+
/* Two pixels of padding and a line of twenty: with the border, a cell is one `--row` high — the same for the header's
|
|
46
|
+
* cells as for the numbers, or the header would be a band of another rhythm. */
|
|
47
|
+
#grid .cells > span {
|
|
48
|
+
padding: 2px 4px;
|
|
49
|
+
line-height: 20px;
|
|
50
|
+
border-bottom: 1px solid var(--grid-line);
|
|
51
|
+
}
|
|
52
|
+
#grid .num { text-align: right; }
|
|
53
|
+
/* The left edge of a group — the total, and every file — is carried by the group's first metric. One class instead of
|
|
54
|
+
* the four rules of "which metric is switched on": the window is built out of the files that are on, so which column
|
|
55
|
+
* stands first in a group is the page's own answer rather than something the styling has to work out. */
|
|
56
|
+
#grid .cells > .g, #grid .hmetrics > .g, #grid .hgroups > .gh { border-left: 1px solid var(--grid-line); }
|
|
57
|
+
|
|
58
|
+
/* The header: one row of groups (the total and the files) over one row of metrics, stuck to the top edge of the shell,
|
|
59
|
+
* and the commit column stuck to its left edge. Both carry an opaque background (Canvas), or the numbers would show
|
|
60
|
+
* through them while the reader scrolls. The two lines are placed by `top` and are one row high each, so the header
|
|
61
|
+
* aligns with the table below it rather than standing a size of its own. */
|
|
62
|
+
#grid .head { position: sticky; top: 0; left: 0; z-index: 3; height: var(--head); background: Canvas; }
|
|
63
|
+
#grid .hgroups, #grid .hmetrics { position: absolute; display: grid; grid-auto-flow: column; grid-auto-columns: var(--col); }
|
|
64
|
+
#grid .hgroups { top: 0; height: var(--row); }
|
|
65
|
+
#grid .hmetrics { top: var(--row); height: var(--row); }
|
|
66
|
+
#grid .hgroups > span, #grid .hmetrics > span {
|
|
67
|
+
padding: 2px 4px;
|
|
68
|
+
line-height: 20px;
|
|
69
|
+
border-bottom: 1px solid var(--grid-line);
|
|
70
|
+
}
|
|
71
|
+
/* A file's name stands over its group of metrics and is centred on it: the group is a column of numbers, and a caption
|
|
72
|
+
* that began at its left edge would carry the eye to the wrong place. */
|
|
73
|
+
#grid .hgroups > span { text-align: center; overflow: hidden; text-overflow: ellipsis; }
|
|
74
|
+
#grid .hmetrics > span { text-align: center; color: CanvasText; }
|
|
75
|
+
|
|
76
|
+
/* The commit column: a sticky cell of every row, so the commit a number belongs to is in sight while the reader scrolls
|
|
77
|
+
* sideways. Its width is fixed and is the script's `APP_COMMIT` as well — the numbers are placed from the left edge of
|
|
78
|
+
* the grid *beside* the column, and a caption longer than it is clipped (the whole subject stands in the tooltip). */
|
|
79
|
+
#grid .c-commit {
|
|
80
|
+
position: sticky;
|
|
81
|
+
left: 0;
|
|
82
|
+
z-index: 2;
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
width: var(--commit);
|
|
85
|
+
height: var(--row);
|
|
86
|
+
line-height: var(--row);
|
|
87
|
+
padding: 0 4px;
|
|
88
|
+
background: Canvas;
|
|
89
|
+
text-align: left;
|
|
90
|
+
font-weight: 400;
|
|
91
|
+
overflow: hidden;
|
|
92
|
+
text-overflow: ellipsis;
|
|
93
|
+
white-space: nowrap;
|
|
94
|
+
border-bottom: 1px solid var(--grid-line);
|
|
95
|
+
}
|
|
96
|
+
#grid .c-commit a { color: inherit; }
|
|
97
|
+
#grid .head .c-commit { z-index: 6; height: var(--head); line-height: var(--head); }
|
|
98
|
+
/* This block fills the commit column: the cell clips what does not fit, and the subject is what gives way (the flex
|
|
99
|
+
* item of `flex: 1 1 auto`), while the date and the journal mark keep their own width. */
|
|
100
|
+
#grid .clip { display: flex; align-items: baseline; gap: 6px; width: 100%; }
|
|
101
|
+
#grid .when { flex: none; opacity: .7; }
|
|
102
|
+
#grid .subj { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; display: block; }
|
|
103
|
+
#grid .subj.plain { opacity: .7; }
|
|
104
|
+
#grid .sect { flex: none; opacity: .7; font-size: 11px; text-decoration: none; border-bottom: 1px dotted currentColor; }
|
|
61
105
|
/* Growth green, fall red — by agreement with whoever asked for the report (growth is "more logic" rather than alarm). */
|
|
62
|
-
.up { color: #1e8449; }
|
|
63
|
-
.down { color: #c0392b; }
|
|
64
|
-
.miss { opacity: .5; }
|
|
65
|
-
/* The top row holds the current sizes: it is also what explains what the deltas refer to
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
/* A row's highlight is laid over rather than swapped in: the sticky column has to stay opaque, or numbers show through
|
|
69
|
-
*
|
|
70
|
-
|
|
106
|
+
#grid .up { color: #1e8449; }
|
|
107
|
+
#grid .down { color: #c0392b; }
|
|
108
|
+
#grid .miss { opacity: .5; }
|
|
109
|
+
/* The top row holds the current sizes: it is also what explains what the deltas below refer to — by its weight rather
|
|
110
|
+
* than by a heavier line, which would be a second border among the rows. */
|
|
111
|
+
#grid .row.now > .c-commit { font-weight: 600; }
|
|
112
|
+
/* A row's highlight is laid over rather than swapped in: the sticky column has to stay opaque, or numbers show through
|
|
113
|
+
* it while the reader scrolls sideways. */
|
|
114
|
+
#grid .row:hover > .c-commit, #grid .row:hover > .cells > span {
|
|
115
|
+
background-image: linear-gradient(rgba(127, 127, 127, .08), rgba(127, 127, 127, .08));
|
|
116
|
+
}
|
package/src/page/work.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/* The page's long work, and the stripe that says it is going on.
|
|
2
|
-
*
|
|
3
|
-
* A switch on a file's box changes a class on every node of that file's column, and a folder or a category is that same
|
|
4
|
-
* work over every file below it. That alone is cheap — measured at about 2 µs a node, so a whole category of this
|
|
5
|
-
* repository's report (73 columns, 55 042 nodes) is 120 ms of it — but it is not the price. **The browser lays this
|
|
6
|
-
* table out again for any change of a column's visibility, and that is close to a second on a table of a few hundred
|
|
7
|
-
* thousand cells** (`probes/step-12-columns.mjs`: 1 cell toggled 234 ms of layout, 750 cells 287 ms, 6 000 cells
|
|
8
|
-
* 539 ms, and the whole click on the shipped page 867 ms blocked with a 742 ms task).
|
|
9
|
-
*
|
|
10
|
-
* Hence the shape of this chapter, and it is a decision rather than a default. The drawing of a switch is **one task**:
|
|
11
|
-
* what is queued is drawn in a single go, one layout, one repaint. Slicing it — a queue worked off between timeouts —
|
|
12
|
-
* was written first and measured (Chrome 153, this repository's report): 37 slices of two columns each paid the table's
|
|
13
|
-
* relayout 37 times, 2.5–4 s a slice, 95 frames and 169 layouts of 151.9 s of pure layout time against 1.04 s for the
|
|
14
|
-
* same click when it is not sliced, with the tab growing to several gigabytes of repaint. The slice is the thing that
|
|
15
|
-
* freezes the page, only more often, so there is none.
|
|
16
|
-
*
|
|
17
|
-
* What is left is honesty about it: work short enough to be over before the browser could paint a stripe is done on the
|
|
18
|
-
* click itself, and above that the stripe appears, the drawing happens in the next task, and the stripe goes away —
|
|
19
|
-
* so a reader sees that the page is working rather than wondering whether it hung. The stripe carries no share: within
|
|
20
|
-
* one task the browser cannot repaint, so a bar that filled would be a bar that lies, and the page already knows the
|
|
21
|
-
* one thing that is true about it (the work is going on).
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
/* Above this much node work the drawing is one task with a stripe rather than a task on the click: a stripe that
|
|
25
|
-
* appears and disappears within the same frame is worse than none, and the figure is one file's column of a report of
|
|
26
|
-
* this repository's size (754 nodes). */
|
|
27
|
-
export const APP_LONG = 2000;
|
|
28
|
-
|
|
29
|
-
/* The stripe: on while a switch is being drawn, off when it is done. There is nothing to count here, and the length is
|
|
30
|
-
* carried by the styling (an indeterminate stripe), which is why this function takes a switch rather than a share. */
|
|
31
|
-
export function appBar(shown) {
|
|
32
|
-
const bar = document.getElementById('bar');
|
|
33
|
-
if (bar !== null) bar.hidden = !shown;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/* What a switch asks for: `items` are the columns that have to be drawn (`{i, units}` — the file's index and the nodes
|
|
37
|
-
* of its column), `step` draws one of them from the view, and the total decides whether the drawing is the reader's own
|
|
38
|
-
* click or the next task with the stripe over it. Only the columns out of step with the view are asked for at all
|
|
39
|
-
* (`appColumnStale`), so a report opened with everything switched on has nothing to draw here. */
|
|
40
|
-
export function appDraw(step, items) {
|
|
41
|
-
/* Counted by a plain walk rather than by `reduce`: the page's shell is held to a rule that it counts no totals of the
|
|
42
|
-
* table itself, and a guard that has to tell a sum of nodes from a sum of numbers is a guard that will be argued with
|
|
43
|
-
* one day. The count of nodes is not one of the report's numbers. */
|
|
44
|
-
let units = 0;
|
|
45
|
-
items.forEach((item) => { units += item.units; });
|
|
46
|
-
if (units <= APP_LONG) {
|
|
47
|
-
items.forEach((item) => step(item.i));
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
appBar(true);
|
|
51
|
-
setTimeout(() => {
|
|
52
|
-
items.forEach((item) => step(item.i));
|
|
53
|
-
appBar(false);
|
|
54
|
-
}, 0);
|
|
55
|
-
}
|