浏览器——HTTP缓存机制与webpack打包优化

news2024/11/16 13:22:15

文章目录

    • 概要
    • 强缓存
      • 定义
      • 开启
    • 关闭强缓存
    • 协商缓存
      • 工作机制
        • 通过Last-Modified + If-Modified-Since
        • 通过ETag + If-None-Match
    • 不使用缓存
    • 前端利用缓存机制,修改打包方案
      • webpack 打包
      • webpack 打包名称优化
        • webpack 默认的hash 值
        • webapck其他hash 类型
        • 配置webpack打包
      • webpack 代码分割优化
    • 小结

概要

在前端开发中,经常接触到JavaScript脚本文件、CSS、HTML文件,每一次开发后,我们需要重新编译,会导致文件名发生变化。这样使得浏览网页时候,需要重新加载资源

如果能合理利用浏览器的缓存,可以提高响应速度。

浏览器缓存涉及到客户端和服务器之间的交互,当浏览器请求一个资源的时候,他首先检查该资源是否已经存在于HTTP缓存中,如果存在,并且满足不过期条件,浏览器则会使用缓存的资源,而不会从服务器重新请求。这个就是缓存的作用。

在实际的项目开发中,浏览器为我们提供下面的三种缓存机制:强缓存、协商缓存和不使用缓存,下面针对以上三个类型进行说明。

强缓存

定义

强缓存,直接使用缓存文件,不请求服务器。

开启

要实现强缓存,可以通过设置HTTP响应头和cache-control 、Expires字段来实现

  • 设置cache-control :在服务器响应中添加Cache-Control:max-age=3600,这将告诉浏览器可以将对应http资源缓存3600秒。这个时间内,浏览器直接从本地缓存加载该资源,而不会向服务器发送请求。
HTTP/1.1 200 OK
Date: Wed, 21 Oct 2025 07:28:00 GMT
Cache-Control: max-age=3600
Content-Type: text/html; charset=utf-8
Content-Length: 131
  • 设置 Expires:另一种设置方式就是使用Expire 字段,它的值是一个具体的时间,例如,Expires: Wed, 21 Oct 2025 07:28:00 GMT,表示资源将在2025 07:28:00之后过去

关闭强缓存

如果需要关闭强缓存,可以使用Cache-Control: no-cache,这将迫使浏览器每次都向服务器发送请求,通过协商机制来决定是否命中缓存

当设置成为no-store时,则完全禁止使用任何缓存,不存在协商,直接拉取服务器资源,重新加载。

协商缓存

浏览器协商缓存,也称为弱缓存,是一种利用HTTP响应头中的Last-Modified 和Etag字段来验证资源是否修改的机制,来决定是否使用本地缓存。在使用协商缓时候,一定要设置cache-control:no-cache ,这样才能发起请求,向服务器确认资源是否被修改。

工作机制

通过Last-Modified + If-Modified-Since

1.当我们第一次请求的时候,浏览器会在头添加Last-Modified 字段,这个值表示资源最后修改的时间

2.在这个资源后续的请求中,浏览器都会在请求头中,添加 If-Modified-Since 字段,这个值就是上一次服务器在响应头添加的Last-Modified 的值。

3.服务器接受到这个请求后,会根据 If-Modified-since 的值与服务器上的资源做对比,如果值不一致,服务器资源发送变化,则服务器返回最新的资源新的 last-Modified 字段

4.如果对比发现,服务器上资源最后修改时间请求的 If-Modified-since一致,则返回304 Not Modified 状态码,告诉浏览器可以使用本地缓存

通过ETag + If-None-Match

通过 ETag 方式来实现的话,原理和流程和上诉的一致,不同的是ETag 值表示文件唯一标识,这个值随着随着文件内容改动而发生变化,而如果文件内容没有改变,则ETag 值不会发生变化

在我们实际开发中,可以将ETag 理解成为文件的hash值,一旦文件改动,hash值变化。

