Ленивая загрузка маршрутов - популярный метод ускорения загрузки страницы за счет разделения файла сборки на множество фрагментов и загрузки его по запросу. Функция асинхронных компонентов Vue и функция разделения кода в webpack упростили отложенную загрузку компонентов маршрута.

Чтобы узнать больше об этой реализации, вы можете проверить мою предыдущую статью об этом здесь

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

Когда я перезагружаю страницу в обход кеша (команда + shift + r на Mac Chrome), навигация по странице работает нормально. При дальнейшей отладке стало очевидно, что проблема возникла при развертывании новой сборки. Ах !!!, виноват "кеш браузера".

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

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

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

Но когда пользователь попытался загрузить новый ленивый маршрут, который еще не был посещен, браузер просмотрел манифест js и сделал сетевой вызов, запрашивая соответствующий фрагмент js. Поскольку наш файл манифеста также был старым, он запросил блок js, который принадлежал более старой версии сборки, и наш сервер выдал ошибку «файл не найден».

Чтобы решить эту проблему, я изменил конфигурацию Nginx, как показано ниже.

location ~* \.html?$ {
    expires -1;
    add_header Pragma "no-cache";
    add_header Cache-Control "no-store, must-revalidate";
  }

это отключает кеширование файлов HTML. Поскольку все маршруты загружались лениво, это не сильно повлияло на время загрузки приложения, поскольку фрагменты js и css все еще кешировались. Это помогло решить проблему? Да, но частично.

Приложение будет работать нормально без каких-либо проблем, если пользователь откроет приложение в новом окне / вкладке после развертывания. Но проблема все равно будет возникать у пользователей, работающих с уже открытыми страницами.

Причина, по которой манифест js указывал на фрагменты js старой версии, и нам нужно было перезагрузить страницу, чтобы решить эту проблему. Мы можем использовать хук onError vue router, чтобы перезагрузить страницу, если загрузка блока завершилась неудачно.

router.onError(error => {
  if (/loading chunk \d* failed./i.test(error.message)) {
    window.location.reload()
  }
})

При желании мы также можем показать предупреждающее сообщение с просьбой перезагрузить страницу.

Внимание: бесконечная перезагрузка

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

Francium Tech - это технологическая компания, специализирующаяся на поставке высококачественного программного обеспечения в масштабе с экстремальной скоростью. Цифры и размер данных нас не пугают. Если у вас есть какие-либо требования или вы хотите бесплатно проверить работоспособность ваших систем или архитектуры, напишите письмо на адрес [email protected], мы свяжемся с вами!