Новости

01.08.2023

Книга «JavaScript. Рецепты для разработчиков. 3-е изд»

Аудитория этой книги
Предупреждаем сразу: стремясь охватить все разнообразие тем и областей, в которых сегодня используется JavaScript, мы не рассчитывали на новичков в программировании. Для тех, кто начинает изучать программирование на JavaScript, есть так много хороших книг и учебных пособий, что мы со спокойной совестью посвятили свою практикующим разработчикам — тем, кто ищет решение конкретных проблем и задач на JavaScript.

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

 

16.3. Создание прогрессивного веб-приложения

 

Задача


Использовать в веб-приложении функции, свойственные обычным приложениям, такие как быстрая загрузка, автономная работа и загрузка значков.

Решение


Превратить веб-приложение в прогрессивное веб-приложение (Progressive Web Application, PWA). Этим термином описывают набор технологий, сочетание которых позволяет реализовывать в веб-приложениях такие типичные функции обычных приложений, как автономная работа и устанавливаемые пользователем значки приложений. При этом приложение по-прежнему строится на основе стандартных веб-технологий и распространяется через интернет.

У PWA помимо возможностей обычной веб-страницы должны иметься следующие два компонента:

  • манифест приложения — свойства приложения, о которых нужно сообщить браузеру;
  • Service Worker — функциональность, обеспечивающая автономную работу приложения.


Первый этап построения прогрессивного веб-приложения — создание файла с манифестом приложения. Благодаря этому файлу у разработчиков появляется доступ к такому функционалу, как значки приложений, всплывающие окна, стиль отображения приложения в браузере и ориентация веб-страницы. Содержимое файла manifest.json выглядит так:

