优化play页面首次加载性能

This commit is contained in:
mtvpls
2025-12-29 22:12:55 +08:00
parent cae84559ea
commit 86d260a4c2
2 changed files with 130 additions and 13 deletions

View File

@@ -44,6 +44,8 @@ interface EpisodeSelectorProps {
availableSources?: SearchResult[];
sourceSearchLoading?: boolean;
sourceSearchError?: string | null;
/** 后台源加载状态 */
backgroundSourcesLoading?: boolean;
/** 预计算的测速结果,避免重复测速 */
precomputedVideoInfo?: Map<string, VideoInfo>;
/** 弹幕相关 */
@@ -73,6 +75,7 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
availableSources = [],
sourceSearchLoading = false,
sourceSearchError = null,
backgroundSourcesLoading = false,
precomputedVideoInfo,
onDanmakuSelect,
currentDanmakuSelection,
@@ -296,6 +299,42 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
// 依赖项保持与之前一致
}, [activeTab, availableSources, getVideoInfo, optimizationEnabled, initialTestingCompleted, currentSource]);
// 监听后台加载完成,触发自动测速
const prevBackgroundLoadingRef = useRef<boolean>(false);
useEffect(() => {
// 当后台加载从 true 变为 false 时(即加载完成)
if (prevBackgroundLoadingRef.current && !backgroundSourcesLoading) {
// 如果当前选项卡在换源位置,触发测速
if (activeTab === 'sources' && optimizationEnabled && currentSource !== 'openlist') {
// 筛选出尚未测速的播放源
const pendingSources = availableSources.filter((source) => {
const sourceKey = `${source.source}-${source.id}`;
return !attemptedSourcesRef.current.has(sourceKey);
});
if (pendingSources.length > 0) {
const batchSize = Math.ceil(pendingSources.length / 2);
const fetchInBatches = async () => {
for (let start = 0; start < pendingSources.length; start += batchSize) {
const batch = pendingSources.slice(start, start + batchSize);
await Promise.all(batch.map(getVideoInfo));
}
if (!initialTestingCompleted) {
setInitialTestingCompleted(true);
}
};
fetchInBatches();
}
}
}
// 更新前一次的加载状态
prevBackgroundLoadingRef.current = backgroundSourcesLoading;
}, [backgroundSourcesLoading, activeTab, availableSources, getVideoInfo, optimizationEnabled, initialTestingCompleted, currentSource]);
// 升序分页标签
const categoriesAsc = useMemo(() => {
return Array.from({ length: pageCount }, (_, i) => {
@@ -881,6 +920,15 @@ const EpisodeSelector: React.FC<EpisodeSelectorProps> = ({
</div>
);
})}
{/* 后台加载提示 */}
{backgroundSourcesLoading && (
<div className='flex items-center justify-center py-6 border-t border-gray-300 dark:border-gray-700'>
<div className='animate-spin rounded-full h-6 w-6 border-b-2 border-green-500'></div>
<span className='ml-2 text-sm text-gray-600 dark:text-gray-300'>
...
</span>
</div>
)}
<div className='flex-shrink-0 mt-auto pt-2 border-t border-gray-400 dark:border-gray-700'>
<button
onClick={() => {