Для удобства отражения сайта на мобильных устройствах зачастую нужно внедрить в проект страницу 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.
Спасибо за внимание! Надеемся, что этот пример был вам полезен.