PWA 开发中如何应对浏览器缓存策略改变

在 PWA(Progressive Web App)开发中,浏览器缓存是一个重要的优化手段。通过合理地配置缓存策略,可以大幅减少数据传输的网络流量,加快页面加载速度,改善用户体验。然而,随着浏览器的不断升级,缓存策略的运作方式也在改变。本文将分析 PWA 开发中常见的浏览器缓存问题,并给出相应的解决方案。

1. 浏览器缓存的种类

在 Web 开发中,浏览器缓存主要分为两种:强缓存和协商缓存。强缓存是指浏览器直接从本地缓存中读取数据,而不需要发起 HTTP 请求。协商缓存则是指在强缓存失效的情况下,浏览器向服务器发起请求,通过协商机制(例如 If-Modified-Since 和 ETag)确认是否需要重新获取数据。下面是两种缓存的具体实现方式:

1.1 强缓存

强缓存可以通过设置 HTTP 响应头实现,常见的响应头字段有:

  • Cache-Control:设置缓存的有效期,常见取值有 max-age 和 no-cache;
  • Expires:设置缓存过期的时间点,通常不再使用。

例如,下面的代码将 index.html 文件的缓存有效期设为 12 小时:

-------- --- --
-------------- -------------
------------- ---------- -------------

--------- -----
------
------
  --------- -----------
-------
------
  --------- ----------
-------
-------

1.2 协商缓存

协商缓存需要服务器返回相应的响应头才能起作用,常见的响应头字段有:

  • Last-Modified 和 If-Modified-Since:用于判断数据是否被修改过;
  • ETag 和 If-None-Match:用于判断数据的内容是否有变化。

如果浏览器发现强缓存无效,就会发起协商缓存请求。服务器通过比对相应的头信息,如果数据没有改变,就返回 304 状态码和空响应体,告诉浏览器可以使用本地缓存。例如,下面的代码将静态资源的协商缓存实现为 ETag:

-------- --- --
------------- --------
----- -------

---- -
  ----------------- --------
  ---------- -----
-

2. 浏览器缓存的问题

然而,随着浏览器的不断升级,缓存策略的运作方式也在不断改变。以下是 PWA 开发中常见的浏览器缓存问题:

2.1 浏览器的缓存策略不一致

不同浏览器对缓存策略的实现可能有所不同,例如 Safari 浏览器对 HSTS(HTTP Strict Transport Security)的实现就和 Chrome 不一样。这就使得开发者难以掌握浏览器的缓存逻辑,从而可能产生奇怪的问题。解决办法是,尽可能使用标准的缓存头字段,避免使用浏览器特有的缓存机制。

2.2 缓存策略的兼容性问题

不同版本的浏览器对缓存头字段的解析方式也可能不一样。例如,某些浏览器可能会将 Content-Length 和 Last-Modified 字段忽略,从而导致协商缓存失效。这就需要开发者花费大量的时间来测试不同浏览器的表现,并可能需要针对不同浏览器采用不同的缓存策略。解决办法是,尽可能使用简单、通用的缓存头字段。

2.3 静态资源的版本管理

对于静态资源而言,版本管理是十分重要的。如果没有良好的版本管理机制,就可能导致缓存不更新,从而无法正确显示最新的页面。通常,可以在 URL 中嵌入版本号或者哈希值,或者使用构建工具对文件名进行哈希化处理,从而保证每个静态资源都有唯一的名称。例如,下面的代码使用文件的哈希值作为版本号:

-------- --- --
-------------- ----------------
------------- --------
----- -------
-------------- ---- - --- ---- -------- ---
-------- ---- -- --- ---- -------- ---

----- ---------------- -----------------------------------

3. 应对浏览器缓存策略的变化

面对不同的浏览器缓存策略,我们需要相应地采取不同的优化策略。以下是一些常见的应对措施:

3.1 推荐使用 Cache-Control

