mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-06 05:13:44 +08:00
perf: improve scrolling performance and interaction in proxy group list
This commit is contained in:
parent
e0fa1f3efe
commit
91b0b1f279
@ -41,12 +41,14 @@ const AlphabetSelector = styled(Box)(({ theme }) => ({
|
|||||||
"& .scroll-container": {
|
"& .scroll-container": {
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
maxHeight: "inherit",
|
maxHeight: "inherit",
|
||||||
|
willChange: "transform",
|
||||||
},
|
},
|
||||||
"& .letter-container": {
|
"& .letter-container": {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: "2px",
|
gap: "2px",
|
||||||
transition: "transform 0.2s ease",
|
transition: "transform 0.2s ease",
|
||||||
|
willChange: "transform",
|
||||||
},
|
},
|
||||||
"& .letter": {
|
"& .letter": {
|
||||||
padding: "1px 4px",
|
padding: "1px 4px",
|
||||||
@ -259,7 +261,7 @@ export const ProxyGroups = (props: Props) => {
|
|||||||
}
|
}
|
||||||
}, [mode, renderList]);
|
}, [mode, renderList]);
|
||||||
|
|
||||||
// 使用防抖保存滚动位置
|
// 改为使用节流函数保存滚动位置
|
||||||
const saveScrollPosition = useCallback(
|
const saveScrollPosition = useCallback(
|
||||||
(scrollTop: number) => {
|
(scrollTop: number) => {
|
||||||
try {
|
try {
|
||||||
@ -275,13 +277,14 @@ export const ProxyGroups = (props: Props) => {
|
|||||||
[mode],
|
[mode],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 优化滚动处理函数,使用防抖
|
// 使用改进的滚动处理
|
||||||
const handleScroll = useCallback(
|
const handleScroll = useCallback(
|
||||||
debounce((e: any) => {
|
throttle((e: any) => {
|
||||||
const scrollTop = e.target.scrollTop;
|
const scrollTop = e.target.scrollTop;
|
||||||
setShowScrollTop(scrollTop > 100);
|
setShowScrollTop(scrollTop > 100);
|
||||||
|
// 使用稳定的节流来保存位置,而不是setTimeout
|
||||||
saveScrollPosition(scrollTop);
|
saveScrollPosition(scrollTop);
|
||||||
}, 16),
|
}, 500), // 增加到500ms以确保平滑滚动
|
||||||
[saveScrollPosition],
|
[saveScrollPosition],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -407,8 +410,11 @@ export const ProxyGroups = (props: Props) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加滚轮事件处理函数
|
// 添加滚轮事件处理函数 - 改进为只在悬停时触发
|
||||||
const handleWheel = useCallback((e: WheelEvent) => {
|
const handleWheel = useCallback((e: WheelEvent) => {
|
||||||
|
// 只有当鼠标在字母选择器上时才处理滚轮事件
|
||||||
|
if (!alphabetSelectorRef.current?.contains(e.target as Node)) return;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!letterContainerRef.current) return;
|
if (!letterContainerRef.current) return;
|
||||||
|
|
||||||
@ -470,20 +476,25 @@ export const ProxyGroups = (props: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ position: "relative", height: "100%" }}>
|
<div
|
||||||
|
style={{ position: "relative", height: "100%", willChange: "transform" }}
|
||||||
|
>
|
||||||
<Virtuoso
|
<Virtuoso
|
||||||
ref={virtuosoRef}
|
ref={virtuosoRef}
|
||||||
style={{ height: "calc(100% - 14px)" }}
|
style={{ height: "calc(100% - 14px)" }}
|
||||||
totalCount={renderList.length}
|
totalCount={renderList.length}
|
||||||
increaseViewportBy={{ top: 256, bottom: 256 }}
|
increaseViewportBy={{ top: 200, bottom: 200 }}
|
||||||
overscan={150}
|
overscan={150}
|
||||||
defaultItemHeight={56}
|
defaultItemHeight={56}
|
||||||
scrollerRef={(ref) => {
|
scrollerRef={(ref) => {
|
||||||
scrollerRef.current = ref as Element;
|
scrollerRef.current = ref as Element;
|
||||||
}}
|
}}
|
||||||
components={{
|
components={{
|
||||||
Footer: () => <div style={{ height: "8px" }} />,
|
Footer: () => <div style={{ height: "2px" }} />,
|
||||||
}}
|
}}
|
||||||
|
// 添加平滑滚动设置
|
||||||
|
initialScrollTop={scrollPositionRef.current[mode]}
|
||||||
|
computeItemKey={(index) => renderList[index].key}
|
||||||
itemContent={(index) => (
|
itemContent={(index) => (
|
||||||
<ProxyRender
|
<ProxyRender
|
||||||
key={renderList[index].key}
|
key={renderList[index].key}
|
||||||
@ -516,7 +527,36 @@ export const ProxyGroups = (props: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 简单的防抖函数
|
// 替换简单防抖函数为更优的节流函数
|
||||||
|
function throttle<T extends (...args: any[]) => any>(
|
||||||
|
func: T,
|
||||||
|
wait: number,
|
||||||
|
): (...args: Parameters<T>) => void {
|
||||||
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
let previous = 0;
|
||||||
|
|
||||||
|
return function (...args: Parameters<T>) {
|
||||||
|
const now = Date.now();
|
||||||
|
const remaining = wait - (now - previous);
|
||||||
|
|
||||||
|
if (remaining <= 0 || remaining > wait) {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
|
previous = now;
|
||||||
|
func(...args);
|
||||||
|
} else if (!timer) {
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
previous = Date.now();
|
||||||
|
timer = null;
|
||||||
|
func(...args);
|
||||||
|
}, remaining);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保留防抖函数以兼容其他地方可能的使用
|
||||||
function debounce<T extends (...args: any[]) => any>(
|
function debounce<T extends (...args: any[]) => any>(
|
||||||
func: T,
|
func: T,
|
||||||
wait: number,
|
wait: number,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user