You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:28:12