Реагировать на исходную предварительную выборку изображения

Мне трудно понять Image prefetch. В doc не так много объяснений:

"Предоставляет удаленное изображение для последующего использования, загружая его на диск Кэш"

Не могли бы вы помочь мне понять следующее о предварительной выборке изображения:

  • Предположим, что пользователь загружает образ профиля, а URL-адрес изображения хранится в AsyncStorage.

    • Должен ли я запускать Image.prefetch(UserStore.profileImageUrl) только один раз после успешной загрузки. И используйте предварительно загруженное изображение в компонентах, как обычно, <Imagesource={{uri: UserStore.profileImageUrl}}/>

    • Или я должен всегда запускать Image.prefetch(UserStore.profileImageUrl) перед использованием этого изображения в компоненте, а затем запускать <Imagesource={{uri: UserStore.profileImageUrl}}/>

  • Предположим, что позже пользователь изменит свой имидж профиля, загрузив новое изображение, и после успешной загрузки я предварительно отрисую новое изображение. Будет ли ранее сохраненное в кэше изображение еще на диске?

    • Если да, не будет ли он занимать много места на устройстве, если есть много предварительно загруженных изображений?
  • Есть ли способ вручную удалить предварительно загруженное изображение с диска?

С учетом вышеуказанных вопросов, если есть альтернативные решения для достижения кеширования изображений при использовании реакции native с expo, не могли бы вы помочь мне с этим.

Ответы

Ответ 1

Это был действительно вопрос, с которым я имел дело некоторое время, и я узнал несколько вещей о Image.prefetch:

В текущей версии React-Native (0.48) этот метод все еще продолжается. Точнее:

  • реализация ios все еще неполна.
  • На нем нет полного руководства.
  • Невозможно очистить кеш (вы можете проверить, кэшируется ли URL-адрес, однако, насколько я знаю, вы не можете его очистить сейчас).

В результате я не предлагаю вам использовать его. Независимо от того, хотите ли вы знать, как работает API, так:

Цель

Цель совершенно очевидна, я думаю, этот API:

Предварительно загружает удаленное изображение для последующего использования, загружая его в кеш диска

Это означает, что вы можете использовать Image.prefetch(url) в constructor или componentWillMount. Он пытается получить изображение асинхронно, а затем отображает вашу страницу с каким-то ActivityIndicator. Наконец, когда изображение будет успешно извлечено, вы можете повторно отобразить свой компонент.

Image.prefetch(url) фактически сохраняет изображение на диск (а не в памяти), в результате, всякий раз, когда вы пытаетесь использовать

<Image source={{uri:url}}/>

Сначала он проверяет список URL-адресов кэшей, если вы предварительно запрограммировали этот URL-адрес раньше (и он находится на диске), он не будет беспокоиться о повторной выборке (если вы не запустите функцию `Image.prefetch(url ) 'снова (я не уверен, что он работает правильно).

Последствия этой проблемы настолько сложны. Это означает, что если вы предварительно вычитаете изображение внутри одного компонента (например, <Component1/>), когда вы пытаетесь показать это конкретное изображение в другом компоненте (например, <Component12>), оно не будет извлекать изображение и просто использует диск кэш.

Следовательно, либо не используйте эту Image.prefetch вообще (пока не будет полный API с контролем кеша) или используйте его на свой страх и риск.

  • на Android

На Android у вас есть 3 API для предварительной выборки, и только одна из них представлена ​​в документации:

  • упреждающей:

    var response = Image.prefetch(imageUrl,callbackFunction)
    

Image.prefetch может иметь необязательный второй аргумент callbackFunction, который выполняет функцию До выборки изображения. Его можно записать в следующем формате:

    var response = Image.prefetch(imageUrl,()=>console.log('Image is being fetched'))

Возможно, стоит отметить, что callbackFunction может иметь аргумент с именем requestId (указывая количество предварительной выборки среди всех других предзадач), которые затем могут использоваться для отмены выборки.

    var response = Image.prefetch(imageUrl,(id)=>console.log(id))

Кроме того, response является обещанием, вы можете использовать .then, чтобы сделать больше после предварительного извлечения изображения.

  1. abortPrefetch

     Image.abortPrefetch(requestId) ;
    

используется для отмены ожидающей предварительной выборки. requestId используется как аргумент, тот же, что и в предварительной выборке.

  1. queryCache

      Image.queryCache([url1,url2, ...])
        .then((data)=>console.log(data));
    

Используется для проверки того, что определенный URL уже кэширован, и если да, то где он кэшируется (диск или память)

  • на IOS

Я думаю, что в IOS доступен только Image.prefetch(url), и нет функции обратного вызова, которая будет вызываться как второй аргумент.

Ответ 2

если есть альтернативные решения для достижения кэширования изображений, когда используя реакцию native с expo, не могли бы вы помочь мне с ней.

Вам может быть интересен мой компонентный модуль более высокого порядка, который добавляет функции кэширования изображений, связанных с производительностью, и функциональность "постоянного кеша" на нативный <Image> компонент.

Реагировать на верный кеш изображения

Tl; Пример кода DR:

import imageCacheHoc from 'react-native-image-cache-hoc';
const CacheableImage = imageCacheHoc(Image);

export default class App extends Component<{}> {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <CacheableImage style={styles.image} source={{uri: 'https://i.redd.it/rc29s4bz61uz.png'}} />
        <CacheableImage style={styles.image} source={{uri: 'https://i.redd.it/hhhim0kc5swz.jpg'}} permanent={true} />
      </View>
  );
  }
}

Первое изображение будет кэшироваться до тех пор, пока общий локальный кеш не станет более 15 МБ (по умолчанию), а затем кешированные изображения будут удалены с самого начала до полного кэша ниже 15 МБ.

Второе изображение будет постоянно храниться на локальном диске. Люди используют это как замену для отправки файлов статического изображения с вашим приложением.

Лично я бы не слишком усложнял вещи, повторяя файлы снова и снова, когда файл меняется, просто спрашивая о массивной головной боли. Вместо этого я создавал бы уникальное имя файла для каждой загрузки. Таким образом, пользовательский профиль pic при первом загрузке - "profile-uniqueIdHere.jpg", и когда они меняют свой профиль pic, вы просто создаете новый файл "profile-anotherUniqueIdHere.jpg" и обновляете свои пользовательские данные, чтобы отобразить новое местоположение файла. Для получения справки о создании уникальных идентификаторов смотрите react-native-uuid.