PERF: Animate request animation frame (#13337)

* PERF: requestanimationframe for better performance on pan events
* PERF: temporarily remove items on animate
This commit is contained in:
Jeff Wong 2021-06-09 04:26:52 -10:00 committed by GitHub
parent 513bfc3a6c
commit f12551afd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 7 deletions

View File

@ -87,6 +87,7 @@ const SiteHeaderComponent = MountWidget.extend(
const menuPanels = document.querySelectorAll(".menu-panel");
const menuOrigin = this._panMenuOrigin;
menuPanels.forEach((panel) => {
panel.classList.remove("moving");
if (this._shouldMenuClose(event, menuOrigin)) {
this._animateClosing(panel, menuOrigin);
} else {
@ -129,6 +130,10 @@ const SiteHeaderComponent = MountWidget.extend(
) {
e.originalEvent.preventDefault();
this._isPanning = true;
const panel = document.querySelector(".menu-panel");
if (panel) {
panel.classList.add("moving");
}
} else {
this._isPanning = false;
}

View File

@ -10,6 +10,7 @@ export default Mixin.create({
//velocity is pixels per ms
_panState: null,
_animationPending: false,
didInsertElement() {
this._super(...arguments);
@ -71,9 +72,7 @@ export default Mixin.create({
//calculate delta x, y, distance from START location
const deltaX = e.clientX - oldState.startLocation.x;
const deltaY = e.clientY - oldState.startLocation.y;
const distance = Math.round(
Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2))
);
const distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
//calculate velocity from previous event center location
const eventDeltaX = e.clientX - oldState.center.x;
@ -87,7 +86,7 @@ export default Mixin.create({
return {
startLocation: oldState.startLocation,
center: { x: Math.round(e.clientX), y: Math.round(e.clientY) },
center: { x: e.clientX, y: e.clientY },
velocity,
velocityX,
velocityY,
@ -102,7 +101,7 @@ export default Mixin.create({
_panStart(e) {
const newState = {
center: { x: Math.round(e.clientX), y: Math.round(e.clientY) },
center: { x: e.clientX, y: e.clientY },
startLocation: { x: e.clientX, y: e.clientY },
velocity: 0,
velocityX: 0,
@ -122,6 +121,7 @@ export default Mixin.create({
this._panStart(e);
return;
}
const previousState = this._panState;
const newState = this._calculateNewPanState(previousState, e);
if (previousState.start && newState.distance < MINIMUM_SWIPE_DISTANCE) {
@ -137,7 +137,17 @@ export default Mixin.create({
) {
this.panEnd(newState);
} else if (e.type === "pointermove" && "panMove" in this) {
this.panMove(newState);
if (this._animationPending) {
return;
}
this._animationPending = true;
window.requestAnimationFrame(() => {
if (!this._animationPending) {
return;
}
this.panMove(newState);
this._animationPending = false;
});
}
},
});

View File

@ -27,12 +27,20 @@
}
.menu-panel.slide-in {
transform: translate(var(--offset), 0);
transform: translateX(var(--offset));
@media (prefers-reduced-motion: no-preference) {
&.animate {
transition: transform 0.1s linear;
}
}
&.moving,
&.animate {
// PERF: only render first 20 items in a list to allow for smooth
// pan events
li:nth-child(n + 20) {
display: none;
}
}
}
.user-menu .quick-access-panel.quick-access-profile li:not(.show-all) {