不使用缓存

不使用缓存,将告诉浏览器,每一次加载资源,都需要重服务器请求获取最新的资源文件,可以通过以下的方式来实现

  • 设置 Cache-Control :在响应头上,将Cache-Control 设置为 no-store。将禁止使用任何缓存。
  • Expire 字段设置为0 ,表示资源立马过期。

前端利用缓存机制,修改打包方案

webpack 打包

我们日常的开发中,利用webpack 进行资源打包,默认情况下,生成的文件名称,带有hash 值。如下图中,用红线标出的地方,都是hash值。

在这里插入图片描述

这个hash 值是全局的不局限于当前文件,也就是说,只要当前项目有任何一个模块或文件的内容发生改动的时候,项目的hash值都会发生变化

如此一来,文件名称改动了,我们打包部署到服务后,客户端需要重新获取资源,而无法使用缓存来加快响应速度。

webpack 打包名称优化

webpack 默认的hash 值

在Webpack中,输出文件名的哈希值默认是[hash],这意味着每次构建时, 只要项目中有任何文件发生变化,生成的文件哈希值就会改变。这种哈希值与整个项目有关,因此它是全局的,不特定于某个文件或模块

webapck其他hash 类型

我们可以通过手动配置webpack 打包文件,来实现输出文件名的hash的控制,webpack 为我们提供处理[hash] 以外的方案,如下

  • contenthash
    [contenthash] 只有当前文件内容发生改动hash值才会发生变化。这有助于确保只有当文件内容发生变化时,文件名才会改变,从而有效地利用浏览器缓存。
  • chunkhash
    [chunkhash] 在一个文件中,如果被依赖的模块引入的文件资源发生变化时hash 值发生变化,而如果文件本身自己内容发生改动hash值是不会变化的。
配置webpack打包

我们可以通过手动配置webpack 输出文件名,将【hash】修改为【contenthash】来优化。

在webpack 项目中,可以修改 webpack.config.js 文件如下:

module.exports = {
  output: {
    filename: '[name].[contenthash].js',
    chunkFilename: '[name].[contenthash].chunk.js'
  },
};

webpack 代码分割优化

在我们日常开发中,常常引入第三方库,如vue.js ,elementUi等。这些第三方库,在我们项目搭建初期版本已经固定了后面不需要改动,如果修改升级,则另外讨论。

如果我们可以将这些第三方库,和自己手写的源码分割处理将第三方库独立出来,即使我们自己写的代码改动,不会影响第三方库文件模块,从而实现缓存命中。

幸运的是,webpack 默认带有代码分割的功能,它基于以下的规则

  • 共享模块
    如果一个新的块可以被多个入口点共享,Webpack会将其分割出来

  • 第三方库
    来自node_modules文件夹的模块通常会被分割出来。

  • 文件大小
    如果新的块在压缩和gzip之前的大小超过30kb,Webpack也会将其分割出来。

除此之外,我们可以通过 webpack.config.js 修改,如下

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

上面的参数,下面具体说明一下:

  • chunks
    控制哪些模块会被拆分。可选值,有:all、async(默认)、initial。
    all 表示所有模块都有可能被拆分async 表示只拆分动态加载initial表示不将动态和静态一起处理而是分开处理

  • minSize : 设置生成块最小单位(字节单位),如果生成的块小于这个大小,那么它不会被拆分

  • maxSize: 设置生成块最大单位,如果生成块大于这个大小,则会拆分成多个小块

  • minChunks:设置模块被引用的最小次数,一个模块被引用次数达到这个值后,才会被分到一个独立的包中

  • maxAsyncRequests:
    设置按需加载时并行请求最大数量。如果超过这个数量,则会把一些请求放到下一个chunk中

  • maxInitialRequests:
    设置入口点最大的并行请求数量。

  • cacheGroups
    这个选项允许你创建自定义的缓存组,以便更细粒度地控制哪些模块应该被分割,以及如何命名分割出来的文件。你可以为每个缓存组设置不同的测试条件、优先级、文件名等

