Perf fix for useScrollFn

pull/1306/head
Lim Chee Aun 2025-10-08 07:51:19 +08:00
rodzic 029fdebf91
commit 1aff45d935
3 zmienionych plików z 93 dodań i 145 usunięć

Wyświetl plik

@ -285,20 +285,8 @@ function Timeline({
const headerRef = useRef();
// const [hiddenUI, setHiddenUI] = useState(false);
const [nearReachStart, setNearReachStart] = useState(false);
const { resetScrollDirection } = useScrollFn(
{
scrollableRef,
distanceFromEnd: 2,
scrollThresholdStart: 44,
},
({
scrollDirection,
nearReachStart,
// nearReachEnd,
reachStart,
// reachEnd,
}) => {
// setHiddenUI(scrollDirection === 'end' && !nearReachEnd);
const scrollFnCallback = useCallback(
({ scrollDirection, nearReachStart, reachStart }) => {
if (headerRef.current) {
const hiddenUI = scrollDirection === 'end' && !nearReachStart;
headerRef.current.hidden = hiddenUI;
@ -307,11 +295,16 @@ function Timeline({
if (reachStart) {
loadItems(true);
}
// else if (nearReachEnd || (reachEnd && showMore)) {
// loadItems();
// }
},
[],
[setNearReachStart, loadItems],
);
const { resetScrollDirection } = useScrollFn(
{
scrollableRef,
distanceFromEnd: 2,
scrollThresholdStart: 44,
},
scrollFnCallback,
);
useEffect(() => {

24
src/locales/en.po wygenerowano
Wyświetl plik

@ -348,7 +348,7 @@ msgstr "More from <0/>"
#: src/components/columns.jsx:27
#: src/components/nav-menu.jsx:181
#: src/components/shortcuts-settings.jsx:139
#: src/components/timeline.jsx:471
#: src/components/timeline.jsx:464
#: src/pages/catchup.jsx:899
#: src/pages/filters.jsx:90
#: src/pages/followed-hashtags.jsx:41
@ -510,7 +510,7 @@ msgstr "Attachment #{i} failed"
#: src/components/compose.jsx:1387
#: src/components/status.jsx:2350
#: src/components/timeline.jsx:1016
#: src/components/timeline.jsx:1009
msgid "Content warning"
msgstr ""
@ -728,14 +728,14 @@ msgstr "Edit History Snapshots"
#: src/components/edit-history-controls.jsx:35
#: src/components/gif-picker-modal.jsx:207
#: src/components/media-modal.jsx:469
#: src/components/timeline.jsx:929
#: src/components/timeline.jsx:922
msgid "Previous"
msgstr ""
#: src/components/edit-history-controls.jsx:47
#: src/components/gif-picker-modal.jsx:225
#: src/components/media-modal.jsx:488
#: src/components/timeline.jsx:946
#: src/components/timeline.jsx:939
msgid "Next"
msgstr ""
@ -826,7 +826,7 @@ msgstr ""
#: src/components/generic-accounts.jsx:214
#: src/components/quotes-modal.jsx:128
#: src/components/timeline.jsx:553
#: src/components/timeline.jsx:546
#: src/pages/list.jsx:321
#: src/pages/notifications.jsx:923
#: src/pages/search.jsx:562
@ -836,7 +836,7 @@ msgstr ""
#: src/components/generic-accounts.jsx:219
#: src/components/quotes-modal.jsx:132
#: src/components/timeline.jsx:558
#: src/components/timeline.jsx:551
#: src/pages/search.jsx:567
msgid "The end."
msgstr ""
@ -1222,7 +1222,7 @@ msgstr ""
#: src/components/status-compact.jsx:70
#: src/components/status.jsx:3204
#: src/components/status.jsx:3282
#: src/components/timeline.jsx:1005
#: src/components/timeline.jsx:998
#: src/pages/catchup.jsx:76
#: src/pages/catchup.jsx:1921
msgid "Filtered"
@ -2787,12 +2787,12 @@ msgstr "{index}/{total}"
msgid "{index}/X"
msgstr "{index}/X"
#: src/components/timeline.jsx:487
#: src/components/timeline.jsx:480
#: src/pages/settings.jsx:1282
msgid "New posts"
msgstr ""
#: src/components/timeline.jsx:588
#: src/components/timeline.jsx:581
#: src/pages/home.jsx:228
#: src/pages/notifications.jsx:899
#: src/pages/status.jsx:1153
@ -2801,16 +2801,16 @@ msgid "Try again"
msgstr ""
#. placeholder {0}: fItems.length
#: src/components/timeline.jsx:623
#: src/components/timeline.jsx:616
msgid "{0, plural, one {# Boost} other {# Boosts}}"
msgstr "{0, plural, one {# Boost} other {# Boosts}}"
#: src/components/timeline.jsx:628
#: src/components/timeline.jsx:621
msgid "Pinned posts"
msgstr "Pinned posts"
#. placeholder {0}: filterInfo.titlesStr
#: src/components/timeline.jsx:1000
#: src/components/timeline.jsx:993
msgid "<0>Filtered</0>: <1>{0}</1>"
msgstr ""

Wyświetl plik

@ -14,121 +14,89 @@ export default function useScrollFn(
init,
} = {},
callback,
deps,
) {
if (!callback) return;
// const [scrollDirection, setScrollDirection] = useState(null);
// const [reachStart, setReachStart] = useState(false);
// const [reachEnd, setReachEnd] = useState(false);
// const [nearReachStart, setNearReachStart] = useState(false);
// const [nearReachEnd, setNearReachEnd] = useState(false);
const isVertical = direction === 'vertical';
const previousScrollStart = useRef(null);
const scrollDirection = useRef(null);
const onScroll = useThrottledCallback(() => {
// let scrollDirection = null;
let reachStart = false;
let reachEnd = false;
let nearReachStart = false;
let nearReachEnd = false;
const onScroll = useThrottledCallback(
() => {
let reachStart = false;
let reachEnd = false;
let nearReachStart = false;
let nearReachEnd = false;
const scrollableElement = scrollableRef.current;
const {
scrollTop,
scrollLeft,
scrollHeight,
scrollWidth,
clientHeight,
clientWidth,
} = scrollableElement;
const scrollStart = isVertical ? scrollTop : scrollLeft;
const scrollDimension = isVertical ? scrollHeight : scrollWidth;
const clientDimension = isVertical ? clientHeight : clientWidth;
const scrollDistance = Math.abs(scrollStart - previousScrollStart.current);
const distanceFromStartPx =
_distanceFromStartPx ||
Math.min(
clientDimension * distanceFromStart,
scrollDimension,
scrollStart,
);
const distanceFromEndPx =
_distanceFromEndPx ||
Math.min(
clientDimension * distanceFromEnd,
scrollDimension,
scrollDimension - scrollStart - clientDimension,
);
if (
scrollDistance >=
(previousScrollStart.current < scrollStart
const scrollableElement = scrollableRef.current;
const {
scrollTop,
scrollLeft,
scrollHeight,
scrollWidth,
clientHeight,
clientWidth,
} = scrollableElement;
const scrollStart = isVertical ? scrollTop : scrollLeft;
const scrollDimension = isVertical ? scrollHeight : scrollWidth;
const clientDimension = isVertical ? clientHeight : clientWidth;
const scrollDelta = scrollStart - previousScrollStart.current;
const isScrollingForward = scrollDelta > 0;
const threshold = isScrollingForward
? scrollThresholdEnd
: scrollThresholdStart)
) {
// setScrollDirection(
// previousScrollStart.current < scrollStart ? 'end' : 'start',
// );
scrollDirection.current =
previousScrollStart.current < scrollStart ? 'end' : 'start';
previousScrollStart.current = scrollStart;
}
: scrollThresholdStart;
const distanceFromStartPx =
_distanceFromStartPx ||
Math.min(
clientDimension * distanceFromStart,
scrollDimension,
scrollStart,
);
const distanceFromEndPx =
_distanceFromEndPx ||
Math.min(
clientDimension * distanceFromEnd,
scrollDimension,
scrollDimension - scrollStart - clientDimension,
);
// setReachStart(scrollStart <= 0);
// setReachEnd(scrollStart + clientDimension >= scrollDimension);
// setNearReachStart(scrollStart <= distanceFromStartPx);
// setNearReachEnd(
// scrollStart + clientDimension >= scrollDimension - distanceFromEndPx,
// );
reachStart = scrollStart <= 0;
reachEnd = scrollStart + clientDimension >= scrollDimension;
nearReachStart = scrollStart <= distanceFromStartPx;
nearReachEnd =
scrollStart + clientDimension >= scrollDimension - distanceFromEndPx;
if (Math.abs(scrollDelta) >= threshold) {
scrollDirection.current = isScrollingForward ? 'end' : 'start';
previousScrollStart.current = scrollStart;
}
callback({
scrollDirection: scrollDirection.current,
reachStart,
reachEnd,
nearReachStart,
nearReachEnd,
});
}, 500);
reachStart = scrollStart <= 0;
reachEnd = scrollStart + clientDimension >= scrollDimension;
nearReachStart = scrollStart <= distanceFromStartPx;
nearReachEnd =
scrollStart + clientDimension >= scrollDimension - distanceFromEndPx;
callback({
scrollDirection: scrollDirection.current,
reachStart,
reachEnd,
nearReachStart,
nearReachEnd,
});
},
500,
{
leading: false,
},
);
useLayoutEffect(() => {
const scrollableElement = scrollableRef.current;
if (!scrollableElement) return {};
previousScrollStart.current =
scrollableElement[isVertical ? 'scrollTop' : 'scrollLeft'];
scrollableElement.addEventListener('scroll', onScroll, { passive: true });
return () => scrollableElement.removeEventListener('scroll', onScroll);
}, [
distanceFromStart,
distanceFromEnd,
scrollThresholdStart,
scrollThresholdEnd,
...deps,
]);
// useEffect(() => {
// callback({
// scrollDirection,
// reachStart,
// reachEnd,
// nearReachStart,
// nearReachEnd,
// });
// }, [
// scrollDirection,
// reachStart,
// reachEnd,
// nearReachStart,
// nearReachEnd,
// ...deps,
// ]);
if (scrollableElement) {
previousScrollStart.current =
scrollableElement[isVertical ? 'scrollTop' : 'scrollLeft'];
scrollableElement.addEventListener('scroll', onScroll, { passive: true });
}
return () => {
if (scrollableElement) {
scrollableElement.removeEventListener('scroll', onScroll);
}
};
}, []);
useEffect(() => {
if (init && scrollableRef.current) {
@ -143,17 +111,4 @@ export default function useScrollFn(
scrollDirection.current = null;
},
};
// return {
// scrollDirection,
// reachStart,
// reachEnd,
// nearReachStart,
// nearReachEnd,
// init: () => {
// if (scrollableRef.current) {
// scrollableRef.current.dispatchEvent(new Event('scroll'));
// }
// },
// };
}