下一个泡泡玛特工程师是谁呢?

收集一些自己用到的prompt

2023-04-05 · 1 min read

机械键盘相关参数

机械键盘相关参数记录

2023-04-05 · 1 min read

Web 前端性能优化

常用的web前端性能优化手段

2023-03-19 · 3 min read

Blender常用快捷键

自己经常用到的一些快捷键记录

2022-12-11 · 1 min read

Docker 常用命令

精简 Docker 常用命令

2022-11-06 · 1 min read

项目管理

项目管理相关知识

2022-11-06 · 1 min read

JS沙箱sandbox的各种实现

我们把Js隔离机制常常称作沙箱

2022-09-18 · 1 min read

Amazing!Solid 比react还react

今天来介绍2个amazing的东东

2022-09-12 · 1 min read

puppeteer应用

使用傀儡师来操作浏览器这个傀儡吧

2022-09-11 · 1 min read

做一个web termianl

前端react, 后端nodejs, 直接可用版web termianl

2022-07-17 · 1 min read

TypeScript里常用的工具类型

经常用到的工具类型,提取抽离出来,供以后复用

2022-06-26 · 1 min read

Vim大法好

想要丢掉鼠标,试试Vim

2022-06-26 · 1 min read

碧血丹心

无论时光如何沾染风霜,也永似红日光

2022-05-10 · 1 min read

chrome V8 引擎中的垃圾回收机制

V8引擎就是nodejs的发动机

2022-03-03 · 1 min read

如何开发一个cli

命令行交互界面是程序员必备的工具,如何开发一个呢?

2022-02-21 · 1 min read

Javascript中的哲学

道生一,一生二,二生三,三生万物

2022-02-20 · 1 min read

React Redux 实现 (Context 版)

React Redux 实现 (Context 版)

2022-02-16 · 1 min read

mobx-react 使用

虽然不常用,但是可以学一下

2022-02-16 · 1 min read

Less中的for和forEach循环

循环的使用是保持代码干燥和避免重复的好方法

2022-02-15 · 1 min read

Webpack Splitchunks 详解

webpack 优化

2022-02-15 · 1 min read

ssh-keygen命令详解

为ssh生成、管理和转换认证密钥

2022-02-15 · 1 min read

使用CURL发送POST请求

curl 是常用的命令行工具,用来请求 Web 服务器。

2022-02-15 · 1 min read

Webpack Plugin 开发

让我们来学一下如何开发一个webpack插件

2022-02-14 · 1 min read

JS 实现两个大数相加?

algo-adding-large-numbers

2022-02-10 · 1 min read

字典树 trie

字典树 trie

2022-02-09 · 1 min read

浏览器原理问题

浏览器原理问题

2022-01-11 · 1 min read

MacBook快速进入一个文件夹目录

mac如何快速进入一个文件夹

2021-10-26 · 1 min read

react合成事件

react-synthetic-event

2021-10-25 · 1 min read

mini webpack实现

通过babel核心来实现迷你版的webpack

2021-10-10 · 1 min read

设计模式

在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于类

2021-10-10 · 1 min read

babel核心

babel核心介绍

2021-10-07 · 1 min read

React 15 和 React 16 的区别

react-15-16

2021-10-06 · 1 min read

React性能优化

浅谈react性能优化的方法

2021-10-05 · 1 min read

交通信号灯实现

如何用js来实现交通信号灯呢

2021-09-25 · 1 min read

内存管理

前端中的内存管理

2021-09-25 · 1 min read

前端安全

前端关于安全方面的知识

2021-09-25 · 2 min read

网络和并发

http各版本对于并发的支持,前端如何控制并发量?

2021-09-25 · 1 min read

跨域方法

总结了9种跨域方法

2021-09-24 · 1 min read

react virtualList 虚拟列表无限滚动实现

用react实现虚拟滚动

2021-09-16 · 1 min read

监控埋点方案

前端监控埋点方案

2021-09-16 · 1 min read

Mini useEffect实现

如何实现useEffect?

2021-09-11 · 1 min read

