Для удобства отражения сайта на мобильных устройствах зачастую нужно внедрить в проект страницу Accelerated Mobile Pages (AMP). Делимся примером, как можно выполнить эту задачу, если вы работаете с приложением на React.
Начнем с того, что AMP — технология ускоренных мобильных страниц от Google с открытым исходным кодом. Этот способ позволяет оперативно загрузить веб-страницу при низкой скорости подключения к сети.
Подробнее с технологией можно познакомиться в различных источниках, например, здесь, здесь или здесь.
Именно такая задача появилась в одном из наших проектов, где стек технологий включал в себя Next.js, React, Styled components и Effector, при этом не было доступа к стору на стороне клиента. Большинство инструкций и гайдов по внедрению AMP, в свою очередь, были ориентированы на обычные html-страницы.
Примечание: для подобных задач можно использовать такие инструменты, как react-snap или prerender.io, если в вашем проекте нет Next.js и иных способов рендеринга на сервере.
В первую очередь установите расширение Amp validator от Google, которое поможет в реализации задачи. Если вы работаете с Next, то для включения режима amp на определенной страницы достаточно добавить следующую строчку:
export const config = { amp: true }
После этого Next добавляет необходимые теги в разметку. Amp validator поможет вам определить, что нужно сделать, чтобы выполнить требования к amp-страницам. Рассмотрим несколько примеров:
Требования к разметке. Next добавляет необходимые теги в разметку, поэтому достаточно убрать дублирование тегов, добавленных вручную в head. Для поискового продвижения также важно добавить тег
<link rel=”canonical” href=”{SOME_URL}” />
.CSS должен быть глобальным, т.е. внутри HTML в теге <head>, и минимального размера. Размер авторской таблицы стилей или совокупный размер встроенных стилей не должен превышать 75 000 байт, иначе произойдет ошибка валидации. Здесь полезна библиотека styled-components, так как на странице будет использоваться только тот css, который необходим. Кроме того, библиотека по умолчанию добавляет стили в тег <head> HTML, а валидатор от Google проверяет
!important
в стилях.Проверьте все компоненты, используемые на странице. Используйте тег
<amp-img />
вместо img или компонента Image, который предоставляет Next. Обратите внимание, что на Typescript на сегодняшний день нет поддержки таких тегов, какamp-img
. Однако, в корне проекта можно создать файлamp.d.ts
и в нем прописать следующее:
declare namespace JSX {
interface IntrinsicElements {
'amp-img': any;
} }
Next предоставляет кастомный хук useAmp()
, который возвращает true
, если это страница AMP, и false
, если нет. Мы не создавали новые компоненты и использовали этот хук внутри тех компонентов, которые рендерятся на странице.
Здесь можно было пойти другим путем и создать новый компонент типа AppImage, который будет возвращать нужный элемент в зависимости от хука. Однако, уровнем выше нам все равно нужно было выполнять проверку, так как изображения в целях оптимизации должны иметь строго определенные размеры width и height.
Еще одна проблема может быть связана с использованием формы. В теге
form
обязательно должен быть атрибутtarget
, который может принимать значение_blank
или_top
Тег
script
запрещен, если параметрtype
не имеет значениеapplication/ld+json
,application/json
илиtext/plain
. Другие неисполняемые значения могут быть добавлены по мере необходимости. Исключения — обязательный тегscript
, используемый для загрузки среды выполнения AMP, а также тегиscript
для загрузки расширенных компонентов.
Если в проекте нужна интерактивность, есть два способа реализации.
-
В AMP HTML запрещены имена атрибутов, начинающиеся с on (например,
onclick
илиonmouseover
). Атрибут с буквальным именем on (без суффикса) является допустимым. Что это дает? Возможность указать действия по событию, например, добавить к кнопке строчкуon=”tap:menu.toggleVisibility”
.По клику на кнопку (tap) происходит поиск элемента, у которого id равен menu. Если он виден, то будет скрыт. Для того чтобы добавить несколько действий на один элемент, их можно перечислить через запятую, например:
on=”tap:menu.toggleVisibility,elem.show”
. Также можно прослушивать несколько событий на одном элементе, для этого их нужно перечислить через точку с запятой:on="submit-success:lightbox1;submit-error:lightbox2"
Вместо этого вы можете использовать существующий amp-компонент. Например, если вам нужна amp-carousel и отдельные слайды готовы, останется только обернуть их в этот компонент и стилизовать кнопки.
Также вы можете использовать тег
<amp-script>
и обернуть им любую часть своего HTML. Amp-script копирует своих потомков в виртуальный дом, и вы сможете обратиться к ним черезdocument.body
<amp-script src="http://example.com/my-script.js" width="300" height="100">
<p>A single line of text</p>
</amp-script>
Заключение
Как вы видите, в создании AMP-страниц для React в принципе нет ничего сложного. При этом зачастую нужно переключиться с того стиля кода, который характерен для современных React-приложений, и реализовать задачу так, как вы бы это сделали до создания React.
Спасибо за внимание! Надеемся, что этот пример был вам полезен.
Комментарии (3)
boldMahoney
20.12.2021 09:46AMP как и его аналог Турбо-Страницы были мертворожденные технологии изначально. Концепция не прижилась, так зачем в 2к22 тормошить труп? Оставьте уже его.
Fuco
Стоит упомянуть, что в апреле 2021 Google анонсировал важные изменения по технологии AMP:
Бейдж AMP в результатах поиска больше не будет показываться,
В Top Stories теперь будут появлятся не-AMP страницы, AMP не имеет никаких преимуществ,
Наличие AMP-версии никак не влияет на ранжирование.
Новость: https://developers.google.com/search/blog/2021/04/more-details-page-experience
В связи с этим непонятна целесообразность внедрения AMP, учитывая, что трафик будет идти на сервера Google, а не ваш.
SimbirSoft_frontend Автор
Добрый день. Хотя эта технология не влияет на ранжирование напрямую, она способствует скорости загрузки, что косвенно позволяет сократить показатель отказов и улучшить ранжирование. Кроме того, реализация AMP-страниц входила в число обязательных требований владельца продукта.