Skip to content

Commit

Permalink
perf(v2): reduce amount of navbar renders while scrolling (#4473)
Browse files Browse the repository at this point in the history
  • Loading branch information
armano2 authored Mar 22, 2021
1 parent af840b7 commit f12e8b5
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -222,7 +225,7 @@ function DocSidebar({
{
'menu--show': showResponsiveSidebar,
[styles.menuWithAnnouncementBar]:
!isAnnouncementBarClosed && scrollY === 0,
!isAnnouncementBarClosed && showAnnouncementBar,
},
)}>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -23,7 +22,7 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
}, []);

useScrollPosition(
({scrollY: scrollTop}) => {
({scrollY: scrollTop}, {scrollY: lastScrollTop}) => {
if (!hideOnScroll) {
return;
}
Expand All @@ -36,7 +35,6 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
if (isFocusedAnchor.current) {
isFocusedAnchor.current = false;
setIsNavbarVisible(false);
setLastScrollTop(scrollTop);
return;
}

Expand All @@ -53,21 +51,15 @@ const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => {
} else if (scrollTop + windowHeight < documentHeight) {
setIsNavbarVisible(true);
}

setLastScrollTop(scrollTop);
},
[lastScrollTop, navbarHeight, isFocusedAnchor],
[navbarHeight, isFocusedAnchor],
);

useEffect(() => {
if (!hideOnScroll) {
return;
}

if (!lastScrollTop) {
return;
}

setIsNavbarVisible(true);
}, [location.pathname]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -15,32 +15,31 @@ 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(() => {
const opts: AddEventListenerOptions & EventListenerOptions = {
passive: true,
};

handleScroll();
window.addEventListener('scroll', handleScroll, opts);

return () => window.removeEventListener('scroll', handleScroll, opts);
}, deps);

return scrollPosition;
};

export default useScrollPosition;
4 changes: 2 additions & 2 deletions packages/docusaurus-theme-classic/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit f12e8b5

Please sign in to comment.