perf(v2): reduce amount of navbar renders while scrolling (#4473)

This commit is contained in:
Armano 2021-03-22 19:32:11 +01:00 committed by GitHub
parent af840b7f85
commit f12e8b596d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 23 deletions

View file

@ -190,12 +190,15 @@ function DocSidebar({
isHidden,
}: Props): JSX.Element | null {
const [showResponsiveSidebar, setShowResponsiveSidebar] = useState(false);
const [showAnnouncementBar, setShowAnnouncementBar] = useState(true);
const {
navbar: {hideOnScroll},
hideableSidebar,
} = useThemeConfig();
const {isAnnouncementBarClosed} = useUserPreferencesContext();
const {scrollY} = useScrollPosition();
useScrollPosition(({scrollY}) => {
setShowAnnouncementBar(scrollY === 0);
});
useLockBodyScroll(showResponsiveSidebar);
const windowSize = useWindowSize();
@ -222,7 +225,7 @@ function DocSidebar({
{
'menu--show': showResponsiveSidebar,
[styles.menuWithAnnouncementBar]:
!isAnnouncementBarClosed && scrollY === 0,
!isAnnouncementBarClosed && showAnnouncementBar,
},
)}>
<button

View file

@ -14,7 +14,6 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
const location = useLocation();
const [isNavbarVisible, setIsNavbarVisible] = useState(hideOnScroll);
const isFocusedAnchor = useRef(false);
const [lastScrollTop, setLastScrollTop] = useState(0);
const [navbarHeight, setNavbarHeight] = useState(0);
const navbarRef = useCallback((node: HTMLElement | null) => {
if (node !== null) {
@ -23,7 +22,7 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
}, []);
useScrollPosition(
({scrollY: scrollTop}) => {
({scrollY: scrollTop}, {scrollY: lastScrollTop}) => {
if (!hideOnScroll) {
return;
}
@ -36,7 +35,6 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
if (isFocusedAnchor.current) {
isFocusedAnchor.current = false;
setIsNavbarVisible(false);
setLastScrollTop(scrollTop);
return;
}
@ -53,10 +51,8 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
} else if (scrollTop + windowHeight < documentHeight) {
setIsNavbarVisible(true);
}
setLastScrollTop(scrollTop);
},
[lastScrollTop, navbarHeight, isFocusedAnchor],
[navbarHeight, isFocusedAnchor],
);
useEffect(() => {
@ -64,10 +60,6 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
return;
}
if (!lastScrollTop) {
return;
}
setIsNavbarVisible(true);
}, [location.pathname]);

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import {useState, useEffect} from 'react';
import {useEffect, useRef} from 'react';
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
import type {ScrollPosition} from '@theme/hooks/useScrollPosition';
@ -15,19 +15,19 @@ const getScrollPosition = (): ScrollPosition => ({
});
const useScrollPosition = (
effect?: (position: ScrollPosition) => void,
effect?: (position: ScrollPosition, lastPosition: ScrollPosition) => void,
deps = [],
): ScrollPosition => {
const [scrollPosition, setScrollPosition] = useState(getScrollPosition());
): void => {
const scrollPosition = useRef(getScrollPosition());
const handleScroll = () => {
const currentScrollPosition = getScrollPosition();
setScrollPosition(currentScrollPosition);
if (effect) {
effect(currentScrollPosition);
effect(currentScrollPosition, scrollPosition.current);
}
scrollPosition.current = currentScrollPosition;
};
useEffect(() => {
@ -35,12 +35,11 @@ const useScrollPosition = (
passive: true,
};
handleScroll();
window.addEventListener('scroll', handleScroll, opts);
return () => window.removeEventListener('scroll', handleScroll, opts);
}, deps);
return scrollPosition;
};
export default useScrollPosition;

View file

@ -163,9 +163,9 @@ declare module '@theme/hooks/useScrollPosition' {
export type ScrollPosition = {scrollX: number; scrollY: number};
const useScrollPosition: (
effect?: (position: ScrollPosition) => void,
effect?: (position: ScrollPosition, lastPosition: ScrollPosition) => void,
deps?: unknown[],
) => ScrollPosition;
) => void;
export default useScrollPosition;
}