AMP

Руководство по AMP-оптимизатору для Node.js

Это руководство рассказывает, как настроить и использовать версию AMP-оптимизатора для Node.js.

Подготовка

Установка выполняется через NPM при помощи следующей команды:

npm install @ampproject/toolbox-optimizer

Использование

API AMP-оптимизатора принимает на входе HTML-строку и возвращает ее оптимизированную версию. Вот простой пример его использования:

const AmpOptimizer = require('@ampproject/toolbox-optimizer');

// create the AMP Optimizer instance
const ampOptimizer = AmpOptimizer.create();

const html = '<h1>Hello World!</h1>';

const optimizedHtml = await ampOptimizer.transformHtml(html);

Оптимизация AMP-кода во время сборки

AMP-страницы статических сайтов лучше всего оптимизировать во время сборки. Ниже показано, как можно интегрировать оптимизацию в инструкции для сборки на основе Gulp.js. Код в данном примере добавляет дополнительное преобразование, которое оптимизирует все HTML-файлы в каталоге src:

const {src, dest} = require('gulp');
const through2 = require('through2');

const AmpOptimizer = require('@ampproject/toolbox-optimizer');
const ampOptimizer = AmpOptimizer.create();

function build(cb) {
  return src('src/*.html')
    .pipe(
      through2.obj(async (file, _, cb) => {
        if (file.isBuffer()) {
          const optimizedHtml = await ampOptimizer.transformHtml(
            file.contents.toString()
          );
          file.contents = Buffer.from(optimizedHtml);
        }
        cb(null, file);
      })
    )
    .pipe(dest('dist/'));
}

exports.default = build;

Оптимизация во время рендеринга

Если страница генерируется динамически, то ее рендеринг часто приходится выполнять на сервере. В этом случае можно запускать AMP-оптимизатор после рендеринга страницы. Ниже показан пример интеграции с сервером Express.js. Один из возможных способов интегрировать AMP-оптимизацию в маршрутизатор Express заключается в том, чтобы запускать ее после завершения рендеринга шаблонов, используя функцию обратного вызова:

const express = require('express');
const router = express.Router();
const AmpOptimizer = require('@ampproject/toolbox-optimizer');
const ampOptimizer = AmpOptimizer.create();

router.get('/', (req, res) => {
  const locals = {title: 'Express with AMP Optimizer'};
  res.render('index', locals, async (err, html) => {
    const optimizedHtml = await ampOptimizer.transformHtml(html);
    res.send(optimizedHtml);
  });
});

module.exports = router;

Важно. При использовании AMP-оптимизатора на сервере обязательно настройте кеширование или CDN, чтобы избежать задержек при рендеринге.

Конфигурация

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

Вот несколько важных параметров:

  • lts: true для переключения на URL-адреса долгосрочных стабильных версий среды выполнения AMP и AMP-компонентов.
  • verbose: true для вывода подробных отладочных сообщений. Особенно полезно, когда нужно выяснить, почему не получается удалить шаблонный код AMP.
  • imageOptimizer: автоматически генерирует атрибут srcset для изображений с помощью функции, которая вычисляет URL-адреса srcset на основании атрибута src определенного изображения. Функция должна возвращать URL-адрес версии данного изображения, имеющей заданную ширину. Если изображение недоступно, функция должна возвращать значение, эквивалентное false. Подробнее об этом читайте в следующем разделе.

Оптимизация изображений

AMP-оптимизатор может генерировать для элементов amp-img значения srcset на основании используемого элементом макета (layout). Для этого вы должны предоставить функцию, преобразующую src изображения и его значение width в значение источника srcset, указывающее на изображение соответствующего размера. При этом сам AMP-оптимизатор не меняет размер изображения; необходимо либо делать это во время сборки (например, для статических сайтов), либо использовать хостинг изображений, такой как thumbor.

Вот пример реализации, которая добавляет к значению атрибута src ширину изображения:

const ampOptimizer = AmpOptimizer.create({
  // parameters are the amp-img `src` and the `width` of the to be generated srcset source value
  imageOptimizer: (src, width) => {
    // we cannot rename if the image does not have a file extension
    const index = src.lastIndexOf('.');
    if (index === -1) {
      // return null means we won't generate a srcset source value for this width
      return null;
    }
    const prefix = src.substring(0, index);
    const postfix = src.substring(index, src.length);
    return `${prefix}.${width}w${postfix}`;
  };
})

При использовании этой реализации AMP-оптимизатор преобразует элементы amp-img:

<!-- Injects srcset for responsive layout -->
<amp-img
  src="image1.png"
  width="400"
  height="800"
  layout="responsive"
></amp-img>
<!-- Ignores existing srcset -->
<amp-img
  layout="fill"
  srcset="image-1x.png 1x,
                             image-2x.png 2x"
></amp-img>

...в следующий код:

<!-- Injects srcset for responsive layout -->
<amp-img
  src="image1.png"
  width="400"
  height="800"
  layout="responsive"
  srcset="image1.470w.png 470w, image1.820w.png 820w, image1.1440w.png 1440w"
></amp-img>
<!-- Ignores existing srcset -->
<amp-img
  layout="fill"
  srcset="image-1x.png 1x,
                               image-2x.png 2x"
></amp-img>

Совет. При использовании layout=responsive указывайте минимальные размеры изображения при помощи атрибутов width и height. Например, чтобы растянуть hero-изображение на всю ширину экрана на мобильном устройстве, укажите width=320.