小结

  • 实现强缓存,可以通过cache-control:max-age=36000,或这个Expire字段来实现

  • 关闭强缓存,可以设置 cache-control:no-cachecache-control:no-storeExpire:0

  • no-cache与no-store 区别在于,no-store禁止任何文件缓存,无法协商,no-cache 需要先和服务器协商来决定是否使用缓存

  • 协商缓存,可以通过Last-Modified/If-Modified-Since 或者 ETag/If-None-Match 来实现

  • 如果协商缓存中,文件没有发生该表,则将响应状态设置为304,告诉客户端使用缓存。

  • webpack 默认使用[hash]命名,颗粒度为整个项目文件,可以通过设置为[contenthash],将颗粒度细化到文件内容。

  • webpack 默认带有文件分割,可以分离第三方库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418394.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql运维篇(三) MySQL备份与恢复

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。如有侵权,请留言,我及时删除! 一、物理备份与逻辑备份 1、物理备份:备份数据文件,转储数据库物理文件到某…

isctf---misc

你说爱我?尊嘟假嘟 转换为ook编码 def convert_string(input_str):# 定义转换映射关系mapping {"你说爱我": "Ook.","尊嘟": "Ook!","假嘟": "Ook?"}# 遍历字符串,进行转换for key, va…

谷歌seo内容营销怎么做?

谷歌SEO内容营销就像是在为两个观众准备一场表演,一边是用户,一边则是谷歌搜索引擎,那么所谓的内容营销,你自然需要知道你的观众想看什么,这就是关键词研究,帮你了解用户在搜索什么,然后&#x…

什么是NAT?NAT类型有哪些?

晚上好,我的网工朋友。NAT是一种地址转换技术,它可以将IP数据报文头中的IP地址转换为另一个IP地址,并通过转换端口号达到地址重用的目的。 在大多数网络环境中,我们都需要通过 NAT 来访问 Internet。 NAT作为一种缓解IPv4公网地址…

数据预处理:纠偏

纠偏 1、偏态分布2、什么是纠偏3、数据纠偏 1、偏态分布 频数分布有正态分布和偏态分布之分。正态分布是指多数频数集中在中央位置,两端的频数分布大致对称 偏态分布是指频数分布不对称,集中位置偏向一侧。若集中位置偏向数值小的一侧,称为正…

航空MRO行业研究:2027年全球市场将达1200亿美元

随着全球航空运输业的不断发展,越来越多的航空器进入了使用年限,需要进行维修、修理和大修。这促进了航空MRO市场的不断增长。此外,航空器设备和技术的不断更新换代,也对航空MRO市场带来了新的机遇和挑战。 航空MRO市场是指维修、…

【Android】实现简易购物车功能(附源码)

先上结果&#xff1a; 代码&#xff1a; 首先引入图片加载&#xff1a; implementation com.github.bumptech.glide:glide:4.15.1配置权限清单&#xff1a; <!-- 网络权限 --><uses-permission android:name"android.permission.INTERNET"/><uses…

ubuntu22.04@laptop安装配置VNC服务端

ubuntu22.04laptop安装&配置VNC服务端 1. 源由2. 系统安装3. VNC安装3.1 系统更新3.2 lightdm安装3.3 x11vnc安装3.4 x11vnc配置3.5 x11vnc自启动3.6 x11vnc状态查询 4. 演示视频 1. 源由 最近系统搞TensorFlow, OpenCV, Python&#xff0c;折腾各种环境&#xff0c;把系统…

数据库管理-第139期 做大还是做小-Oracle名称哪些事(20240125)

数据库管理139期 2024-01-25 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09;1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Oracle A…

【备战蓝桥杯】——循环结构

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-bFHV3Dz5xMe6d3NB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