{
    "name": "JavaScript Everywhere",
    "short_name": "JavaScript",
    "start_url": "/index.html",
    "display": "standalone",
    "background_color": "#ffc40d",
    "theme_color": "#ffc40d",
    "icons": [
        {
            "src": "/images/icons/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "/images/icons/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}


Теперь остается добавить в HTML-файлы и шаблоны ссылку на файл манифеста, а в раздел — соответствующие значки (пример 16.1).

Пример 16.1. Метатеги PWA

<!-- Ссылка на файл manifest.json -->
<link rel="manifest" href="manifest.json" />
<!-- Ссылка на значки iOS -->
<link rel="apple-touch-icon" sizes="180x180" href="images/icons/
           apple-touch-icon.png" />
<!-- Значки и цвета для плиток приложений Microsoft -->
<meta name="msapplication-TileColor" content="#ffc40d" />
<meta name="msapplication-TileImage" content="/img/icons/mstile-310x310.png" />
<!-- Цвет темы -->
<meta name="theme-color" content="#ffc40d" />


Если веб-сайт соответствует критериям PWA, то автоматически запускается система подсказок для установки PWA (рис. 16.1). После установки PWA на устройстве пользователя появляется значок PWA, как и при установке обычного приложения (рис. 16.2).

image


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

Первый шаг при создании Service Worker — регистрация скрипта, который будет содержать код Service Worker, в браузере пользователя. Для этого нужно разместить скрипт регистрации внизу страницы, непосредственно перед закрывающим тегом :

<!-- Инициализируем Service Worker -->
<script>
    if ('serviceWorker' in navigator) {
        window.addEventListener('load', function() {
            navigator.serviceWorker
                .register('service-worker.js')
                .then(reg => {
                    console.log('Service worker registered!', reg);
                })
                .catch(err => {
                    console.log('Service worker registration failed: ', err);
                });
        });
    }
</script>


В нем мы проверяем, поддерживает ли данный браузер технологию Service Worker, и, если поддерживает, даем браузеру ссылку на скрипт Service Worker (в данном случае это файл service-worker.js). Для удобства отладки в скрипте реализованы также перехват ошибок и вывод в консоль сообщений о них.

В файле service-worker.js прежде всего определяется версия кэша и приводится список файлов, которые должны кэшироваться в браузере:

var cacheVersion = 'v1';
filesToCache = [
    'index.html',
    '/styles/main.css',
    '/js/main.js',
    '/images/logo.svg'
]

 

При внесении изменений на сайте значение cacheVersion также необходимо изменить, иначе пользователи могут получать неизмененное содержимое сайта, сохраненное в кэше.


Затем в файле service-worker.js создаются обработчики событий install, fetch и activate. При возникновении события install браузеру передаются инструкции по установке файлов, сохраненных в кэше. При возникновении события fetch браузер получает инструкции по обработке таких событий: это может быть загрузка файлов — либо из кэша, либо полученных по сети. Наконец, событие activate, которое возникает при активации Service Worker, может использоваться для проверки объектов, хранящихся в кэше, и их удаления в случае, если изменилось значение cacheVersion или если данного файла больше нет в списке filestoCache (рис. 16.3):

image

 

const cacheVersion = 'v1';

const filesToCache = ['index.html', '/styles/main.css', '/js/main.js'];

self.addEventListener('install', event => {

    console.log('Service worker install event fired');
    event.waitUntil(
        caches.open(cacheVersion).then(cache => {
            return cache.addAll(filesToCache);
        })
    );
});

self.addEventListener('fetch', event => {
    console.log('Fetch intercepted for:', event.request.url);
    event.respondWith(
        caches.match(event.request).then(cachedResponse => {
            if (cachedResponse) {
                return cachedResponse;
            }
            return fetch(event.request);
        })
    );
});

self.addEventListener('activate', event => {
    event.waitUntil(
        caches.keys().then(keyList => {
            return Promise.all(
                keyList.map(key => {
                    if (key !== cacheVersion) {
                        return caches.delete(key);
                    }
                })
            );
        })
    );
});

 

Обсуждение


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

Манифест веб-приложения представляет собой файл в формате JSON, в котором содержится информация о приложении. Вот полный список основных значений, которые могут содержаться в этом файле:

  • background_color — код фонового цвета для экрана запуска;
  • categories — категории, к которым относится приложение, представленные в виде массива строк;
  • description — строка с описанием приложения;
  • dir — направление отображения символов: auto, ltr (слева направо) или rtl (справа налево);
  • display — предпочтительный режим отображения: browser (стандартное поведение браузера) или fullscreen (на некоторых устройствах браузер сворачивается);
  • iarc_rating_id — возрастной рейтинг (International Age Rating);
  • icons — массив объектов со ссылками на изображения и описания значков;
  • lang — основной язык приложения;
  • name — название приложения;
  • orientation — позволяет разработчику определить для приложения ориентацию экрана по умолчанию;
  • prefer_related_applications — если этот параметр равен true, то разработчик может указать аналогичные приложения, которые можно установить вместо данного веб-приложения;
  • related_applications — массив объектов, в котором содержится список аналогичных обычных приложений;
  • scope — строка, в которой обозначена область навигации приложения. Если она задана, то навигация внутри приложения ограничивается указанным здесь каталогом;
  • screenshots — массив копий экрана приложения;
  • short_name — сокращенное название приложения, которое можно использовать там, где полное название не помещается;
  • start_url — URL страницы, которая должна открываться при запуске приложения;
  • theme_color — строка, в которой указан цвет темы приложения, используемый по умолчанию.


В документации W3C приводится образец правильного файла манифеста для онлайн-игры (https://oreil.ly/zlk9P):

{
    "lang": "en",
    "dir": "ltr",
    "name": "Super Racer 3000",
    "description": "The ultimate futuristic racing game from the future!",
    "short_name": "Racer3K",
    "icons": [{
        "src": "icon/lowres.webp",
        "sizes": "64x64",
        "type": "image/webp"
    },{
        "src": "icon/lowres.png",
        "sizes": "64x64"
    },{
        "src": "icon/hd_hi",
        "sizes": "128x128"
    }],
    "scope": "/racer/",
    "start_url": "/racer/start.html",
    "display": "fullscreen",
    "orientation": "landscape",
    "theme_color": "aliceblue",
    "background_color": "red",
    "screenshots": [{
        "src": "screenshots/in-game-1x.jpg",
        "sizes": "640x480",
        "type": "image/jpeg"
    },{
        "src": "screenshots/in-game-2x.jpg",
        "sizes": "1280x920",
        "type": "image/jpeg"
    }]
}


На некоторых платформах, таких как iOS и Windows, для веб-приложения помимо файла манифеста нужно указать дополнительную информацию в виде метатегов HTML. В примере 16.1 с помощью метатегов определены цвет темы, значок iOS и параметры плиток Windows.Создание значков для всех возможных типов устройств и всех разрешений экрана может оказаться весьма утомительным занятием. Советую использовать RealFaviconGenerator (https://oreil.ly/AlsQe).

Service Worker — это скрипт, который выполняется в браузере в фоновом режиме параллельно с отображением и выполнением кода страницы. Поскольку это рабочий процесс (worker), он не имеет прямого доступа к DOM. Зато, поскольку Service Worker выполняется параллельно, благодаря ему у приложения появляется множество новых вариантов использования. Один из самых впечатляющих — возможность кэшировать куски приложения, чтобы потом оно могло работать автономно. В приведенном ранее примере я выполнил кэширование файлов HTML, JavaScript и CSS, чтобы обеспечить полноценную (хотя и по минимуму) автономную работу сайта.

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

Следует учитывать, что использование Service Worker накладывает следующие ограничения.

  • Сайты, на которых применяются скрипты Service Worker, обслуживаются только по протоколу HTTPS.
  • Скрипты Service Worker не работают, если пользователь включил в браузере режим приватного просмотра.
  • Поскольку браузер выполняет Service Worker в отдельном потоке, у Service Worker нет доступа к DOM.
  • Скрипты Service Worker ограничены своей областью видимости — это значит, что их необходимо размещать в корневом каталоге приложения.
  • Объем хранилища для кэша зависит от браузера и свободного места на жестком диске у пользователя.


В предыдущем примере я создал Service Worker вручную, однако при таком подходе большое приложение быстро станет неуправляемым. Для управления скриптами Service Worker и автономной работы веб-приложений можно использовать созданную Google библиотеку Workbox (https://oreil.ly/Gu3Z6). Она берет на себя большую часть забот по управлению версиями и кэшем и выполняет более сложные операции, такие как фоновая синхронизация и предварительное кэширование.

Прогрессивные веб-приложения — важный шаг в сторону интернет-приложений, не зависящих от фреймворка: они могут быть построены как на базе обычных HTML, CSS и JavaScript, так и с использованием одного из новых фреймворков JavaScript. В этом разделе мы лишь немного коснулись возможностей этих технологий. Подробное описание свойств и функциональных возможностей прогрессивных веб-приложений можно найти в книге Тала Альтера (Tal Alter) Building Progressive Web Apps, выпущенной издательством O’Reilly.

16.4. Тестирование и профилирование прогрессивных веб-приложений

 

Задача


Протестировать прогрессивное веб-приложение, чтобы убедиться, что оно удовлетворяет всем требованиям.

Решение


С помощью Lighthouse (https://oreil.ly/hEdHB) можно выполнить аудит производительности, доступности, соответствия лучшим рекомендациям, SEO и критериям прогрессивных веб-приложений. Чтобы получить доступ к Lighthouse, проще всего перейти на вкладку Lighthouse на панели инструментов разработки в Google Chrome. Откройте сайт (на рабочем или на локальном веб-сервере) и нажмите кнопку Generate Report (рис. 16.4).

image


Lighthouse сгенерирует отчет, включив в него рекомендации по улучшению всех показателей (рис. 16.5 и 16.6).

image

 

Подробнее об использовании Lighthouse на панели инструментов разработки Chrome для обычных сайтов, а не для прогрессивных веб-приложений, читайте в рецепте 11.4.



Обсуждение


Lighthouse — это инструмент, позволяющий проверить сайт на соответствие рекомендациям для веб-приложений, включая производительность и соответствие критериям прогрессивных веб-приложений. Инструмент Lighthouse встроен в панель инструментов разработки Chrome, его также можно установить в Firefox в виде расширения.

Lighthouse доступен не только в браузерах — его можно установить через npm и использовать в командной строке или как модуль Node. Lighthouse устанавливается так же, как и другие модули Node:

$ npm install -g lighthouse


Затем можно запустить Lighthouse, передав URL в качестве аргумента:

$ lighthouse https://www.oreilly.com/


Если вдобавок передать аргумент --view, то результаты откроются в браузере:

$ lighthouse https://www.oreilly.com/ --view


Можно также указать имя и расположение выходного файла, чтобы сохранить там результаты проверки:

$ lighthouse https://www.oreilly.com/ --view --output html
                                             --output-path ./report.html


С помощью файла budget.json можно проверить производительность с учетом заданных бюджетных ограничений. В файле budget.json задаются следующие ограничения тестирования:

[
    {
        "path": "/*",
        "timings": [
            {
                "metric": "interactive",
                "budget": 3000
            },
            {
                "metric": "first-meaningful-paint",
                "budget": 1000
            }
        ],
        "resourceSizes": [
            {
                "resourceType": "script",
                "budget": 125
            },
            {
                "resourceType": "total",
                "budget": 300
            }
        ],
        "resourceCounts": [
            {
                "resourceType": "third-party",
                "budget": 10
            }
        ]
    }
]

 

Команда Google Chrome создала репозиторий (https://github.com/GoogleChrome/budget.json), в котором хранится документация с описанием всех параметров budget.json.


Локальное тестирование из командной строки хорошо подходит для разработки на локальном сервере. Но главные возможности Lighthouse как модуля кода раскрываются при использовании средств непрерывной интеграции, таких как GitHub Actions, Circle CI, Jenkins и Travis CI. Модуль Lighthouse CI (https://github.com/GoogleChrome/lighthouse-ci) позволяет выполнять тестирование с помощью Lighthouse в конвейере непрерывной интеграции — например, при каждом запросе на внесение изменений в репозиторий GitHub.

Вот пример конфигурации Circle CI:

version: 2.1
jobs:
    build:
        docker:
            — image: circleci/node:10.16-browsers
        working_directory: ~/your-project
        steps:
            — checkout
            — run: npm install
            — run: npm run build
            — run: sudo npm install -g @lhci/cli@0.3.x
            — run: lhci autorun


Полное описание использования Lighthouse в разных средах непрерывной интеграции содержится в руководстве Google Getting Started (https://oreil.ly/7jnwx).

Об авторах
Адам Д. Скотт — ведущий инженер, веб-разработчик, преподаватель и художник из Коннектикута. Вот уже более десяти лет Адам работает на стыке технологий и образования, составляя учебные программы для ряда технических дисциплин. Это его седьмая книга.

Мэтью Макдоналд — технический писатель, обладатель статуса Microsoft MVP (Most Valuable Professional). Мэтью написал столько увесистых книг, что ими можно подпереть все двери в доме. На его сайте (https://prosetech.com) вы найдете бесплатную книгу «JavaScript для детей», а также можете ознакомиться с серией его публикаций по программированию для юных разработчиков, которая называется Young Coder.

Шелли Пауэрс работает в области веб-технологий и пишет о них уже более 12 лет. Ее последние книги, вышедшие в O’Reilly, были посвящены семантически структурированным сетям, Ajax, JavaScript и веб-графике. Шелли — заядлый фотограф и поклонница веб-разработки. Ей нравится применять результаты своих новейших экспериментов при разработке многочисленных сайтов.


Более подробно с книгой можно ознакомиться на сайте издательства.


Комментарии: 0

Пока нет комментариев


Оставить комментарий






CAPTCHAОбновить изображение

Наберите текст, изображённый на картинке

Все поля обязательны к заполнению.

Перед публикацией комментарии проходят модерацию.