Кэшируйте ресурс через свежесть в Angular 6 Service Worker - PullRequest
0 голосов
/ 17 октября 2018

Я пытаюсь интегрировать Angular Service Worker в существующий проект.Если я правильно понял, есть два случая, когда данные кэшируются в Angular SW.Можно предварительно выбрать или отложить обновление данных актива, а также кэшировать определенные вызовы 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?Было бы предпочтительнее не перемещать файл или изменять способ его запрашивания.

EDIT

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

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

У меня была такая же проблема.Решение, которое я нашел, чтобы всегда иметь свежие файлы js и css, состоит в простом исключении index.html из кэшированных ресурсов.

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

Убедитесь, что у вас есть "outputHashing": "all", для вашего углаКонфигурация сборки.Таким образом, когда вы вносите изменения в свой код, он генерирует файл с другим именем.Затем он автоматически добавит тег сценария (или тег ссылки) в ваш html-файл (который работник службы будет игнорировать), и как только вы отправите изменения в производство, index.html будет указывать на ваши новые файлы js и css.

Конечно, это отстой очень очевидным образом: ваш index.html не будет кэшироваться работником службы, но, по крайней мере, он позволит вернувшимся пользователям получать самые свежие файлы.

Мне бы очень хотелось, чтобы у активов был вариант «свежести» ...

0 голосов
/ 26 октября 2018

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

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

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

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

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

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

Добавление Angular Service Worker в существующее приложение

Давайте вручную выполним те же 4 шага сверху:

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

npm install @angular/service-worker --save

2.Включить поддержку сборки (только для Angular CLI 1.6, см. Примечание ниже)

ng set apps.0.serviceWorker=true

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

Важно!На данный момент, когда мы используем Angular CLI 1.5, убедитесь, что у вас нет этого свойства в .angular-cli.json, это приведет к ошибкам сборки.Посмотрите, как эмулировать этот шаг в Angular 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. На самом деле, есть 2 дополнительных действиядолжен выполняться в дополнение к команде ng build --prod (важно использовать производственную сборку, чтобы использовать NGSW!):

Создать NGSW файл управления (манифест) 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 - Angular PWA в его форме по умолчанию готов для нас!Разверните приложение или просто запустите его локально, используя любой статический веб-сервер (в моем случае пакет http-server, вы запускаете npm run serve-prod-ngsw для сборки и обслуживания).

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

enter image description here

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

enter image description here

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

NGSW использует Cache Storage для хранения данных ответов HTTP и некоторых метаданных для управления версиями:

enter image description here

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

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

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

Справа.Форма по умолчанию для файла конфигурации 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-адрес файла шрифта может время от времени изменяться для поддержки контроля версий веб-шрифтов.Также вы можете заметить, что мы не указали ни installMode, ни updateMode.С одной стороны, оба будут установлены как prefetch в результирующем управляющем файле NGSW, так как это значение по умолчанию.С другой стороны, они будут кэшироваться только после того, как они были запрошены, потому что специфика urls -way для перечисления ресурсов.

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

В Cache Storage мы увидим две новые записи:

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.

...