rustdoc: avoid whole page layout on each frame
This makes two changes, based on experimenting with different browsers: - It debounces resizing the body text. This improves behavior on huge pages like struct.Vec.html, because it doesn't have to do layout. - It does the sidebar width updates directly on the sidebar instead of doing it on the `<HTML>` element. Doing it on `<HTML>` causes it to recalculate CSS for the entire document, also causing layout jank.
This commit is contained in:
parent
9aabfd5892
commit
77fa09d9a1
@ -389,12 +389,14 @@ img {
|
||||
.sidebar {
|
||||
font-size: 0.875rem;
|
||||
flex: 0 0 var(--desktop-sidebar-width);
|
||||
width: var(--desktop-sidebar-width);
|
||||
overflow-y: scroll;
|
||||
overscroll-behavior: contain;
|
||||
position: sticky;
|
||||
height: 100vh;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.rustdoc.src .sidebar {
|
||||
@ -403,7 +405,6 @@ img {
|
||||
overflow-x: hidden;
|
||||
/* The sidebar is by default hidden */
|
||||
overflow-y: hidden;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hide-sidebar .sidebar,
|
||||
@ -415,8 +416,8 @@ img {
|
||||
touch-action: none;
|
||||
width: 9px;
|
||||
cursor: col-resize;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
z-index: 200;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
/* make sure there's a 1px gap between the scrollbar and resize handle */
|
||||
left: calc(var(--desktop-sidebar-width) + 1px);
|
||||
@ -445,6 +446,14 @@ img {
|
||||
cursor: col-resize !important;
|
||||
}
|
||||
|
||||
.sidebar-resizing .sidebar {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
}
|
||||
.sidebar-resizing > body {
|
||||
padding-left: var(--resizing-sidebar-width);
|
||||
}
|
||||
|
||||
.sidebar-resizer:hover,
|
||||
.sidebar-resizer:active,
|
||||
.sidebar-resizer:focus,
|
||||
@ -474,7 +483,7 @@ img {
|
||||
|
||||
.sidebar-resizer.active {
|
||||
/* make the resize tool bigger when actually resizing, to avoid :hover styles on other stuff
|
||||
while resizing */
|
||||
while resizing */
|
||||
padding: 0 140px;
|
||||
width: 2px;
|
||||
margin-left: -140px;
|
||||
@ -503,6 +512,7 @@ img {
|
||||
.src-sidebar-expanded .src .sidebar {
|
||||
overflow-y: auto;
|
||||
flex-basis: var(--src-sidebar-width);
|
||||
width: var(--src-sidebar-width);
|
||||
}
|
||||
|
||||
.src-sidebar-expanded .src .sidebar > *:not(#src-sidebar-toggle) {
|
||||
|
@ -1337,6 +1337,13 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
// it gets the sidebar to restore its size.
|
||||
let desiredSidebarSize = null;
|
||||
|
||||
// Sidebar resize debouncer.
|
||||
//
|
||||
// The sidebar itself is resized instantly, but the body HTML can be too
|
||||
// big for that, causing reflow jank. To reduce this, we queue up a separate
|
||||
// animation frame and throttle it.
|
||||
let pendingSidebarResizingFrame = false;
|
||||
|
||||
// If this page has no sidebar at all, bail out.
|
||||
const resizer = document.querySelector(".sidebar-resizer");
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
@ -1360,12 +1367,26 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
if (isSrcPage) {
|
||||
window.rustdocCloseSourceSidebar();
|
||||
updateLocalStorage("src-sidebar-width", null);
|
||||
// [RUSTDOCIMPL] CSS variable fast path
|
||||
//
|
||||
// The sidebar width variable is attached to the <html> element by
|
||||
// storage.js, because the sidebar and resizer don't exist yet.
|
||||
// But the resize code, in `resize()`, sets the property on the
|
||||
// sidebar and resizer elements (which are the only elements that
|
||||
// use the variable) to avoid recalculating CSS on the entire
|
||||
// document on every frame.
|
||||
//
|
||||
// So, to clear it, we need to clear all three.
|
||||
document.documentElement.style.removeProperty("--src-sidebar-width");
|
||||
sidebar.style.removeProperty("--src-sidebar-width");
|
||||
resizer.style.removeProperty("--src-sidebar-width");
|
||||
} else {
|
||||
addClass(document.documentElement, "hide-sidebar");
|
||||
updateLocalStorage("hide-sidebar", "true");
|
||||
updateLocalStorage("desktop-sidebar-width", null);
|
||||
document.documentElement.style.removeProperty("--desktop-sidebar-width");
|
||||
sidebar.style.removeProperty("--desktop-sidebar-width");
|
||||
resizer.style.removeProperty("--desktop-sidebar-width");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1384,15 +1405,27 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
}
|
||||
}
|
||||
|
||||
// Call this to set the correct CSS variable and setting.
|
||||
// This function doesn't enforce size constraints. Do that before calling it!
|
||||
/**
|
||||
* Call this to set the correct CSS variable and setting.
|
||||
* This function doesn't enforce size constraints. Do that before calling it!
|
||||
*
|
||||
* @param {number} size - CSS px width of the sidebar.
|
||||
*/
|
||||
function changeSidebarSize(size) {
|
||||
if (isSrcPage) {
|
||||
updateLocalStorage("src-sidebar-width", size);
|
||||
document.documentElement.style.setProperty("--src-sidebar-width", size + "px");
|
||||
// [RUSTDOCIMPL] CSS variable fast path
|
||||
//
|
||||
// While this property is set on the HTML element at load time,
|
||||
// because the sidebar isn't actually loaded yet,
|
||||
// we scope this update to the sidebar to avoid hitting a slow
|
||||
// path in WebKit.
|
||||
sidebar.style.setProperty("--src-sidebar-width", size + "px");
|
||||
resizer.style.setProperty("--src-sidebar-width", size + "px");
|
||||
} else {
|
||||
updateLocalStorage("desktop-sidebar-width", size);
|
||||
document.documentElement.style.setProperty("--desktop-sidebar-width", size + "px");
|
||||
sidebar.style.setProperty("--desktop-sidebar-width", size + "px");
|
||||
resizer.style.setProperty("--desktop-sidebar-width", size + "px");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1424,6 +1457,19 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
const constrainedPos = Math.min(pos, window.innerWidth - BODY_MIN, SIDEBAR_MAX);
|
||||
changeSidebarSize(constrainedPos);
|
||||
desiredSidebarSize = constrainedPos;
|
||||
if (pendingSidebarResizingFrame !== false) {
|
||||
clearTimeout(pendingSidebarResizingFrame);
|
||||
}
|
||||
pendingSidebarResizingFrame = setTimeout(() => {
|
||||
if (currentPointerId === null || pendingSidebarResizingFrame === false) {
|
||||
return;
|
||||
}
|
||||
pendingSidebarResizingFrame = false;
|
||||
document.documentElement.style.setProperty(
|
||||
"--resizing-sidebar-width",
|
||||
desiredSidebarSize + "px"
|
||||
);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
// Respond to the window resize event.
|
||||
@ -1447,6 +1493,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
window.removeEventListener("pointermove", resize, false);
|
||||
window.removeEventListener("pointerup", stopResize, false);
|
||||
removeClass(document.documentElement, "sidebar-resizing");
|
||||
document.documentElement.style.removeProperty( "--resizing-sidebar-width");
|
||||
if (resizer.releasePointerCapture) {
|
||||
resizer.releasePointerCapture(currentPointerId);
|
||||
currentPointerId = null;
|
||||
@ -1472,6 +1519,8 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/how-to-read-rustdoc.html\
|
||||
window.addEventListener("pointerup", stopResize, false);
|
||||
addClass(resizer, "active");
|
||||
addClass(document.documentElement, "sidebar-resizing");
|
||||
const pos = e.clientX - sidebar.offsetLeft - 3;
|
||||
document.documentElement.style.setProperty( "--resizing-sidebar-width", pos + "px");
|
||||
desiredSidebarSize = null;
|
||||
}
|
||||
resizer.addEventListener("pointerdown", initResize, false);
|
||||
|
@ -100,7 +100,6 @@ pub(crate) fn for_each<E>(f: impl Fn(&StaticFile) -> Result<(), E>) -> Result<()
|
||||
storage_js => "static/js/storage.js",
|
||||
scrape_examples_js => "static/js/scrape-examples.js",
|
||||
wheel_svg => "static/images/wheel.svg",
|
||||
sidebar_svg => "static/images/sidebar.svg",
|
||||
clipboard_svg => "static/images/clipboard.svg",
|
||||
copyright => "static/COPYRIGHT.txt",
|
||||
license_apache => "static/LICENSE-APACHE.txt",
|
||||
|
Loading…
Reference in New Issue
Block a user