mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-30 10:48:05 +02:00
perf(v2): reduce amount of navbar renders while scrolling (#4473)
This commit is contained in:
parent
af840b7f85
commit
f12e8b596d
4 changed files with 17 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue