Кэш-ресурс через свежесть в угловом сервисе 6

Я пытаюсь интегрировать Углового Работника Службы в существующий проект. Если я правильно понял, есть два случая, как данные кэшируются в Угловом SW. Можно предварительно запрограммировать или lazyupdate данные о ресурсе и кэшировать определенные вызовы API и другие запросы XHR.

То, что я пытаюсь достичь, - это загрузить конкретный актив сначала по сети, если запрос запущен в тайм-аут или недоступен, он будет обслуживаться через кеш. Как и стратегия freshness при вызове API кеширования. Но, похоже, нет никакого способа настроить такой механизм загрузки свежести для JS файла, который загружается как актив в проекте Angular. Я установил пример проекта для тестирования: https://github.com/philipp-schaerer-lambdait/angular-service-worker-test

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

\_ Angular root  
 |_ src/
   |_ index.html <----------- links to excluded_asset.js
   |_ app/
   |_ assets/
     |_ excluded_asset.js <-- this one is excluded in ngsw-config.json
     |_ included_asset.js
     |_ ...

Здесь соответствующие конфигурации:

ngsw-config.json

{
    "index": "/index.html",
    "assetGroups": [
        {
            "name": "app",
            "installMode": "prefetch",
            "resources": {
                "files": ["/favicon.ico", "/index.html", "/*.css", "/*.js"]
            }
        },
        {
            "name": "assets",
            "installMode": "lazy",
            "updateMode": "prefetch",
            "resources": {
                "files": ["/assets/**", "!/assets/excluded_asset.js"]
            }
        }
    ]
}

Возможно ли достичь кэширующего поведения, такого как стратегия freshness, с помощью installMode и updateMode для активов?

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

После этого я попытался включить его снова через dataGroups и установил стратегию на freshness но кажется, что актива не будет кэшироваться снова, как только он исключен из конфигурации актива. Также я не думаю, что параметры dataGroups могут использоваться для этого файла.

"dataGroups": [
    {
        "name": "config",
        "urls": ["assets/excluded_asset.js"],
        "cacheConfig": {
            "maxSize": 10,
            "maxAge": "1d",
            "timeout": "100",
            "strategy": "freshness"
        }
    }
}

Я что-то пропустил или нет способа кэшировать актив через стратегию freshness? Было бы предпочтительнее не перемещать файл или изменять способ запроса файла.

РЕДАКТИРОВАТЬ

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

Ответ 1

Новое приложение с сервисным работником

Команда будет следующей:

ng new myApp --service-worker (or using the alias — -sw )

Имея этот флаг сервисного работника, Angular CLI 1.6 сделает для нас определенную автоматизацию:

  1. Будет установлен пакет "Угловой сервис".
  2. Поддержка сборки NGSW будет включена.
  3. NGSW будет зарегистрирован для вашей заявки.
  4. Файл конфигурации NGSW будет создан с некоторыми интеллектуальными значениями по умолчанию.

В любом случае, даже после того, как CLI 1.6 будет выпущен, хорошо знать, как воспроизвести эти шаги, потому что мы должны выполнить их вручную, чтобы добавить поддержку NGSW в существующее приложение. Переходим к добавлению Углового Рабочего Работника в PWAtter.

Добавление оператора углового обслуживания в существующее приложение

Позволяет вручную выполнить те же 4 шага сверху:

1. Установите NGSW

npm install @angular/service-worker --save

2. Включите поддержку построения (только для Углового CLI 1.6, см. Уведомление ниже)

ng set apps.0.serviceWorker=true

или вручную добавьте/отредактируйте этот параметр в .angular-cli.json.

Важный! На данный момент, когда мы используем Angular CLI 1.5, убедитесь, что у вас нет этого свойства в .angular-cli.json, это вызовет ошибки сборки. Посмотрите, как эмулировать этот шаг в Угловом CLI 1.5 ниже.

3. Зарегистрируйте NGSW в своем AppModule. Вот как это будет выглядеть в Angular CLI 1.6:

import { ServiceWorkerModule } from '@angular/service-worker'
import { environment } from '../environments/environment';

...

@NgModule({
  imports: [
    ...
    environment.production ? ServiceWorkerModule.register('/ngsw-worker.js') : []
  ],
  ...
})
export class AppModule { }

4. Создайте конфигурационный файл NGSW (имя по умолчанию - src/ngsw-config.json). Вот содержимое по умолчанию будет генерироваться с помощью Angular CLI 1.6.

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.ico",
        "/index.html"
      ],
      "versionedFiles": [
        "/*.bundle.css",
        "/*.bundle.js",
        "/*.chunk.js"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "lazy",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/**"
      ]
    }
  }]
}

В настоящий момент, используя Angular CLI 1.5, мы также должны эмулировать поддержку сборки с шага 2. На самом деле в дополнение к ng build --prod необходимо выполнить 2 дополнительных действия (важно использовать производственную сборку для использования NGSW):

Создайте файл управления NGNW (манифест) ngsw.json на основе конфигурационного файла NGSW src/ngsw-config.json, используя NGSW CLI ngsw-config.

Скопируйте NGSW непосредственно из папки пакета npm_modules в нашу папку dist.

Чтобы иметь одну простую команду для создания сборки с поддержкой NGSW, вы можете добавить некоторые скрипты npm:

{
  ...
  "scripts": {
    ...
    "ngsw-config": "node_modules/.bin/ngsw-config dist src/ngsw-config.json",
    "ngsw-copy": "cp node_modules/@angular/service-worker/ngsw-worker.js dist/",
    "build-prod-ngsw": "ng build --prod && npm run ngsw-config && npm run ngsw-copy",
    "serve-prod-ngsw": "npm run build-prod-ngsw && http-server dist -p 8080"
  }
}

Теперь, если мы запустим npm run build-prod-ngsw вас есть Angular PWA в папке dist. По желанию мы могли бы обслуживать его с помощью простейшего http-server, запустив npm run serve-prod-ngsw.

Важный! Не используйте ng serve сервис для проверки вашего Углового Рабочего Работника. Этот сервер разработки не был разработан для совместной работы с потоком PWA. Всегда создавайте производственную версию приложения и обслуживайте его из своей дистрибутивной папки с помощью любого статического веб-сервера.

Оболочка приложения

Если мы выполним вышеуказанные действия и запустим npm run build-prod-ngsw - Угловая PWA в форме по умолчанию готова для нас! Разверните приложение или просто запустите его локально, используя любой статический веб-сервер (пакет http-server в моем случае, вы запускаете npm run serve-prod-ngsw для сборки и обслуживания).

Приложение будет работать после того, как мы отправимся в автономный режим. Зачем? Поскольку NGSW кэшировал все ресурсы, перечисленные в разделе theassetGroups файла конфигурации, и теперь он отвечает за их обслуживание из хранилища кэшей, который теперь заполнен данными:

enter image description here

Сервисный рабочий зарегистрирован и активен

enter image description here

Мы можем просмотреть содержимое кэшированного ответа (доступно только в Chrome Canary на данный момент)

NGSW использует хранилище кэшей для хранения как данных ответов HTTP, так и некоторых метаданных для управления версиями:

enter image description here

Типы хранилищ по NGSW

  • Записи с postfix :cache - фактические ответы HTTP.
  • Записи с postfix :meta - для хранения метаинформации версии. Позже этот вид сохраненных данных может быть перемещен в indexedDB.

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

Правильно. Форма конфигурации файла конфигурации NGSW по умолчанию недостаточно для нашего случая, потому что мы используем веб-интерфейс Material Icons. Очевидно, что эти ресурсы (соответствующие файлы CSS и WOFF2) не были кэшированы NGSW, но мы можем легко исправить это, добавив еще одну группу в assetGroups в дополнение к app по умолчанию и assets по умолчанию. Позволяет называть его fonts:

{
  ...
  "assetGroups": [
   ...
   {
    "name": "fonts",
    "resources": {
      "urls": [
        "https://fonts.googleapis.com/**",
        "https://fonts.gstatic.com/**"
      ]
    }
  }]
}

Имеет смысл указывать эти ресурсы, используя синтаксис globs, потому что точный URL-адрес файла шрифта может время от времени меняться для поддержки управления версиями webfont. Кроме того, вы можете заметить, что мы не указали ни installMode ни updateMode. С одной стороны, оба будут установлены как prefetch в результате управляющего файла NGSW, так как это значение по умолчанию. С другой стороны, они будут кэшироваться только после того, как они были запрошены, потому что специфика urls -way перечисляет ресурсы.

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

В хранилище кэш-памяти см. Две новые записи:

enter image description here

Склады, созданные NGSW

Мы можем даже просмотреть кешированный шрифт:

enter image description here

Существует фундаментальное различие между assetGroups и dataGroups.

  • assetGroups отслеживает версию приложения [shell].
  • dataGroups не зависят от версии приложения. Они кэшируются с использованием собственных политик кэширования и его соответствующего раздела для обработки наших ответов API.

Кэширование времени выполнения

Использовать стратегию Network-First для конечной точки API моей /timeline и стратегии Cache-First для конечной точки /favorites. Соответствующая настройка в src/ngsw-config.json будет выглядеть так:

{
  ...
  "dataGroups": [{
      "name": "api-freshness",
      "urls": [
        "/timeline"
      ],
      "cacheConfig": {
        "strategy": "freshness",
        "maxSize": 100,
        "maxAge": "3d",
        "timeout": "10s"
      }
    },
    {
      "name": "api-performance",
      "urls": [
        "/favorites"
      ],
      "cacheConfig": {
        "strategy": "performance",
        "maxSize": 100,
        "maxAge": "3d"
      }
    }
  ]
}

Существует главный переключатель, определяющий поведение NGSW: cacheConfig/strategy. Для сетевой первой стратегии, ее freshness, для кэш-первых - performance.

Теперь создайте, выполните, нажмите "Загрузить мою временную шкалу" и загрузите мои кнопки "Избранное", чтобы получить и отбросить ответы API и переключиться в автономный режим.

Об оптимизации для онлайн-режима. Вернитесь в онлайн и нажмите " Timeline/Favorites один или два раза. Его отчетливо видно, что "Избранное" загружается немедленно, просто потому, что мы пропускаем всю сетевую поездку и получаем данные из кеша. Чтобы указать, как долго кэшировать Использование настроек в разделе cacheConfig - у нас есть мелкозернистый контроль.

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