Mini useState 实现

我们来思考一下useState是怎么实现的呢?

2021-09-11 · 1 min read

React Fiber

react-fiber

2021-09-11 · 1 min read

React class组件和function组件异同

类组件和函数组件有何相同点有何不同点呢?

2021-09-11 · 1 min read

Lodash Get 实现

algo-lodash-get

2021-09-08 · 1 min read

手写reduce实现

algo-reduce

2021-09-08 · 1 min read

Hooks 原理概览

react-hooks

2021-09-05 · 1 min read

Hook原理——状态Hook

react-hook-state

2021-09-05 · 1 min read

手写Mini Redux实现

手写一个简易版的redux实现,包含了核心逻辑

2021-09-04 · 1 min read

legacy和concurrent模式

react-legacy-concurrent

2021-09-01 · 1 min read

react架构

总体 react 的核心可以用 ui=fn(state)来表示 3 大核心对象、3 大核心阶段、2 大工作循环 Scheduler(调度器): 排序优先级,让优先级高的任务先进行 reconcile Reconciler…

2021-09-01 · 2 min read

react核心api和jsx

为什么要有jsx,为什么会有虚拟bom

2021-09-01 · 1 min read

setState是同步的还是异步的

react-setstate-usestate

2021-08-31 · 1 min read

如何使用NodeJs创建HTTP服务?

如何使用NodeJs创建HTTP服务?

2021-08-17 · 1 min read

NodeJS 事件循环模型

nodejs-eventloop

2021-08-11 · 2 min read

Buffer

nodejs中的内存管理

2021-08-10 · 1 min read

微前端解决方案-qiankun

目前国内最好的微前端解决方案-qiankun

2021-08-10 · 1 min read

React Mini版实现(1)

学一门技术最好的方法就是做一个其玩具版的实现,我们来尝试实现一下react和react-dom最简单版本吧

2021-08-04 · 1 min read

brew安装

brew 是 MacOS 上的包管理工具,可以简化 macOS 和 Linux 操作系统上软件的安装。

2021-08-04 · 1 min read

CommonJS简易版实现

CommonJS我们经常用,如何实现一个简易版的commonJS呢?

2021-08-01 · 1 min read

极品透明Dashboard样式分享

一个极品透明Dashboard样式分享

2021-07-30 · 1 min read

Stream

nodejs中的流

2021-07-11 · 1 min read

NodeJS全局对象

JavaScript 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。

2021-05-18 · 1 min read

如何部署Nodejs服务

如何快速的部署一个Nodejs服务到公网呢?

2021-05-12 · 1 min read

Events

events模块是node的核心模块之一,几乎所有常用的node模块都继承了events模块,比如http、fs等。

2021-05-11 · 1 min read

用JS绘制背景,让CSS直接使用 'background:paint(xxx)'

CSS对象新特性,新的background设置方式

2021-04-30 · 1 min read

Block Formatting Context 块级格式化上下文

可以将BFC看成是元素的一种属性,拥有了这种属性的元素就会使他的子元素与世隔绝,不会影响到外部其他元素

2021-04-17 · 1 min read

如何使用Nodejs来创建一个TCP/UDP服务?

如何使用Nodejs来创建一个TCP/UDP服务?

2021-04-17 · 1 min read

Mac使用tree生成目录结构

程序员经常会有需求,需要列出项目的结构树。Mac或者Linux下可以使用tree列出项目结构

2021-04-04 · 1 min read

常见算法

一些比较常见算法

2021-03-20 · 1 min read

前端缓存

对于性能优化离不开缓存

2021-02-28 · 1 min read

前端答疑

一些比较常见的问题

2020-09-02 · 1 min read

Nodejs 网络 & HTTP

nodejs-network

2020-08-14 · 1 min read

JavaScript AST 抽象语法树

源代码的抽象语法结构的树状表现形式

2020-08-02 · 1 min read

nodejs里面向切面编程的一种范式

在一些场景下我们可能需要一种面向切面的编程方式

2020-08-01 · 1 min read

各种JS模块化特性

