React Native Expo应用首次启动图片延迟弹窗问题求助
Expo React Native 图片首次加载延迟弹窗问题
应用启动或重载后,用户首次进入页面时,所有图片会延迟约半秒才加载显示(以弹窗形式突然出现)。
已尝试的解决措施
- 替换为在其他项目中正常使用的小型webp图片,问题依旧存在
- 按照Expo文档实现图片预取逻辑,无任何效果
- 制作开发构建版本进行测试,问题仍未解决
关键排查组件代码
_layout.tsx
import { useFonts } from "expo-font"; import { Stack } from "expo-router"; import * as SplashScreen from "expo-splash-screen"; import { useEffect, useState } from "react"; import { useColorScheme } from "@/hooks/useColorScheme"; import { Provider as StateProvider } from "react-redux"; import { store } from "@/state/store"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Asset } from "expo-asset"; // 防止资源加载完成前闪屏自动隐藏 SplashScreen.preventAutoHideAsync(); function cacheImages(images: any[]) { return images.map((image) => { if (typeof image === "string") { return Image.prefetch(image); } else { return Asset.fromModule(image).downloadAsync(); } }); } export default function RootLayout() { const [fontsLoaded] = useFonts({ Inter: require("../assets/fonts/Inter-Standard.ttf"), InterItalic: require("../assets/fonts/Inter-Italic.ttf"), KodchasanRegular: require("../assets/fonts/Kodchasan-Regular.ttf"), KodchasanMedium: require("../assets/fonts/Kodchasan-Medium.ttf"), }); const [imagesLoaded, setImagesLoaded] = useState(false); // 渲染应用前加载所需资源或数据 useEffect(() => { async function loadResourcesAndDataAsync() { try { SplashScreen.preventAutoHideAsync(); const imageAssets = cacheImages([ require("../assets/images/affirmation-images/California-backyard-1.webp"), require("../assets/images/affirmation-images/California-backyard-2.webp"), require("../assets/images/affirmation-images/California-backyard-3.webp"), require("../assets/images/affirmation-images/California-backyard-4.webp"), require("../assets/images/affirmation-images/english-countryside-1.webp"), require("../assets/images/affirmation-images/english-countryside-2.webp"), require("../assets/images/affirmation-images/english-countryside-3.webp"), require("../assets/images/affirmation-images/english-countryside-4.webp"), ]); await Promise.all([...imageAssets]); console.log("images cached"); } catch (err) { console.warn(err); } finally { setImagesLoaded(true); SplashScreen.hideAsync(); } } loadResourcesAndDataAsync(); }, []); if (!imagesLoaded || !fontsLoaded) { return null; } return ( <StateProvider store={store}> <GestureHandlerRootView> <Stack> <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name="tools/classic_cbt/cda" options={{ headerShown: false }} /> <Stack.Screen name="tools/classic_cbt/journal" options={{ headerShown: false }} /> <Stack.Screen name="tools/relax/breathing" options={{ headerShown: false }} /> <Stack.Screen name="tools/distract/phone" options={{ headerShown: false }} /> <Stack.Screen name="+not-found" /> </Stack> </GestureHandlerRootView> </StateProvider> ); }
app/(tabs)/Tools.tsx
import React from "react"; import { View } from "react-native"; import FrameMenu from "@/components/FrameMenu"; import Text from "@/components/global/Text"; import ToolCard from "../../components/ToolCard"; const Tools = () => { return ( <FrameMenu title="Tools"> <View> <Text className="mb-8 mt-2 text-left text-2xl">Classic</Text> <ToolCard name="Identify the Distortions" image={require("@/assets/images/affirmation-images/english-countryside-1.webp")} link="/tools/classic_cbt/cda" /> <ToolCard name="Mood Journal" image={require("@/assets/images/affirmation-images/english-countryside-2.webp")} link="/tools/classic_cbt/journal" /> <ToolCard name="Ground Yourself" image={require("@/assets/images/affirmation-images/english-countryside-3.webp")} link="tools/classic_cbt/grounding" ></ToolCard> <Text className="mb-8 mt-2 text-left text-2xl">Relax</Text> <ToolCard name="Breathing excercises" link="/tools/relax/breathing" image={require("@/assets/images/affirmation-images/english-countryside-4.webp")} /> <ToolCard name="Muscle relaxation" link="/tools/relax/muscleRelaxation" image={require("@/assets/images/affirmation-images/english-countryside-1.webp")} /> <Text className="mb-8 mt-2 text-left text-2xl">Distract yourself</Text> <ToolCard name="Phone to a friend" image={require("@/assets/images/affirmation-images/english-countryside-1.webp")} link="/tools/distract/phone" /> <ToolCard name="Listen to music" link="/tools/distract/music" image={require("@/assets/images/affirmation-images/english-countryside-1.webp")} /> </View> </FrameMenu> ); }; export default Tools;
内容的提问来源于stack exchange,提问作者Mer Danii
相关产品推荐
相关产品推荐

