Как заставить Angular Universal и PWA работать вместе?

У меня есть приложение SSR Angular, которое я пытаюсь преобразовать в PWA. Я хочу, чтобы он отображался на стороне сервера для SEO и для «быстрого первого рендеринга», который он обеспечивает.

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

Я покопался в коде ngsw-worker.js и увидел это:

// Next, check if this is a navigation request for a route. Detect circular
// navigations by checking if the request URL is the same as the index URL.
if (req.url !== this.manifest.index && this.isNavigationRequest(req)) {
    // This was a navigation request. Re-enter `handleFetch` with a request for
    // the URL.
    return this.handleFetch(this.adapter.newRequest(this.manifest.index), context);
}

У меня нет контроля над этим файлом, так как он взят из фреймворка и не доступен разработчикам. Кто-нибудь нашел решение или обходной путь для этого?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
9
0
3 996
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел рабочее решение, свойство navigationUrls элемента ngsw-config.json содержит список включенных или исключенных URL-адресов навигации (с восклицательным знаком), как описано в документация.

Затем я настроил это так:

"navigationUrls": [
    "!/**"
]

Таким образом, ни один из URL-адресов не перенаправляется на index.html, и приложение, отображаемое на стороне сервера, вступает в игру, когда приложение впервые запрашивается (или обновляется), каким бы ни был URL-адрес.

Чтобы пойти дальше, сервис-воркер управляет тремя типами URL-адресов:

  • URL-адреса без навигации: статические файлы, кэшированные сервис-воркером и перечисленные в сгенерированном файле ngsw.json с соответствующими хэшами.
  • URL-адреса навигации: по умолчанию перенаправляются на index.html, перенаправляются на сервер, если используется конфигурация "!/**"
  • GET запросы к бэкенду: перенаправлены на бэкенд

Чтобы отличить GETXMLHttpRequest от запроса навигации, сервис-воркер использует свойство Запрос.режим и заголовок Accept, который содержит text/html при навигации и application/json, text/plain, */* при запросе бэкенда.

Обновлено: на самом деле это не очень хорошая практика по двум причинам:

  • В зависимости от качества сети нет гарантии, что серверная версия будет отображаться быстрее, чем кэшированная версия браузера.
  • Это нарушает механизм «обновления в фоновом режиме». Действительно, приложение, отображаемое на стороне сервера, всегда будет ссылаться на последние версии файлов JavaScript.

Для получения более подробной информации об этом, пожалуйста, взгляните на ответ члена команды Angular на мой запрос функции: https://github.com/angular/angular/issues/30861

Обновление v11.0.0

В Angular теперь есть опция navigationRequestStrategy, которая позволяет расставлять приоритеты для запросов к серверу для навигации. Выдержка из журнала изменений:

service-worker: add the option to prefer network for navigation requests (#38565) (a206852), closes #38194

Чтобы использовать с умом! Это предупреждение появляется в документации:

The freshness strategy usually results in more requests sent to the server, which can increase response latency. It is recommended that you use the default performance strategy whenever possible.

Другие вопросы по теме