AMD、CMD、CJS、ESM

2020-05-30 · 1 min read

手写Ajax实现

使用HMR一步步实现Ajax

2020-05-30 · min read

手写PromiseA+实现

如何自己实现promiseA+规范,手写一个promise实现

2020-04-30 · 1 min read

debug和内存泄露

nodejs的debug方法

2020-04-08 · 1 min read

Javascript prototype 原型链

js-prototype

2019-09-07 · 1 min read

this指针、作用域

this是在执行时动态读取上下文决定的,不是在定义时决定

2019-06-14 · 1 min read

call、apply、bind的极简实现

使用symbol实

2019-06-03 · 1 min read

CSS联合选择器区分列表元素个数不同所要求的不同样式

对于列表,在有些时候针对于不同个数的item会有不同的显示,比如col份数,用js固然可以,是否可以用css更简便的实现呢?

2019-04-30 · 1 min read

TypeScript基础

介绍TypeScript基础知识

2019-04-30 · 1 min read

JS中的变量提升

为什么js当时要这样设计

2019-03-07 · 1 min read

ES6之Class

关于ES6里的class, 我们有什么不知道的事?

2019-03-01 · 1 min read

HTTP详解

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议

2019-02-17 · 2 min read

极简代码实现节流Throttle和防抖Debounce

使用各9行代码实现节流和防抖函数

2019-01-30 · 1 min read

Javascript 事件循环 EventLoop

js-eventloop

2018-09-07 · 1 min read

POST和GET区别

POST和GET区别是什么呢?

2018-08-14 · 1 min read

正则表达式

正则表达式一锅端

2018-07-30 · 1 min read

cloneDeep 深克隆实现

algo-clonedeep

2017-09-07 · 1 min read

webpack

engin-webpack

2017-09-07 · 1 min read

http1.1和http2.0有什么区别

http1.1和http2.0有什么区别

2017-06-14 · 1 min read

手写EventEmitter事件巴士

咱们来手写实现一个EventEmitter事件巴士

2017-01-10 · 1 min read

OOP 面向对象编程

对象是什么?为什么要面向对象?

2016-05-08 · 1 min read
Stay hungry & Stay foolish
战歌
16
The Reluctant Warrior
Immediate Music
To Glory
Two Steps From Hell
Victory
Two Steps From Hell
Empire of Angels
Thomas Bergersen
Serenata Immortale
Immediate Music
Cornfield Chase
Hans Zimmer
Tennessee
Hans Zimmer
He's a Pirate
Martin Ermen
Rise
Hans Zimmer
On Thin Ice
Hans Zimmer
Angels Will Rise
Twisted Jukebo
When It All Falls Down
Audiomachine
Icarus
Ivan Torrent
Star Sky - Instrumental
Two Steps From Hell
亡灵序曲
L
Up Is Down
Hans Zimm
回到首页

Web 前端性能优化

袁官东
March 19th, 2023 · 3 min read
图:Amrit Pal Singh

前端页面生命周期

web

1、用户在浏览器中输入 url 地址

2、浏览器解析域名得到服务器 ip 地址

浏览器会首先从缓存中找是否存在域名,如果存在就直接取出对应的 ip 地址,如果没有就开启一个 DNS 域名解 析器。DNS 域名解析器会首先访问顶级域名服务器,将对应的 ip 发给客户端;然后访问根域名解析器,将对应的 ip 发给客户端;最后访问本地域名服务器,得到最终的 ip 地址。

3、TCP 三次握手建立客户端和服务器的连接

因为 HTTP 是基于 TCP 的可靠传输,所以在发送 http 数据报之前,需要先进行 TCP 的三次握手建立连接。三次 握手过程如下:

第一次握手:客户端--->服务端 ack=1,seq=x(x 随机生成)

第二次握手:服务端--->客户端 ACK=1,ack=x+1,seq=y(y 随机生成)

第三次握手:客户端--->服务端 ACK=1,ack=y+1,seq=x+1

完成第三次握手时,实际上客户端已经与服务器建立了连接,所以第三次握手的报文已经可以携带数据了。

