Как бороться с большими необработанными изображениями, вызывающими задержку в приложении React? - PullRequest
3 голосов
/ 27 апреля 2020

Я изменяю положение фона фонового изображения, которое пользователь только что загрузил (и, следовательно, является необработанным URI данных), используя CSS, но повторный рендеринг начинает отставать, если изображение> 1 МБ.

Проблема не существует для небольших изображений.

Есть ли какая-то проблема, если не попытаться оптимизировать рендеринг? Я уже не выполняю повторный рендеринг, если только положение фона не изменилось как минимум на 1% (т. Е. Между повторными рендерингами изменение составило 1% или более).

Проблема не возникает с тем же изображением, когда я размещаю хост и затем загрузите изображение с URL.

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

Могу ли я как-то кэшировать данные? Казалось бы, это отстает, потому что необработанные данные не кэшируются, а изображение кэшируется.

1 Ответ

0 голосов
/ 27 апреля 2020

Я немного поиграл с логикой c и изменил styles.backgroundPositionY на прямое манипулирование стилем с помощью элемента ref. Я не вижу больших улучшений. Загруженное изображение действительно запаздывало при его перемещении туда, где было по умолчанию шустрое.

const imageDivRef = useRef(null);

  const onUpload = e => {
    new Promise((resolve, reject) => {
      const reader = new FileReader();

      reader.onload = onLoadEvent => {
        const dataUri = onLoadEvent.target.result;
        let image = new Image() // try to cache that
        image.src = dataUri;
        image.onload = () => {
          resolve(dataUri);
        }
      };

      reader.readAsDataURL(e.target.files[0])

  }).then(dataUri => {
    updateBackgroundImage(dataUri)
  })
};

  const onPan = e => {
    const y = position.y;
    const delta = (e.deltaY / CONTAINER_HEIGHT) * -100;
    requestAnimationFrame(() => {
      imageDivRef.current.style.backgroundPositionY = `${Math.min(
        Math.max(y + delta, 0),
        100)}%`
    })

  };

  const onPanEnd = e => {
    const y = position.y;
    const delta = (e.deltaY / CONTAINER_HEIGHT) * -100;
    requestAnimationFrame(() => {
    imageDivRef.current.style.backgroundPositionY = `${Math.min(
      Math.max(y + delta, 0),
      100)}%`
    })
  };

Существует также одна безумная идея. Откажитесь от backgroundPositionY, сделайте упаковщик div со скрытым и фиксированным размером переполнения, поместите в него элемент img и управляйте им со свойством transform: translateY(unit). Интересно, может ли это быть быстрее ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...