tldr; Компонент Image React Native имеет встроенную обработку для быстрой загрузки изображений. Мы можем настроить компонент изображения React Native для получения изображения наилучшего размера для нашего компонента изображения без введения каких-либо новых зависимостей.

В Finimize изображения действительно заставляют наше приложение сиять. У нас более 50 пакетов, и каждую неделю мы выпускаем все больше. Пакеты - это серия руководств, в которых исследуются различные финансовые темы и инвестиционные стратегии. Проверьте приложение здесь. (И получите скидку 20 фунтов стерлингов на нашу премиальную подписку, перейдя по этой ссылке!)

У каждого пакета есть своя обложка, красиво оформленная нашим штатным иллюстратором. Обложка каждой упаковки в одних местах отображается в виде миниатюр, в других - в полном размере.

Понятно, что мы сильно полагаемся на изображения, но их загрузка становилась огромным узким местом в производительности нашего приложения React Native. Тем не менее, мы сделали гигантский скачок в производительности с помощью всего нескольких изменений, изложенных здесь, и без каких-либо новых зависимостей или сложной логики.

Вы должны быстро получать удаленные изображения

Первое, на что следует обратить внимание, это то, что разные телефоны имеют разное соотношение пикселей. Допустим, у нас есть изображение размером 64x64. Для этого потребуются:

  • 128 на 128 пикселей на iPhone 7 (соотношение пикселей @ 2x с его дисплеем Retina)
  • 192 на 192 пикселя на iPhone Xs Max (соотношение @ 3x)

Это разница в количестве пикселей в 2,25 раза, что означает больше данных по сети и, в конечном итоге, более длительное время загрузки изображений и снижение производительности для вашего приложения React Native.

Если вы хотите получить более подробную информацию о том, почему так, читайте дальше. В противном случае пропустите этот раздел!

Почему на разных устройствах нужны изображения разного размера?

Хотя размеры экрана не сильно различаются ни физически, ни в измерениях, используемых в коде React Native, устройства имеют разное количество пикселей на «точку» - измерение, используемое в React Native.

(Если вы используете Photoshop, это аналогично точкам на дюйм - пиксели на точку просто измеряют количество фактических пикселей экрана, которые используются для измерения одного «пикселя» / точки на устройстве.)

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

Однако это означает, что для каждого изображения, используемого на iPhone 7, мы получаем на 125% больше данных, чем нам нужно, из-за его соотношения пикселей @ 2x по сравнению с соотношением @ 3x более поздних iPhone. Использование множества разных изображений может явно сказаться на производительности приложения.

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

Как помогает компонент Image React Native

Обычно, когда мы используем компонент Image, мы передаем ему объект в качестве источника. Например:

import React from "react"
import { Image } from "react-native"
const RandomCat = () => {
  return (
    <Image
      style={{ height: 64, width: 64 }}
      source={{ uri: https://cataas.com/cat }}
    />
  )
}
export default RandomCat

Это просто говорит React Native пойти и получить это изображение, независимо от размера компонента Image. Если мы показываем только миниатюру, мы тратим впустую данные наших пользователей, а также без необходимости увеличиваем время загрузки.

Чтобы решить эти проблемы, мы можем быстро получать изображения. Для этого нам понадобится набор «точек останова» для изображений: вариации изображения разных размеров. Когда нам нужно изображение размером 64 фактического устройства в высоту и ширину, мы просто выбираем изображение с наименьшей точки останова, которая имеет ширину и высоту не менее 64 пикселей.

Компонент Image может управлять всей этой логикой за нас. Если мы передадим ему массив исходных объектов с указанной высотой и шириной, React Native выберет изображение, которое лучше всего подходит для отображения с реальным размером пикселя этого изображения.

Нам даже не нужно указывать размер компонента Image в его стиле, поскольку React Native рассчитывает его на макете. Все, что нам нужно сделать, это передать массив исходных объектов (каждый с URI, высотой и шириной), и React Native сделает остальную работу за нас.

import React from "react"
import { Image } from "react-native"
const sources = [
  {
    uri: "https://picsum.photos/id/30/64/64",
    height: 64,
    width: 64
  },
  {
    uri: "https://picsum.photos/id/30/128/128",
    height: 128,
    width: 128
  },
  {
    uri: "https://picsum.photos/id/30/256/256",
    height: 256,
    width: 256
  },
  {
    uri: "https://picsum.photos/id/30/512/512",
    height: 512,
    width: 512
  }
]
const SomeImage = () => {
  // We don't even need to specify the height or width 🤯
  return <Image source={sources} />
}

Никаких зависимостей или сложной логики!

Единственная проблема здесь заключается в том, что нам нужно сгенерировать диапазон размеров для каждого изображения, которое мы хотим быстро загрузить, а затем загрузить их в нашу веб-папку, S3 или какой-либо другой сервис. Хотя это может быть нормально, если вы используете только несколько изображений в своем приложении, это может быстро стать головной болью.

Бонус: автоматическое создание точек останова изображения с помощью imgix

i mgix избавляет от проблем с обслуживанием изображений в различных точках останова. Он обслуживает изображения, хранящиеся в вашей веб-папке, S3 или в облачном хранилище Google, с возможностью редактировать их, используя только параметры запроса.

Все ваши изображения обслуживаются из их глобального CDN и стоят всего 3 доллара за 1000 обслуживаемых изображений (без учета вариаций в изображениях).

Попробуйте: https://assets.imgix.net/unsplash/moon.jpg?fit=crop&w=500&h=400

Получив URL-адрес imgix, мы можем легко сгенерировать URL-адреса для наших точек останова в React Native, если захотим.

import React from "react"
import { Image } from "react-native"
const breakpoints = [[100, 100], [200, 200], [300, 300]]
const sources = breakpoints.map([w, h] => ({
    uri: `https://assets.imgix.net/unsplash/moon.jpg?fit=crop&w={w}&h={h}`,
    height: w,
    width: h
  })
)
const TheMoon = () => {
  return <Image source={sources} />
}
export default TheMoon

Кроме того, вы можете сгенерировать их на своем сервере и отправить в приложение через API-запрос, как это делаем мы в Finimize.

imgix имеет гораздо больше возможностей для редактирования ваших изображений на лету, если они вам нужны, а также возможность обслуживать и редактировать любое изображение с URL-адресом, если вы используете их источник веб-прокси.

Впервые в Finimize? Наша миссия - дать возможность миллениалам стать собственными финансовыми консультантами.

Узнайте больше, подписавшись на нашу финансовую рассылку новостей по электронной почте или загрузив наше приложение. Кстати, мы нанимаем!

(Вы также можете получить скидку 20 фунтов стерлингов на нашу премиальную подписку по этой ссылке!)