Scroll restoration is the code that puts a reader back where they were after they tap an item and press Back. The policy in the most code is two lines: save scrollTop, set it back.
Try it: https://dev48.infy.uk/design/day78-scroll-restoration.html
It is perfect until the feed does what feeds do
| exact restores | |
|---|---|
| feed unchanged while they were away | 600 / 600 |
| three items arrived at the top | 0 / 600 |
Not slightly off. The reader lands a mean of 2.86 items from where they were, up to 9 at the worst. A pixel offset is a promise about a coordinate system, and inserting anything above the reader silently redefines it.
And it passes every test
A scroll-restoration suite can assert three things without a reader in the room: a position gets set, it lands inside the document, and scrolling further before leaving restores further. All three are real statements about the code, and scrollTop satisfies all three.
Four of six policies pass the suite. Two of the four are correct. None of the three properties mentions the item the reader was looking at, so the suite has no way to tell which.
The suite rejects the accurate one
Remembering which item was on top — and nothing else — fails the first property. When the reader was part-way down the very first post, it restores to 0, and a suite that treats "restored nothing" as a bug records a failure. On 5 of 400 checks.
It is also right about the item on 600 of 600 journeys, mean distance 0.000 items.
policy suite right about the item
save scrollTop ACCEPTS 0 / 600 exact
remember the item REJECTS 600 / 600
The suite throws out the policy that puts the reader where they were, and keeps the one that is a mean of 2.86 items wrong.
The fixture is the whole story
The test fixture is static because writing one that grows is more work. That single convenience is what hides the defect — and the general shape is worth carrying: a property that holds for a random permutation of your elements is not a property of your ordering. The same three assertions pass for 3,600 of 3,600 lists drawn at random from the dialog, because a cycle is a cycle whatever is in it.
959 verifier asserts, 15 in-page checks, 0 failures. Vanilla JavaScript, one file, no build step.
Top comments (0)