perf: 懒加载表现优化
- 优化路由首进页面过渡策略,减少遮罩阻塞感 - 为菜单导航增加组件预取,降低首次点击等待 - 缩短页面 loading 遮罩过渡时长
This commit is contained in:
@@ -7,6 +7,8 @@ import { isHttpUrl, openRouteInNewWindow, openWindow } from '@easyflow/utils';
|
||||
function useNavigation() {
|
||||
const router = useRouter();
|
||||
const routeMetaMap = new Map<string, RouteRecordNormalized>();
|
||||
const prefetchedPaths = new Set<string>();
|
||||
const prefetchingPaths = new Set<string>();
|
||||
|
||||
// 初始化路由映射
|
||||
const initRouteMetaMap = () => {
|
||||
@@ -37,6 +39,51 @@ function useNavigation() {
|
||||
return router.resolve(path).href;
|
||||
};
|
||||
|
||||
const prefetch = (path: string) => {
|
||||
if (
|
||||
isHttpUrl(path) ||
|
||||
prefetchedPaths.has(path) ||
|
||||
prefetchingPaths.has(path)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const { matched } = router.resolve(path);
|
||||
if (matched.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const componentLoadTasks: Array<Promise<unknown>> = [];
|
||||
matched.forEach((route) => {
|
||||
const component = route.components?.default;
|
||||
if (typeof component !== 'function' || component.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const loaded = (component as () => unknown)();
|
||||
if (loaded && typeof (loaded as Promise<unknown>).then === 'function') {
|
||||
componentLoadTasks.push(loaded as Promise<unknown>);
|
||||
}
|
||||
} catch {
|
||||
// 预取失败不影响正常导航
|
||||
}
|
||||
});
|
||||
|
||||
if (componentLoadTasks.length === 0) {
|
||||
prefetchedPaths.add(path);
|
||||
return;
|
||||
}
|
||||
|
||||
prefetchingPaths.add(path);
|
||||
void Promise.allSettled(componentLoadTasks)
|
||||
.then(() => {
|
||||
prefetchedPaths.add(path);
|
||||
})
|
||||
.finally(() => {
|
||||
prefetchingPaths.delete(path);
|
||||
});
|
||||
};
|
||||
|
||||
const navigation = async (path: string) => {
|
||||
try {
|
||||
const route = routeMetaMap.get(path);
|
||||
@@ -53,6 +100,7 @@ function useNavigation() {
|
||||
} else if (openInNewWindow) {
|
||||
openRouteInNewWindow(resolveHref(path));
|
||||
} else {
|
||||
prefetch(path);
|
||||
await router.push({
|
||||
path,
|
||||
query,
|
||||
@@ -68,7 +116,7 @@ function useNavigation() {
|
||||
return shouldOpenInNewWindow(path);
|
||||
};
|
||||
|
||||
return { navigation, willOpenedByWindow };
|
||||
return { navigation, prefetch, willOpenedByWindow };
|
||||
}
|
||||
|
||||
export { useNavigation };
|
||||
|
||||
Reference in New Issue
Block a user