Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign uplayout: Dramatically improve performance of layout queries and `requestAnimationFrame()`. #14442
Conversation
`ConstructionResult::get()`. It only actually swaps out in nonincremental mode (which isn't suitable for real world use), so the name is confusing.
non-animation purposes and back off to a timer if so. After this patch, when the page calls `requestAnimationFrame()` too many times in the row without actually mutating the DOM, further calls to `rAF` will actually perform the moral equivalent of `setTimeout(16)`. This saves a lot of CPU time compared to actually waiting for the vertical blanking interval, because waiting for that requires us to draw the page. Reduces CPU usage drastically on nytimes.com, which has a perpetual `requestAnimationFrame()` loop that checks whether ads are in view.
queries. Instead of searching the entire tree to find the applicable fragment, we use the flow construction result of the nearest DOM node to find the flow we're looking for directly. We then recursively do this with ancestor DOM nodes in order to find the entire flow tree path, performing breadth first search to deal with anonymous flows in between. To fully eliminate the search, we will probably want some combination of (a) parent pointers in the flow tree and (b) rewritten script-to-layout queries that don't depend on visiting all ancestor flows of the query node. But this is a quick and dirty solution that dramatically improves the performance of layout queries. This is a large responsiveness increase on nytimes.com.
changed and no flows were reconstructed. This saves a tree traversal. It also has the side effect of making incremental reflow bugs of the form "a dirty bit is never cleared" less likely to ruin the performance of layout queries.
after building display lists.
highfive
commented
Dec 2, 2016
|
Heads up! This PR modifies the following files:
|
highfive
commented
Dec 2, 2016
|
Regarding ba274c9: Is an RAF that performs canvas draws but no dom mutations considered "spurious"? Is that desirable? |
|
@fitzgen No, it shouldn't be considered spurious. Does it dirty the canvas? If not, I'm not sure what the best way to detect this is. |
|
The canvas element is dirtied when you draw to it, so there should be no problems here. |
|
r=me on the layout changes, they're great :) I'm not sure we can fake animation frame callbacks using a timer per spec. IIRC we should run them at a very specific timing per the processing model, and we're already awful at it unfortunately. I'd love to see this, and it may be the case that results are black-box identical in this case (though I think not because at least the last fake callback that modifies something and makes us go back to real animation frames runs out of sync). I'd probably defer to @jdm or @Ms2ger to approve that bit, or request more proof of that being the case. |
| /// | ||
| /// A rAF request is considered spurious if nothing was actually reflowed. | ||
| spurious_animation_frames: Cell<u8>, | ||
|
|
This comment has been minimized.
This comment has been minimized.
| // Find the path from the root to the node. | ||
| // | ||
| // FIXME(pcwalton): This would be unnecessary if we had parent pointers in the flow tree. I | ||
| // think they're going to be inevitable. |
This comment has been minimized.
This comment has been minimized.
emilio
Dec 3, 2016
Member
Yeah, this is relatively expensive, though better that a full traversal I guess...
| } | ||
|
|
||
| // Find the next child in the path. | ||
| let target_child = *path.last().expect("Path ended prematurely!"); |
This comment has been minimized.
This comment has been minimized.
|
@bors-servo try |
layout: Dramatically improve performance of layout queries and `requestAnimationFrame()`. See individual commits for details. This improves nytimes.com CPU usage and gets it within the ballpark of Firefox. r? @emilio <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14442) <!-- Reviewable:end -->
|
|
|
@emilio I don't see anything in that list that mandates when animation frame callbacks run, only that they run at specific times relative to other events. We already don't try to do that, I don't think. Indeed it'd be impossible for the spec to mandate a specific time other than describing what a VBLANK is (and if it did, then every other browser on non-Windows platforms would fail it because they don't sync to VBLANK properly). (On a side note, it's irritating that the spec technically forbids off main thread CSS animations, but I'm going to just break the spec because that's dumb.) |
|
On Fri, Dec 02, 2016 at 11:39:39PM -0800, Patrick Walton wrote:
We already don't try to do that, I don't think. Indeed it'd be
impossible for the spec to mandate a specific time other than
describing what a VBLANK is (and if it did, then every other browser
on non-Windows platforms would fail it because they don't sync to
VBLANK properly).
That's fair, that's why I lean towards merging this. But I think we
eventually should try to conform to it, given there are pages that rely
on it, and this will be more complexity to rewrite/remove when we want
to do it.
|
|
|
|
This looks fine to me. Sorry that it was overlooked for so long! |
| } | ||
|
|
||
| impl FakeRequestAnimationFrameCallback { | ||
| #[allow(unrooted_must_root)] |
This comment has been minimized.
This comment has been minimized.
|
That would be great! |
Improve performance of layout queries and requestAnimationFrame Supersedes #14442. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15816) <!-- Reviewable:end -->
Improve performance of layout queries and requestAnimationFrame Part of #14442. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15816) <!-- Reviewable:end -->
|
I carried the first 2 commits in #15816. |
|
@pcwalton Are you sure the commit "query: Stop searching the entire flow tree to resolve script-to-layout" works as intended? |
|
Lack of response, I'm closing this. |
pcwalton commentedDec 2, 2016
•
edited by larsbergstrom
See individual commits for details. This improves nytimes.com CPU usage and gets it within the ballpark of Firefox.
r? @emilio
This change is