Cache-Control 是 HTML5 推荐的缓存头字段,它可以统一控制缓存的行为。例如,可以设置:

  • max-age:指定缓存的有效时间,单位为秒;
  • no-cache:指示浏览器不要对该资源进行强缓存,需要利用协商缓存向服务器验证;
  • no-store:指示浏览器不要对该资源进行任何缓存操作,每次都要重新从服务器获取。

例如,下面的代码将静态资源设为永久缓存,并启用 ETag 协商缓存:

-------- --- --
-------------- ----------------- ---------------
------------- ----------
----- -------
-------------- ---- - --- ---- -------- ---
-------- ---- -- --- ---- -------- ---

---- -----------------------

3.2 配合使用 ETag 和 Last-Modified

ETag 和 Last-Modified 可以一起使用,让浏览器更加准确地判断数据是否有变化。例如,下面的代码将静态资源的协商缓存实现为 ETag 和 Last-Modified:

-------- --- --
------------- --------
----- -------
-------------- ---- - --- ---- -------- ---

---- -
  ----------------- --------
  ---------- -----
-

3.3 版本管理

为了避免静态资源缓存失效,我们需要对每个版本的静态资源进行版本管理。可以使用构建工具对文件名进行哈希化处理,或者在 URL 中嵌入版本号或者哈希值。例如,下面的代码使用文件的哈希值作为版本号:

-------- --- --
-------------- ----------------
------------- --------
----- -------
-------------- ---- - --- ---- -------- ---
-------- ---- -- --- ---- -------- ---

----- ---------------- -----------------------------------

4. 总结

在 PWA 开发中,浏览器缓存是一个重要的优化手段。不同的浏览器缓存策略可能不一致,因此我们需要相应地采取不同的优化策略,购合理地利用缓存头字段,进行版本管理,以提高用户体验。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/647ff7dd48841e9894f7aeef