4、客户端发送 HTTP 请求获取服务器端的静态资源

5、服务器发送 HTTP 响应报文给客户端,客户端获取到页面静态资源

6、TCP 四次挥手关闭客户端和服务器的连接

数据传输完毕后,TCP 会进行四次挥手断开连接,释放资源。四次挥手过程如下:

第一次挥手:客户端--->服务器 FIN=1,ack=1,seq=u 客户端状态变为 FIN_WAIT_1

第二次挥手:服务器--->客户端 ACK=1,ack=u+1,seq=v 服务器状态变为 CLOSE_WAIT,TCP 进入半关闭状态

第三次挥手:服务器--->客户端 FIN=1,ACK=1,ack=u+1,seq=w 服务器状态变为 LAST_ACK

第四次挥手:客户端--->服务器 ACK=1,ack=w+1,seq=u+1 客户端状态变为 TIME_WAIT,此时 TCP 未释放,需要等 待计时器计时完成后,客户端状态变为 CLOSED

7、浏览器解析文档资源并渲染页面

浏览器解析文档资源并渲染页面流程:

(1)解析 html 资源,构建 DOM Tree

(2)解析 css 资源,构建 CSS Rule Tree

(3)JS 通过 DOM API 和 CSS OM API 来操作 DOM Tree 和 CSS Tree

(4)解析完成后综合 DOM Tree 和 CSS Tree 会生成 Render Tree,计算每个元素的位置,这个过程就是回流 (layout or reflow)

(5)调用操作系统 Native GUI 的绘制

(6)页面绘制完成

网络模型

  • OSI (理论)

模型武术忘传悔表赢

1应用层
2表示层
3会话层
4传输层
5网络层
6数据链路层
7物理层
  • TCP/IP (标准)

模型鼠王传音

1应用层
2传输层
3网络层
4数据链路层

http 头部

http 协议主要组成部分:

状态行 - General 请求头 - Request Headers 响应头 - Respones Headers 状态行

1
在状态行中我们其实一般来说只需要关注Request Method和Status Code就可以了。

请求头

2
一般来说前端开发需要关注请求头数据大概如下:

Accept - 客户端喜欢接受的数据类型 Accept-Encoding - 一般我们需要看的值就是 gzip,一般我们的资源都会 进行 gzip Accept-Language - 客户端支持的语言,按顺序使用 Cache-Control - 浏览器请求资源的缓存设置 ,no-cache 会比较常用,意思就是在使用缓存资源的时候必须先请求服务器进行验证 Pragme - 中间服务器不返 还资源标识,为兼容 http1.0 Connection - 开启持久链接,默认是 keep-alive(http1.1 才有哟) Cookie - 就 是将你浏览器中符合 cookie 的 path 中的 cookie 字段组成字符串提交给服务器 Referer - 页面来源,就是跳 转进当前页面的上一个页面路径 Content-Type - 告诉服务器提交的数据体是那种格式。响应头

3
响应头对于前端来说就十分重要了,无论是js或者css静态资源,或者是接口返回数据,里面的信息都十分重要。

Access-Control-Allow-Credentials - 跨域允许提交 cookie Access-Control-Allow-Methods - 跨域允许提交方 式 Access-Control-Allow-Origin - 跨域允许的域名路径(如果你的接口跨域可以检查一下这个哟,一般设置* 即可) Cache-Control - http 缓存策略 Connection - 开启持久链接,默认是 keep-alive(http1.1 才有哟) Content-Encoding - 一般我们需要看的值就是 gzip,一般我们的资源都会进行 gzip Content-Type - 告诉浏览 器以何种方式接收数据。 Set-Cookie - 服务器对浏览器设置 cookie 字段补充几个属性

Expires - 缓存到期时间 X-Cache - CDN 标识,有时候我们看 CDN 资源是否回源了,可以通过这个标识知道是否 命中到 CDN Content-Type 类型一般前端使用的 Content-Type 的类型有 3 种:

