资源缓存


本节涵盖与在应用中加载资源相关的所有内容,从与应用二进制文件打包到缓存、预加载和发布。

¥This section covers all things related to loading assets in your apps, from bundling with an app binary, to caching, pre-loading and publishing.

打包资源

¥Bundling assets

将资源打包到二进制文件中将提供最佳的用户体验,因为你的资源将立即可用。你的应用无需向 CDN 发出网络请求来获取已发布的资源,而是从本地磁盘获取它们,从而获得更快、更高效的加载体验。打包资源还允许离线功能。

¥Bundling assets into your binary will provide the best user experience as your assets will be available immediately. Instead of having to make a network request to the CDN to fetch your published assets, your app will fetch them from the local disk resulting in a faster, more efficient loading experience. Bundling assets also allows offline functionality.

要将资源打包到二进制文件中,请使用 app.json 中的 assetBundlePatterns 键来提供项目目录中的路径列表:

¥To bundle assets in your binary, use the assetBundlePatterns key in app.json to provide a list of paths in your project directory:

下次运行 eas build 时,路径与给定模式匹配的图片将被打包到你的原生二进制文件中。

¥Images with paths matching the given patterns will be bundled into your native binaries next time you run eas build.

注意:如果你的应用包含异常数量的资源或尺寸异常大的资源,资源打包可能不是最好的解决方案,因为它会导致你的应用尺寸膨胀。如果是这种情况,请有选择性地打包那些必要的资源,并将其余资源存储在 CDN 上。

¥Note: If your app contains an abnormal amount of assets or assets that are abnormally large in size, asset bundling may not be the best solution as it will cause your application size to bloat. If this is the case, be selective and bundle those assets that are essential and store the rest on the CDN.

预加载和缓存资源

¥Pre-loading and caching assets

资源的缓存方式有所不同,具体取决于资源的存储位置和使用方式。本部分提供最佳实践,以确保你仅在需要时下载资源。为了在缓存资源时保持加载屏幕可见,最好渲染 SplashScreen 直到一切准备就绪。

¥Assets are cached differently depending on where they are stored and how they are used. This section offers best practices to ensure you only download assets when needed. To keep the loading screen visible while caching assets, it's a good idea to render a SplashScreen until everything is ready.

要下载并缓存保存到本地文件系统的图片,请使用 Asset.fromModule(image).downloadAsync()。对于具有远程 URL 的图片,请使用 Image.prefetch(image)

¥To download and cache the images saved to the local filesystem, use Asset.fromModule(image).downloadAsync(). For images with remote URLs, use Image.prefetch(image).

字体是使用 Font.loadAsync(font) 预加载的。此方法中的 font 参数是一个对象,例如:{OpenSans: require('./assets/fonts/OpenSans.ttf')}@expo/vector-icons 为该对象提供了一个有用的快捷方式,如以下示例中的 FontAwesome.font

¥Fonts are pre-loaded using Font.loadAsync(font). The font argument in this method is an object such as: {OpenSans: require('./assets/fonts/OpenSans.ttf')}. @expo/vector-icons provides a helpful shortcut for this object as FontAwesome.font in the following example:

Pre-loading and Caching Assets
import React, { useState, useEffect } from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import * as SplashScreen from 'expo-splash-screen';
import * as Font from 'expo-font';
import { Asset } from 'expo-asset';
import FontAwesome from '@expo/vector-icons/FontAwesome';

function cacheImages(images) {
  return images.map(image => {
    if (typeof image === 'string') {
      return Image.prefetch(image);
    } else {
      return Asset.fromModule(image).downloadAsync();
    }
  });
}

function cacheFonts(fonts) {
  return fonts.map(font => Font.loadAsync(font));
}

export default function App() {
  const [appIsReady, setAppIsReady] = useState(false);

  // Load any resources or data that you need before rendering the app
  useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        SplashScreen.preventAutoHideAsync();

        const imageAssets = cacheImages([
          'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
          require('./assets/images/circle.jpg'),
        ]);

        const fontAssets = cacheFonts([FontAwesome.font]);

        await Promise.all([...imageAssets, ...fontAssets]);
      } catch (e) {
        // You might want to provide this error information to an error reporting service
        console.warn(e);
      } finally {
        setAppIsReady(true);
        SplashScreen.hideAsync();
      }
    }

    loadResourcesAndDataAsync();
  }, []);

  if (!appIsReady) {
    return null;
  }

  return (
    <View style={styles.container}>
      <Text>Hello world, this is my app.</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

如需使用本地图片资源,你可以在项目中继续正常引用图片来源,例如:

¥To use the local image asset, you can continue referencing the source of the image normally in your project, for example:

<Image source={require('path/to/image.png')} />

请参阅 Expo 的选项卡模板项目 中的完整工作示例。你还可以运行 npx create-expo-app --template tabs 以使用相同的模板设置本地项目。

¥See the complete working example in Expo's tabs template project. You can also run npx create-expo-app --template tabs to set up a local project with the same template.

Expo 中文网 - 粤ICP备13048890号