猜你喜欢

  • ES6 和 ES7 中 Symbol 的入门指南

    随着 JavaScript 越来越流行,每个新版本都会带来新的功能和标准。其中,ES6 和 ES7 中的 Symbol 是一个非常有用的新特性。在本篇文章中,我们将会深入了解 Symbol,了解它的作...

    1 年前
  • 异步编程解决方案:Promise 的拓展

    异步编程解决方案:Promise 的拓展 在现代web应用程序中,异步编程是非常常见的。异步编程使得我们可以编写代码来处理网络请求,访问数据库,和处理其他长时间的操作。

    1 年前
  • ECMAScript 2020 中的新特性:显著提高 JavaScript 开发效率

    随着大量 Web 应用程序的产生和前端技术的不断发展,JavaScript 语言也在不断演化。ECMAScript 2020 是 JavaScript 的最新版本,引入了一些激动人心的新特性,这些特性...

    1 年前
  • 在ESLint中使用自定义规则编写规则

    在前端开发中,使用ESLint是一个不可或缺的工具,它可以帮助我们检查代码中的错误并规范代码风格。除了ESLint提供的默认规则,我们还可以通过编写自定义规则来满足特定的需求。

    1 年前
  • 能与阿里云 Serverless 能打的电商研发架构

    电商行业的繁荣发展,不仅带来了商机,也带来了技术上的挑战。传统的电商架构通常存在着高负载、低扩展性等问题,因此阿里云 Serverless 技术应运而生。本文将介绍如何能与阿里云 Serverless...

    1 年前
  • Sequelize 之分组 Count 查询数据

    Sequelize 是 Node.js 平台上热门的 ORM(Object-Relational Mapping)库,它允许我们使用操作对象的方式来操作关系型数据库。

    1 年前
  • Docker 部署 Node.js 应用实践

    前言 Docker 作为一款流行的容器化技术,可以改变传统应用部署的方式,提高开发效率、运维效率。而 Node.js 作为一种高性能、跨平台的 JavaScript 运行环境,也有许多开发者在使用。

    1 年前
  • 使用 GraphQL 的状态管理器

    随着前端应用变得越来越复杂,状态管理就成为了一个不可忽视的问题。前端框架提供的状态管理方案如 Redux、MobX 减轻了这个问题,然而使用这些方案会带来一些复杂性,例如大量的模板代码和繁琐的接口调用...

    1 年前
  • 使用 Express.js 将 Twitter 数据可视化并保存

    介绍 Express.js 是一个功能强大的 Node.js 框架,可以帮助开发者构建基于 web 的应用程序。通过 Express.js,可以快速地创建一个可扩展、易于维护的 web 应用程序。

    1 年前
  • ES10 中 Object.is 和 Number.isNaN 函数的使用技巧

    ES10 是 JavaScript 的最新版本,其中包含了许多有用的新特性,其中 Object.is 和 Number.isNaN 函数是其中两个非常有用的函数。在本文中,我们将会详细讨论这两个函数的...

    1 年前
  • 使用 Webpack4 + Vue.js 搭建优化的开发模式

    在前端开发中,使用工具可以提高开发效率,优化开发体验。其中,Webpack 是前端开发中应用最广泛的打包工具。Vue.js 则是一款流行的 MVVM 前端框架。在使用 Webpack4 和 Vue.j...

    1 年前
  • 使用 ES6 的箭头函数重构 Vue.js 代码

    Vue.js 是一个流行的前端框架,它为 Web 应用程序开发提供了一个强大的工具集。随着 ES6 规范的逐渐普及,Vue.js 也逐渐加入了 ES6 的新特性支持。

    1 年前
  • ES7 中的 Reflect.defineMetadata 函数:使用方法详解

    在 ES7 中,新增了一种元编程(meta-programming)工具:Reflect.defineMetadata 函数。该函数可以为对象或函数设置元数据信息,以便在运行时进行动态控制和修改。

    1 年前
  • Jest 测试时如何 mock 页面中的 ajax 请求和接口请求?

    Jest 是一种流行的 JavaScript 测试框架,它提供了一个简单易用的 API,可以快速编写和运行测试用例。在前端开发中,通常需要测试某些依赖于 AJAX 请求或者接口数据的代码。

    1 年前
  • # 如何在 Fastify 框架中实现微信支付功能

    如何在 Fastify 框架中实现微信支付功能 快速和可扩展的Web框架已经成为前端开发中不可或缺的工具。其中,Fastify是一个高效,快速和低开销的Web框架,它具有丰富的插件生态系统和易于使用的...

    1 年前
  • 如何使用 SSE 实现后端推送前端消息

    在现代 Web 应用程序中,实时性变得更加重要,尤其是在像在线游戏、实时数据可视化和聊天应用程序等场景下。为了实现实时通信,需要一种机制来在 Web 上进行长时间的持续连接, SSE(Server-S...

    1 年前
  • 如何使用 Enzyme 测试 React Native 中的布局

    Enzyme 是一个流行的 React 测试工具,它可以帮助我们测试 React 组件的各种行为和状态。在 React Native 中,我们同样可以使用 Enzyme 来进行布局测试。

    1 年前
  • # 无障碍设计:如何让产品操作更容易理解?

    无障碍设计:如何让产品操作更容易理解? 随着互联网与移动互联网的快速发展,越来越多的人开始依赖产品与服务进行日常生活和工作。然而,由于很多产品的设计不够友好,以及不同人群的个体差异,很多用户在使用产品...

    1 年前
  • 解决 Deno 中编码问题的方法

    在 Deno 中,处理编码问题是一个常见的任务。由于 Deno 默认使用 UTF-8 编码,当读取其他编码格式的文本时,常常会遇到编码不一致的问题。本文将介绍一些解决 Deno 中编码问题的方法,其中...

    1 年前
  • 使用 Angular 和 RxJS 在 TypeScript 中进行响应式编程教程

    响应式编程(Reactive Programming)是一种基于数据流和变化传播的编程方式,它可以用来构建高效且响应性能好的程序。Angular 和 RxJS 是两个流行的响应式编程框架,它们可以协同...

    1 年前

相关推荐

    暂无文章