application/x-www-form-urlencoded - 默认方式,原生 ajax,jquery 都默认使用这种方式提交,该方式会将请 求的 json 数据格式序列化变成 key=value&key=value。 multipart/form-data - 这种方式一般是 form 表单提 交文件必须使用这种方式 application/json - 其实就是不进行序列化,直接以 JSON 方式提交,个人十分喜欢 content-type 属性在 request 头中是代表以何种数据格式进行提交,response 头中是代表浏览器需要以何种方 式接收数据以及解析数据。

keep-alive(TCP 链接持久化) 在 HTTP/1.0 里,为了实现 client 到 web-server 能支持长连接,必须在 HTTP 请求头里显示指定 Connection:keep-alive。

在 HTTP/1.1 里,就默认是开启了 keep-alive,要关闭 keep-alive 需要在 HTTP 请求头里显示指定 Connection:close。

如果不开启 keep-alive 的情况下,那么每一次请求都会重复 3 次握手,如果开启了的话,在一定时间内(这个 时间是服务器配置的)可以复用同一个 TCP。从而达到了性能的优化。

图像加载优化

图像延迟加载图片延时加载,是真实项目中的一个非常重要的性能优化手段。如果不做图片的延时加载,那也页面 渲染的时候,同时也要把图片资源请求回来,进行渲染,这样会阻碍页面的渲染进度,导致首次加载页面的速度很 慢,延迟加载一方面可以提要页面的加载速度,另一方面可以减少没必要的网络消耗

这里推荐使用 IntersectionObserver

1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <meta
6 http-equiv="X-UA-Compatible"
7 content="IE=edge"
8 />
9 <meta
10 name="viewport"
11 content="width=device-width, initial-scale=1.0"
12 />
13 <title>Document</title>
14 </head>
15 <style>
16 * {
17 margin: 0;
18 }
19
20 .imageLazyBox {
21 width: 236px;
22 height: 420px;
23 background: url(./images/loading.gif) no-repeat center center #eee;
24 background-size: 100px 100px;
25 margin: 1000px 0px;
26 }
27
28 .imageLazyBox img {
29 width: 100%;
30 height: 100%;
31 /* 开始图片隐藏:因为在ie 浏览器中,如果图片src 是空的,或者加载图片是错误的,图片不隐藏 ,会显示一个X
32 效果,很难看,所以图片没有加载之前还是让他隐藏比较好
33 办法一: display:none;这种办法加载完成真实的图片后,还需让他display:blok;这样触发dom的回流重汇,性能消耗比较大
34 办法二 :opacity:0 ;transition:opacity: .3s; ->推荐方案,一方面加载真实图片后,我们只需要设置opacity:1;
35 这样一方面不会引发dom的回流重汇,一方面可以css3实现出渐现的效果
36 */
37 opacity: 0;
38 transition: opacity 1s;
39 /* display: none; */
40 }
41 </style>
42 <body>
43 <div class="imageLazyBox">
44 <img
45 src=""
46 alt=""
47 lazy-image="./images/img1.jpeg"
48 />
49 </div>
50 </body>
51</html>
52<script>
53 function imageLazyFun(imageLazyBox) {
54 let imageItem = imageLazyBox.querySelector("img"),
55 lazy_image = imageItem.getAttribute("lazy-image");
56 imageItem.src = lazy_image;
57 imageItem.onload = function () {
58 imageItem.style.opacity = 1;
59 };
60 imageItem.removeAttribute("lazy-image");
61 imageItem.isLoad = true;
62 }
63
64 let imageLazyBox = document.querySelector(".imageLazyBox");
65 let ob = new IntersectionObserver((changes) => {
66 // 我们监听的dom元素与可视窗口的交叉信息
67 let item = changes[0];
68 target = item.target;
69 // 符合条件:盒子已经完全出现在视口中
70 if (item.isIntersecting) {
71 // 符合条件:盒子已经完全出现在视口中
72 imageLazyFun(target);
73 // 处理过一次延迟加载,以后这个元素出现无需要再次监听处理
74 ob.unobserve(target);
75 }
76 });
77 // 监听dom元素
78 ob.observe(imageLazyBox);
79 // 解除监听
80 // ob.unobserve(imageLazyBox)
81</script>

