Commit 1775049b authored by yangjing@wanxin-holdings.com's avatar yangjing@wanxin-holdings.com
parents 36a7768c dc4a659a
Pipeline #19416 failed with stage
### 前言
作为一个前端开发者,每天都在和浏览器打交道,对于浏览器缓存,相信都不会陌生,同时它也是我们日常开发中存在的一个非常重要的优化手段,无论在节省带宽、提高加载和渲染速度、减少网络阻塞,以及提高用户体验上,都有重要的作用。
### 为什么需要缓存?
- 减少用户等待时间,提升用户体验,直接从内存或磁盘中取缓存数据肯定是比从服务器请求更快的。
- 减少了冗余的数据传输。
- 减少服务器的负担,大大提升了网站性能。
### 缓存读写顺序
![在这里插入图片描述](https://img-blog.csdnimg.cn/4418790e27e34187b27f2dc5741b2b77.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/089e4b196b3140a08ccf507205f24160.png#pic_center)
备注:
**memory cache** ==>浏览器本地缓存
**disk cache** => 硬盘缓存
1. 先在 浏览器缓存 中查找,如果有,直接加载。
2. 如果 浏览器缓存 中不存在,则在 硬盘 中查找,这里又细分:
1)如果有强缓存且未失效,则使用强缓存,不请求服务器。
2)如果有强缓存但已失效,使用协商缓存,比较后确定 304 还是 200;
3. 如果硬盘中也不存在,向服务器发起网络请求
4. 如果硬盘中也不存在,向服务器发起网络请求
***
下面将从** 缓存位置****缓存策略** 两个角度介绍浏览器缓存。
### 缓存位置
**memory cache(浏览器本地缓存)**
是浏览器内存中的缓存,相比于 disk cache 它的特点是读取速度快,但容量小,且时效性短;不受开发者控制,也不受HTTP协议头的约束。一旦浏览器 tab 页关闭,memory cache 就将被清空,再次重新打开相同页面时不再出现from memory cache的情况。
**disk cache(硬盘缓存)重点**
硬盘缓存取决于HTTP中的响应头信息,它也是浏览器缓存中最重要的内容。因为DNS缓存它主要是做一个ip地址查找并且是自主完成的,memory cache 也是不受控制,算是一个黑盒。所以剩下的可以受我们控制的硬盘缓存的重要性就不言而喻了,大多优化手段也是针对硬盘缓存。
根据 HTTP 响应头的各类字段进行判定资源的缓存规则,比如是否可以缓存,什么时候过期,过期之后是否需要重新发起请求呢?相比于 memory cache 的 disk cache 拥有存储空间时间长等优点。
### 缓存策略 - 强缓存和协商缓存
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?![在这里插入图片描述](https://img-blog.csdnimg.cn/899aaebbb3a946bf971b735c850a9c50.png#pic_center)
origin_url=7e63bfa1490c0013bbac3b012a832e50.png&pos_id=img-8561M81x-1699411348306)
根据 HTTP header 的字段将缓存分为两个部分,分别是**强缓存****协商缓存**
**强缓存:**使用强缓存策略时,如果缓存资源在过期时间内,是的话直接从本地缓存中读取资源,不与服务器进行通信。
**协商缓存:**如果强缓存失效后,客户端将向服务器发出请求,进行协商缓存。浏览器携带上一次请求返回的响应头中的 缓存标识 向服务器发起请求(如ETag、Last-Modified等),由服务器判断资源是否更新。如果资源没有更新,则返回状态码 304 Not Modified,告诉浏览器可以使用本地缓存;否则返回新的资源内容。强缓存优先级高于协商缓存,但是协商缓存可以更加灵活地控制缓存的有效性。
#### 强缓存
**强缓存**的字段有:**Expires **和 Cac**he-Control**。协商缓存的字段有:**Last**-**Modified ****ETag**
**Expires ****Cache-Control **都被设置的时候,浏览器会优先考虑后者。
**Last-Modified****ETag** 都被设置的时候,浏览器会优先考虑后者。
当强缓存失效的时候,则会进入到协商缓存阶段。
#### 协商缓存
一旦发现强缓存无效,浏览器会发送一个请求到服务器,服务器根据请求header中的部分信息来判断资源是否更新。如果没有更新,返回304重定向,告诉浏览器资源未更新,可继续使用本地的缓存;否则返回 状态码200 和 新的资源内容,浏览器缓存新的内容。
**Last-Modify / If-Modify-Since**
浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-Modify,Last-Modify是一个时间标识该资源的最后修改时间。
当浏览器再次请求该资源时,请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify。服务器收到 If-Modify-Since 后,根据资源的最后修改时间判断资源是否更新。
资源未更新,返回**304**重定向,表示资源未更新可以继续使用缓存中的资源。
资源更新,返回200状态码,返回新的资源,并进行硬盘和浏览器缓存。
缺点:如果资源更新的速度是小于 1 秒的,那么该字段将失效,因为 Last-Modified 时间是精确到秒的。所以有了 ETag。
**ETag / If-None-Match**
与 Last-Modify/If-Modify-Since 不同的是,Etag/If-None-Match 返回的是一个校验码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器上发送的 If-None-Match 值来判断是否缓存。
与 Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。
<br/>
```javascript
Cache-Control: max-age=3600 // 我希望你把这个资源缓存起来,缓存时间是3600秒(1小时)
Expires: Mon Oct 17 2023 16:10:32 GMT // 到达指定时间过期
Date: Mon Oct 16 2023 13:30:30 GMT
Etag:W/"121-171ca289ebf"// (后面协商缓存内容)这个资源的编号是W/"121-171ca289ebf"
Last-Modified: Mon Oct 16 2023 09:20:10 GMT // (后面协商缓存内容)这个资源的上一次修改时间
```
---
title: 被多次吐槽的elementUI 图标乱码问题终于解决了
date: 2023/9/26 19:48:20
tags:
- 前端
- elementUI
- vue
author: 李燕
---
#### 现象:图标乱码
参与做的Vue2+elementUI的项目中,图标偶尔会出现乱码的情况(刷新后就正常了),如下图。
<!-- more -->
![1.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c3d2fde084874c0e8e605f1cc6ca79ff~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=818&h=181&e=png&b=ffffff)
一开始以为是阿里图标库的问题,因为上图中的图标我们是从阿里图标库引入的,而不是elementUI自带的。
然后我们就把阿里图标库的引入方式由在线引入改为存到本地使用,但是乱码问题依然存在。
#### 本质:编译问题
在网上一番搜索,终于找到出现乱码的原因,是sass编译的问题。
.scss文件中通过伪元素方式添加的图标,经过sass编译后,样式中的content会变成乱码,如下:
![2.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/073c4da21d614d0f8992d910a57c8244~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=240&h=58&e=png&b=fffefe)
(el-select组件使用elementUI自带的图标)
![3.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b7fc17b17f2842b7836ee303309fe28b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=269&h=76&e=png&b=fffefe)
(el-select组件使用阿里图标库的图标)
el-select组件使用阿里图标库的图标经项目中的sass编译产生问题还能理解,那为什么el-select组件使用elementUI自带的图标也会产生编译问题呢?
因为项目中引用elementUI时,需要改主题色,就引入了包含了icon.scss的elementUI scss样式文件,该文件经过sass 会重新编译。但如果引入的是elementui 编译后的css 文件,sass就不会再编译了。
![4.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/25756c60fe6d4c32921af0abf6ad8c0b~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1241&h=348&e=png&b=1e1e1e)
#### 解决:两种策略
##### 一、更改写法:通过伪元素方式添加的图标均放到.css文件中,不用sass写法。
1.如果项目中在使用elementUI组件时直接用组件自带的图标,则只需在main.js中加入如下代码即可:
```
import 'element-ui/lib/theme-chalk/icon.css'
```
前提是检查element-ui/packages/theme-chalk/src/index文件中,是否引入了icon.scss文件。
如果未引入,则直接加如上一行代码就行。
如果引入了,则还需要修改项目里自定义element-ui主题的文件element-variables.scss。这个文件里本来有一个引入所有element组件scss文件的一行代码,如下。
```
@import "~element-ui/packages/theme-chalk/src/index";
```
把这一行去掉,然后直接引入所有的scss文件,除了icon.scss。
如下:
```
@import "~element-ui/packages/theme-chalk/src/common/transition.scss";
@import "~element-ui/packages/theme-chalk/src/pagination.scss";
@import "~element-ui/packages/theme-chalk/src/dialog.scss";
@import "~element-ui/packages/theme-chalk/src/autocomplete.scss";
...
```
2.如果项目中有在.scss文件中通过伪元素方式添加图标,则需要单独建立一个icon.css文件,把所有sass写法的图标改成css写法并放到icon.css文件中,然后再在main.js文件中引入:
```
import './styles/icon.css'
```
检查自己的项目,按照以上操作,即可解决问题。
##### 二、升级版本,添加配置
1. 将sass升级到1.39.0及以上版本
1. vue.config.js添加配置:
```
module.exports = {
...
css: {
   loaderOptions: {
     scss: {
       sassOptions: { outputStyle: 'expanded' }
    }
  }
},
 ...
}
```
若编译时出现如下提示
```
DEPRECATION WARNING: Using / for division is deprecated and will be removed in Dart Sass 2.0.0.
```
则执行以下命令:
```
$ npm install -g sass-migrator
$ sass-migrator division **/*.scss
```
具体参考:<https://blog.csdn.net/qq_38951259/article/details/127278847>
按照此方法,同样可以解决问题。
##### 三、其他
1.因项目中使用的sass默认是dart-sass,而elementUI中用的是node-sass。所以有网友建议卸载sass,安装node-sass。
2.还有网友建议保持已有的sass,然后安装css-unicode-loader插件,安装后在webpack配置针对scss、sass的文件loader中,在sass-loader前加上css-unicode-loader。
这两种方式我也尝试了一下,但是没有成功,有兴趣的可以去试试。
#### 验证:两种方式
##### 一. 按F12打开控制台,看样式代码
![5.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7146c467d4fa40eba3e93e49faa73777~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=273&h=68&e=png&b=fffefe)
如果对应图标的content像图中显示,则代表正常了,不乱码了。
##### 二、按F12后再多次按F5刷新
找到问题页面,按F12打开控制台后,如果多次刷新页面,图标都正常,说明乱码问题修复了。
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment