Как оптимизировать загрузку изображений в Next.js

По умолчанию встроенная оптимизация изображений Next.js отключена в App Hosting, если вы не задали для images.unoptimized значение false или не используете собственный загрузчик изображений.

Вы можете настроить глобальный загрузчик изображений Next.js с помощью расширения Firebase для обработки изображений, чтобы включить оптимизацию по запросу и доставку изображений в приложении Next.js на App Hosting.

Требования

  • У вас есть проект Firebase и серверная часть App Hosting.
  • В вашем проекте включен сервис Cloud Storage.
  • В вашем проекте включен сервис Cloud Functions for Firebase.

Установите расширение

Перейдите к расширению Image Processing в Firebase Extensions Hub и выберите Install in Firebase Console (Установить в консоли Firebase). Следуйте инструкциям на экране.

Настройте оптимизацию локальных изображений (необязательно).

Если в вашем приложении используются локальные изображения, которые вы хотите оптимизировать с помощью этого расширения, вам необходимо настроить параметр "Имя хоста" в процессе установки расширения.

  1. Во время настройки расширения. На этапе "Настройка расширения" найдите параметр "Имя хоста".

  2. Укажите имя хоста. Введите домен по умолчанию для серверной части Firebase App Hosting. Обычно он заканчивается на .hosted.app.

После завершения установки Image Processing API должен быть развернут как функция в Cloud Functions. Перейдите на панель управления функциями в консоли Firebase и скопируйте URL триггера Image Processing API.

Как настроить собственный загрузчик изображений

Создайте загрузчик изображений, который использует развернутый Image Processing API для каждого оптимизированного компонента изображения. Для оптимизации перепишите его, чтобы он размещался в том же домене Firebase App Hosting и кешировался в той же глобальной сети доставки контента, что и ваше приложение Next.js.

Сначала добавьте в файл next.config.js следующие поля:

// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    loader: "custom",
    loaderFile: "./loader.js",
  },
  async rewrites() {
    return [
      {
        source: "/_fah/image/:path*",
        destination:
          "<CLOUD_FUNCTIONS_URL>/:path*",
      },
    ];
  },
}

module.exports = nextConfig;

Затем создайте в корневом каталоге файл loader.js со следующим содержимым:

"use client"

export default function myImageLoader({ src, width, quality }) {
  if (process.env.NODE_ENV === "development") {
    return src;
  }

  const operations = [
    {
      operation: "input",
      type: "url",
      url: src,
    },
    { operation: "resize", width: width },
    { operation: "output", format: "webp", quality: quality || 75 },
  ];

  const encodedOperations = encodeURIComponent(JSON.stringify(operations));

  return `/_fah/image/process?operations=${encodedOperations}`;
}

Создайте фиксацию с этими изменениями и добавьте ее в активную ветку. Затем дождитесь завершения развертывания App Hosting.