构建优化

并行构建(thread-loader、happypack)

构建缓存(cache-loader、hard-source-webpack-plugin)

代码切割(splitChunks):按需加载,分离基础库和公共代码库。通过分割打包,可以将公共代码或外包依赖项 单独打包,并从客户端缓存中受益。在此过程中,整个的包体积没有变小,且需要执行的请求可能会变多,但缓存 的好处可以弥补这一成本。

Hash 缓存

减少构建(external、DllPlugin)

Tree Shaking

预渲染

分离样式:通过 css-loader、style-loader 等一系列 loader 打包好了的 css,如果是通过内联到 js 中,就会 存在 css 无法缓存、增加了 js 文件体积和未样式化元素闪动(FOUC)问题。

静态资源、图片内联: 使用 url-loader 内联资源,将小图像转换为 base64 形式的字符串,从而减少 http 请 求。

第三方库 external

第三方库按需加载

渲染优化

减少不必要的回流

js 处理 -> 计算样式 -> 页面布局 -> 绘制 -> 合成

  • 渲染过程
  1. 解析获取到的 HTML,生成 DOM 树,解析 CSS,生成 CSSOM 树

  2. 将 DOM 树和 CSSOM 树进行结合,生成渲染树(render tree)

3.根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)

4.重绘(Painting):根据渲染树以及回流得到的几何信息,得到节点的绝对像素(像素,背景色,外观等)

5.Display 将像素发送给 GPU,展示在页面上。

  • 回流

浏览器会把获取到的 HTML 代码解析成一个 DOM 树,html 中的每一个元素都是 DOM 树的一个节点,根节 点也就 是我们说的 document 对象。在渲染树中的一部分(或者全部)因为元素的规模尺寸、布局 、显隐等改 变而需要 重新构建,这就称为回流。每次页面至少会发生一次回流,就是在页面第一次渲染的时候。

  • 何时发生回流?

添加或者删除可见的 DOM 元素元素的位置发生变化元素的尺寸发生变化(包括外边距、内边 距 、边框大小、高 度和宽度等)内容发生变化,文本或者图片被另一个不同尺寸的图片所代替页面开始渲染的 时 候浏览器的窗口尺 寸变化(回流是根据视口的大小来计算元素的位置和大小的)

  • 重绘 在渲染树中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格,不影响布局,就称为重绘 。

  • 什么时候发生重绘?

背景色改变样式发生改变的时候

  • 区别

回流必定会引起重绘,重绘一定不会引起回流

回流会导致页面重排,影响性能

恰当的使用 web worker

由于设计原因,长期以来浏览器中 JS 都是单线程工作的,我们通过 EventLoop 驱动异步事件完成工作。然而随 着前端页面越来越复杂,有些应用不可避免的要在前端执行大量的计算,这种情况会较长一段时间占用主线程,用 户会感觉到明显的页面卡顿。在这种场景下我们可以使用 WebWorker 来解决问题。

1// main.js
2const worker = new Worker("./worker.js");
3worker.onmessage = (e) => {
4 console.log(e.data);
5};
6
7worker.postMessage("hello worker");
1// worker.js
2onmessage = (e) => {
3 console.log(e.data);
4 postMessage("hi from worker");
5};
1// worker.js
2self.onmessage = (e) => {
3 console.log(e.data);
4 self.postMessage("hi from worker");
5};

将一个大任务拆分成多个微任务

1const taskList = splitTask(BigTask);
2
3function processTaskList(taskStartTime) {
4 let taskFinishTime;
5 do {
6 const nextTask = taskList.pop();
7 processTask(nextTask);
8 taskFinishTime = window.performance.now();
9 } while (taskFinishTime - taskStartTime < 3);
10
11 if (taskList.length > 0) {
12 requestAnimationFrame(processTaskList);
13 }
14}
15
16requestAnimationFrame(processTaskList);

缓存技术

强缓存

浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回 Status Code: 200 OK

200 form memory cache : 不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。 浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现 from memory cache。

200 from disk cache: 不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览 器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是 from disk cache。

优先访问 memory cache,其次是 disk cache,最后是请求网络资源

Expires:

过期时间,如果设置了时间,则浏览器会在设置的时间内直接读取缓存,不再请求 Cache-Control:当值设为 max-age=300 时,则代表在这个请求正确返回时间(浏览器也会记录下来)的 5 分钟内再次加载资源,就会命中 强缓存。 cache-control:除了该字段外,还有下面几个比较常用的设置值:

1(1) max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;
2
3(2) s-maxage:和
4max-age 是一样的,不过它只针对代理服务器缓存而言;
5
6(3)public:指示响应可被任何缓存区缓存;
7
8(4)private:只能针对个人用户,而不能被代理服务器缓存;
9
10(5)no-cache:强制客户端直接向服务器发送请
11求,也就是说每次请求都必须向服务器发送。服务器接收到 请求,然后判断资源是否变更,是则返回新内容,否则
12返回 304,未变更。这个很容易让人产生误解,使人误 以为是响应不被缓存。实际上 Cache-Control: no-cache
13
14是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。
15
16(6)no-store:禁止一切缓存(这个才是响应不被缓存的意思)。

cache-control

是 http1.1 的头字段,expires 是 http1.0 的头字段,如果 expires 和 cache-control 同时存

在,cache-control 会覆盖 expires,建议两个都写。

协商缓存

向服务器发送请求,服务器会根据这个请求的 request header 的一些参数来判断是否命中协商缓存,如果命中, 则返回 304 状态码并带上新的 response header 通知浏览器从缓存中读取资源;

Last-Modifed/If-Modified-Since 和 Etag/If-None-Match 是分别成对出现的,呈一一对应关系

  • Etag/If-None-Match:

Etag:

Etag 是属于 HTTP 1.1 属性,它是由服务器(Apache 或者其他工具)生成返回给前端,用来帮助服务器控制 Web 端的缓存验证。 Apache 中,ETag 的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间 (MTime)进行 Hash 后得到的。

If-None-Match:

当资源过期时,浏览器发现响应头里有 Etag,则再次像服务器请求时带上请求头 if-none-match(值是 Etag 的值 )。服务器收到请求进行比对,决定返回 200 或 304

  • Last-Modifed/If-Modified-Since:

Last-Modified:

浏览器向服务器发送资源最后的修改时间

If-Modified-Since:

当资源过期时(浏览器判断 Cache-Control 标识的 max-age 过期),发现响应头具有 Last-Modified 声明,则 再次向服务器请求时带上头 if-modified-since,表示请求时间。服务器收到请求后发现有 if-modified-since 则与被请求资源的最后修改时间进行对比(Last-Modified),若最后修改时间较新(大),说明资源又被改过,则 返回最新资源,HTTP 200 OK;若最后修改时间较旧(小),说明资源无新修改,响应 HTTP 304 走缓存。

Last-Modifed/If-Modified-Since 的时间精度是秒,而 Etag 可以更精确。

Etag 优先级是高于 Last-Modifed 的,所以服务器会优先验证 Etag

Last-Modifed/If-Modified-Since 是 http1.0 的头字段

性能检测

Performance 是 Chrome 浏览器自带的性能监测工具。根据我的使用,简单理解就是我们可以通过它录制一段时间 的浏览器活动,通过活动的数据去分析页面是否存在提升的空间。想要获取页面的活动数据,那我们的第一步便是 录制浏览器的活动。

具体做法可参考 https://www.cnblogs.com/mushanya/p/16827522.html

More articles from Favori 重剑

Blender常用快捷键

自己经常用到的一些快捷键记录

December 11th, 2022 · 1 min read

Docker 常用命令

精简 Docker 常用命令

November 6th, 2022 · 1 min read
© 2016–2023 Favori 重剑
Link to $https://github.com/yuanguandongLink to $https://favori.zcool.com.cn/Link to $https://codepen.io/favori