Leetcode刷题笔记题解(C++):1114. 按序打印(多线程)

思路&#xff1a; 保证A,B,C三个线程的顺序不会变&#xff0c;即优先级顺序的问题 A,B需要资源1&#xff0c;B,C需要资源2 A先占用资源1和资源2&#xff0c;A线程完了之后释放资源1不释放资源2&#xff0c;然后B线程占用资源1&#xff0c;A线程完了之后释放资源1和资源2&…

【极数系列】Flink配置参数如何获取?(06)

文章目录 gitee码云地址简介概述01 配置值来自.properties文件1.通过路径读取2.通过文件流读取3.通过IO流读取 02 配置值来自命令行03 配置来自系统属性04 注册以及使用全局变量05 Flink获取参数值Demo1.项目结构2.pom.xml文件如下3.配置文件4.项目主类5.运行查看相关日志 gite…

D6212——由八路达林顿管 阵列和 H 桥驱动电路两个单元组成,可用于驱动步进电机等产品上

D6212是专为安防摄像头系统设计的驱动电路&#xff0c;电路由八路达林顿管 阵列和 H 桥驱动电路两个单元组成。八路达林顿管阵列均带有续流二极 管&#xff0c;可用于驱动步进电机&#xff1b;H 桥驱动电路单元可以直接驱动IR-CUT。单个 达林顿管在输入电压低至 1.8V 状态下支持…

SQL中实现行列转换

目录 方法一&#xff1a;sum case when 方法二&#xff1a;sum if 方法三&#xff1a;pivot 现在有一张表class_gender&#xff0c;内容如下&#xff1a; classgender一年级女一年级女一年级男一年级男二年级女二年级女二年级男 现在我们要根据上表&#xff0c;统计得到下…

spring boot学习第八篇:操作elastic search的索引和索引中的数据

前提参考&#xff1a;elastic search入门-CSDN博客 前提说明&#xff1a;已经安装好了elastic search 7.x版本&#xff0c;我的es版本是7.11.1 1、 pom.xml文件内容如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns&q…

深分页怎么导致索引失效了?提供6种优化的方案!

深分页怎么导致索引失效了&#xff1f;提供6种优化的方案&#xff01; 上篇文章说到索引失效的几种规则&#xff0c;其中就有包括 深分页回表太多导致索引失效 的场景 本篇文章来聊聊深分页场景中的问题并提供几种优化方案&#xff0c;以下是本篇文章的思维导图&#xff1a; …

go学习之air库的使用

首先下载air库 go install github.com/cosmtrek/air之后你需要去找到库下载的地方&#xff0c;若使用的是go mod可以使用命令 go env GOPATH找到下载库的位置 进入后&#xff0c;有bin&#xff0c;pkg目录&#xff0c;进入bin目录&#xff0c;你能看到air.exe文件 这时候将此…

数据结构(队列Queue)

文章目录 一、队列1、队列的定义2、队列的顺序实现2.1、初始化2.2、入队2.3、出队2.4、查找2.5、判断队列 满/空 3、队列的链式实现3.1、初始化3.2、入队3.3、出队 4、双端队列 一、队列 1、队列的定义 2、队列的顺序实现 2.1、初始化 //初始化 void InitQueue(SqQueue &Q…

微信小程序(二十一)css变量-定义页面主题色

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.使用css变量 2.消除按钮白块影响 3.修改图标样式 源码&#xff1a; npmTest.json {"navigationStyle": "custom","usingComponents": {//引入vant组件"van-nav-bar"…

使用py-spy对python程序进行性能诊断学习

py-spy简介 py-spy是一个用Rust编写的轻量级Python分析工具&#xff0c;它能够监视正在运行的Python程序&#xff0c;而不需要修改代码或者重新启动程序。Py-spy可以在不影响程序运行的情况下&#xff0c;采集程序运行时的信息&#xff0c;生成火焰图&#xff08;flame graph&…