【HTTP之浏览器缓存及渲染】

一、为什么要进行浏览器缓存?

  1. 减少 HTTP 请求次数,避免重复建立连接,缩短页面加载时间,提升用户体验。
  2. 减少服务器压力,降低带宽、CPU、IO 消耗,减少服务端成本。

二、浏览器缓存机制:

明确浏览器请求的不同情况:

第一件事:第一次请求(从来没访问过)

浏览器:

  • 本地什么都没有
  • 没有资源
  • 没有缓存
  • 没有任何过期规则

所以: 必须发 1 次请求服务器返回:

  1. 资源内容
  2. 缓存规则(Cache-Control / Expires)
  3. 缓存标识(ETag / Last-Modified)

浏览器把这三样全部存在本地


第二件事:第二次、第三次、第 N 次请求

浏览器:

  • 本地已经有缓存规则了
  • 上一次请求时,服务器给你的
  • 存在硬盘 / 内存里,不用再问服务器要

所以:👉 浏览器直接看本地已有的规则自己判断:

  • 过期了吗?
  • 能用缓存吗?

这个过程,不发任何请求。


2. 缓存整体流程

浏览器执行缓存先查浏览器缓存中的强缓存,然后再决定是否用协商缓存。

  1. 先查强缓存
    • 有效:直接用本地,不发请求(200 from cache)
    • 无效:发请求,走协商缓存
  2. 再查协商缓存
    • 服务端验证未修改:304 Not Modified,用本地缓存
    • 已修改:200 + 新资源

3. 强缓存(不发请求)

作用

资源未过期,直接本地读取,不和服务器通信。

字段

  • Cache-Control(HTTP/1.1,主流)
    • max-age=秒数:相对过期时间
    • no-cache不走强缓存,直接走协商缓存
    • no-store完全不缓存(最强禁用)
  • Expires(HTTP/1.0,旧)
    • 绝对时间,受本地时间影响

优先级:Cache-Control > Expires


4. 协商缓存(发请求,但省流量)

作用

强缓存过期后,问服务器资源是否更新

第一组:Last-Modified / If-Modified-Since

  • 服务端返回:Last-Modified: 最后修改时间
  • 浏览器请求带:If-Modified-Since: 上次时间
  • 服务端对比:没变 → 304;变了 → 200 + 新内容

第二组:ETag / If-None-Match(更精准)

  • 服务端返回:ETag: 资源唯一标识(哈希)
  • 浏览器请求带:If-None-Match: 上次标识
  • 服务端对比:一致 → 304;不一致 → 200 + 新内容

优先级:ETag > Last-Modified


明确:缓存规则完全由服务器通过响应头控制,浏览器只是遵守规则。

5.强制缓存和协商缓存的触发是由什么决定的呢?

5.1强制缓存和协商缓存的触发,由 Cache-Control 直接决定

浏览器的缓存决策流程是分层判断 的,Cache-Control 是第一层(强制缓存层)的 "总开关",它的指令直接决定:

  • 是否进入「强制缓存判断」
  • 如果强制缓存不生效,是否进入「协商缓存」
  • 还是直接跳过所有缓存,发全新请求
5.1.2决策表(核心)
Cache-Control 指令 强制缓存是否生效 协商缓存是否触发 最终行为总结
max-age=3600(有有效期) 生效 不触发(过期前) 有效期内直接用缓存(0 请求);过期后触发协商缓存
no-cache 不生效 触发 每次都发请求(带协商标识),服务器判断是否用缓存
no-store 不生效 不触发 完全不缓存,每次发全新请求(不带任何缓存标识)
无 Cache-Control 字段 不生效 触发 走默认协商缓存流程
5.1.3关键结论:

Cache-Control 是通过是否允许浏览器 "自主判断使用缓存" 来控制流程:

  • 只要指令允许强制缓存(如 max-age)→ 浏览器先判断强制缓存,生效则不走协商;
  • 只要指令禁止强制缓存(如 no-cache)→ 跳过强制缓存,直接走协商缓存;
  • 只要指令禁止缓存(no-store)→ 跳过所有缓存,发全新请求。

5.2拆解 Cache-Control 控制逻辑的底层原理

我们以"动态页面(个人中心)用 no-cache"为例,一步步看 Cache-Control 是如何和浏览器缓存规则、HTTP 流程联动的:

5.2.1 Cache-Control: no-cache 的字面意思(先纠偏)

很多人误以为 no-cache = "不缓存",但真实含义是:

"不允许浏览器直接使用本地缓存(强制缓存失效),必须先向服务器验证(走协商缓存)"。

它的核心是:缓存依然会存,但用之前必须问服务器

5.2.2 动态页面用 no-cache 的完整执行流程(和 HTTP 联动)

假设你访问 https://xxx.com/user/123(个人中心),服务器返回 Cache-Control: no-cache + ETag: "user123-v1"

第一次访问(无缓存):

  1. 浏览器查本地缓存 → 无 → 发 1 次请求;

  2. 服务器返回:

    javascript 复制代码
    HTTP/1.1 200 OK
    Cache-Control: no-cache  # 禁止强制缓存
    ETag: "user123-v1"       # 协商缓存标识
    # 个人中心页面内容(如用户名、头像、订单)
  3. 浏览器依然会把页面内容 + ETag 存到本地缓存 (注意:no-cache 不是不存,是不用)。

第二次访问(有缓存,但 no-cache 生效):

  1. 浏览器查本地缓存 → 有页面 + ETag,但看到 Cache-Control: no-cache

  2. 浏览器决策:no-cache 禁止强制缓存 → 跳过强制缓存判断

  3. 浏览器构造请求,带上协商缓存标识:

    javascript 复制代码
    GET /user/123 HTTP/1.1
    If-None-Match: "user123-v1"  # 本地存的ETag
  4. 服务器判断:

    • 如果用户数据没改(如没换头像、没下单)→ 返回 304 Not Modified,浏览器用本地缓存;
    • 如果用户数据改了 → 返回 200 OK + 新页面 + 新 ETag,浏览器更新缓存。

5.3 对比:如果动态页面用 max-age=3600(错误做法)

  1. 第一次访问:存缓存 + 规则;
  2. 第二次访问:浏览器看 max-age 没过期 → 直接用本地缓存(0 请求);
  3. 问题:用户改了头像,但浏览器还显示旧头像(强制缓存生效,没问服务器)→ 数据不一致。

这就是为什么动态页面必须用 no-cache禁止浏览器自主用缓存,每次都问服务器,保证数据最新

6. 为什么 ETag 比 Last-Modified 好?

  1. 精度更高 :秒内多次修改,Last-Modified 识别不出
  2. 内容不变不算改 :文件改了但内容一样,ETag 不变(资源唯一标识)
  3. 时间不准问题:部分服务器无法精确获取修改时间

7.浏览器缓存整个流程是什么?(必考题)

**问:**从浏览器输入 URL 到页面展示,说说浏览器缓存的完整流程。

答:

  1. 浏览器先判断 强缓存 是否有效:
    • 通过 Cache-Control(优先)或 Expires 判断。
    • 有效:直接使用本地缓存,不发请求,状态码 200 from cache。
  2. 强缓存失效,则发送 HTTP 请求,进入 协商缓存
    • 请求头带上 If-Modified-SinceIf-None-Match
  3. 服务端对比缓存标识:
    • 资源未修改:返回 304 Not Modified,浏览器继续使用本地缓存。
    • 资源已修改:返回 200 + 新资源,并更新缓存。

8.强缓存和协商缓存有什么区别?

**问:**强缓存、协商缓存的区别是什么?

答:

  1. 是否发请求
    • 强缓存:不发请求,直接本地读取。
    • 协商缓存:会发请求,但可能只返回头信息,不返回 body。
  2. 判断依据
    • 强缓存:Cache-Control / Expires
    • 协商缓存:Last-Modified / ETag
  3. 状态码
    • 强缓存命中:200(from cache)。
    • 协商缓存命中:304 Not Modified。

9.为什么有了 Last-Modified 还需要 ETag?

**问:**已经有 Last-Modified 了,为什么还要设计 ETag?

答:

  1. 精度更高Last-Modified 只能精确到秒,秒内多次修改无法识别,ETag 是内容哈希,能精准识别。
  2. 内容不变就不变文件修改时间变了,但内容没变,ETag 不变,不会重复传输。
  3. 避免服务器时间不准有些服务器无法准确获取文件修改时间,会导致 Last-Modified 失效。
  4. 优先级 同时存在时,ETag 优先级高于 Last-Modified

10. 总结

浏览器请求资源时,先判断强缓存是否有效 ,有效直接用本地缓存;无效则发送请求,带上协商缓存标识,服务端验证通过返回 304 继续使用缓存,否则返回 200 和最新资源。


三、内存缓存(from memory cache)与硬盘缓存(from disk cache)

1.浏览器的缓存是缓存在哪里呢?

浏览器缓存分 4 层 ,按查找优先级从高到低

  1. Memory Cache(内存缓存)

    • 存放位置:浏览器进程内存
    • 特点:最快、关闭标签页就消失
    • 作用:当前页面快速复用资源(小图、脚本、样式)
  2. Disk Cache(硬盘缓存)

    • 存放位置:本地硬盘(浏览器用户数据目录)
    • 特点:容量大、持久化、重启浏览器还在
    • 绝大多数静态资源都存在这里
  3. Service Worker Cache

    • 存放位置:硬盘独立存储区
    • 特点:程序员可手动控制,支持离线缓存(PWA)
  4. Push Cache(HTTP/2 推送缓存)

    • 存放位置:内存
    • 特点:会话级缓存,生命周期极短

浏览器读取缓存的优先级始终是:先查内存缓存 → 内存无缓存 → 再查硬盘缓存

2.怎么判断强缓存生效?

1. 看 Network 面板三个标志

满足 全部 才叫强制缓存生效

  1. Status Code = 200 OK
  2. Size 列显示
    • from memory cache
    • from disk cache
  3. 没有发送请求
    • Request Headers 区域是灰色 / 不显示请求

2. 强制缓存 vs 协商缓存 区别

类型 是否发请求 状态码 表现
强制缓存 不发 200 OK (from cache) 直接读本地
协商缓存 发请求 304 Not Modified 问服务器是否过期

状态码的请求 200 from cache代表强缓存生效;状态码的请求304 Not Modified代表协商缓存生效。

3. 内存缓存(from memory cache)

内存缓存是浏览器将解析 / 编译后的资源(如已执行的 JS、渲染后的图片)存入当前浏览器进程的内存中,核心特点:

  • 极速读取:内存读写无需磁盘 I/O 操作,直接从进程内存中调取,响应时间可低至 0ms,是浏览器缓存中最快的层级;
  • 进程级时效性:内存缓存与浏览器进程强绑定 ------ 关闭标签页 / 浏览器窗口后,进程销毁,内存缓存会被立即清空;
  • 容量限制:内存空间有限,浏览器仅会将高频访问、体积较小的核心资源(如常用 JS、Base64 图片)存入内存缓存。

4. 硬盘缓存(from disk cache)

硬盘缓存是浏览器将资源文件直接写入本地硬盘(如浏览器的缓存文件夹),核心特点:

  • 读取效率稍低:读取时需执行硬盘 I/O 操作,再重新解析文件内容,速度慢于内存缓存,但远快于网络请求;
  • 持久化存储:缓存不随浏览器进程销毁而消失,关闭标签页 / 浏览器后,硬盘缓存仍会保留(直到缓存过期 / 被清理);
  • 容量宽松:硬盘存储空间远大于内存,浏览器会将体积较大、访问频率稍低的资源(如 CSS、字体文件、未即时使用的图片)存入硬盘缓存。

5. 浏览器资源缓存的默认规则以及浏览器渲染规则

浏览器会根据资源类型和使用场景,默认分配缓存存储位置:

  • 存入内存缓存:JS 文件(解析执行后)、图片(渲染后)、页面 DOM 结构等 "即时复用" 的资源;
  • 存入硬盘缓存:CSS 文件(需重新解析渲染)、字体文件、视频 / 音频片段、体积较大的静态资源等。
5.1浏览器渲染页面时为什么会出现先加载出来文字内容,然后才能加载出来样式?为什么有的时候会先加载出来图片占位,之后才会完整显示图片资源?

首先明确:

  1. HTML 文字不阻塞 → 最先渲染
  2. CSS 阻塞渲染 → 样式必须等 CSSOM 构建完
  3. 图片不阻塞布局,只阻塞绘制 → 先占位,后显示

跟缓存放内存还是硬盘没有半毛钱关系。

5.1.1Memory Cache 与 Disk Cache 跟「资源类型」无关,只跟 2 件事有关:
  1. 当前是否正在使用
    • 页面打开、正在渲染 → 放 Memory Cache
    • 页面关掉、闲置 → 移去 Disk Cache
  2. 系统内存压力
    • 内存够 → 尽量放内存
    • 内存不够 → 直接放硬盘

真正的规则:

  • 图片、JS、CSS、字体 既可以在内存,也可以在硬盘
  • 内存缓存:会话级、快、关页面就没
  • 硬盘缓存:持久化、慢、重启还在
5.1.2浏览器渲染流程:

浏览器渲染是严格流水线

  1. 解析 HTML → 生成 DOM
  2. 解析 CSS → 生成 CSSOM
  3. DOM + CSSOM → 合成 Render Tree
  4. **Layout(布局 / 重排)**计算:元素在哪、多大、占多少空间
  5. **Paint(绘制 / 重绘)**真正把像素画到屏幕
  6. Composite(合成)
5.1.3图片为什么会 "先占位"?

当浏览器解析到:

javascript 复制代码
<img src="a.jpg" width="200" height="200">

步骤 1:HTML 解析遇到 img

  • 浏览器只做一件事知道这个标签要占 200×200 的位置
  • 不会等图片下载
  • 不会等图片解码

直接进入 Layout

步骤 2:Layout 阶段

  • 布局引擎直接给图片留好空位
  • 页面其他内容(文字、div)正常排版→ 你看到的空白占位框,就是这一步出来的。

步骤 3:异步线程去加载 / 读取图片

浏览器开网络线程 / IO 线程去做:

  • 网络请求 或
  • 读 Disk Cache 或
  • 读 Memory Cache

这完全是异步的,不阻塞布局.

步骤 4:图片下载 / 读取完成 → 解码

JPG/PNG/WebP 都是压缩格式,必须解码成位图才能画。

解码也是异步、耗时的。

步骤 5:解码完毕 → 通知主线程 → Paint

图片到位了,浏览器才会把图片画到占位框里

5.2为什么给 img 设置 width/height 能优化布局偏移?

没有设置 width/height 时,布局阶段无法确定图片的占位尺寸 ,会先按「默认尺寸」占位,等图片加载完成后触发二次布局(重排),从而导致布局偏移。

5.2.1一句话底层结论:

设置 width/height 能让浏览器在「第一次布局」时就确定图片的准确占位,避免图片加载完成后触发「重排(Reflow)」,从而消除布局偏移。

分两种对比场景拆解:

场景 1:未设置 width/height(导致布局偏移)
javascript 复制代码
<!-- 无尺寸 -->
<img src="big.jpg">

渲染流程:

  1. 第一次布局:浏览器不知道图片尺寸,只能按「默认占位(比如 0×0 或浏览器默认的小尺寸)」计算布局 → 页面其他元素按这个 "临时尺寸" 排版。
  2. 图片加载完成 :浏览器拿到图片的真实尺寸(比如 800×600),发现「之前的占位尺寸不对」→ 触发二次布局(重排)
  3. 二次布局 :重新计算图片和周边元素的位置 → 页面元素 "突然移位" → 这就是布局偏移(CLS,Cumulative Layout Shift),也是谷歌核心网页指标(Core Web Vitals)的重要项。
场景 2:设置 width/height(消除布局偏移)
html 复制代码
<!-- 有尺寸 -->
<img src="big.jpg" width="800" height="600">
<!-- 或用 CSS 设置 -->
<img src="big.jpg" style="width:800px; height:600px;">

渲染流程:

  1. 第一次布局:浏览器直接用设置的 800×600 计算占位 → 周边元素按这个准确尺寸排版。
  2. 图片加载完成:尺寸和预设一致 → 无需二次布局,只触发「重绘(Paint)」(仅画图片,不改变布局)。
  3. 最终效果:图片占位从一开始就准确,加载完成后只有 "填充图片" 的视觉变化,无任何元素移位 → 消除布局偏移。
拓展:5.3 为什么现在推荐「宽高比」而非固定尺寸?

移动端适配场景下,固定宽高会变形,最优方案是「预设宽高比 + 自适应尺寸」:

css 复制代码
/* 核心:用 padding-top 模拟宽高比(比如 16:9) */
.img-container {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 9/16=56.25% */
}
.img-container img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

原理:padding-top 是相对父元素宽度计算的,能固定宽高比,布局阶段就确定占位,同时适配不同屏幕宽度。

拓展:5.4布局偏移的本质:重排(Reflow)vs 重绘(Repaint)
  • 重排(Reflow):布局重新计算 → 性能消耗大(涉及整个页面排版)。
  • 重绘(Repaint) :仅重新绘制像素 → 性能消耗小(只改图片区域)。设置 img 宽高的核心价值:把重排变成重绘,既消除偏移,又优化性能。
拓展:5.4面试高频追问:如果不知道图片真实宽高怎么办?

答:① 服务端返回图片宽高(接口字段),前端渲染时动态设置;② 用骨架屏 / 占位图(比如和图片宽高比一致的灰色块),替代空白占位;③ 用 CSS aspect-ratio(现代浏览器支持):

css 复制代码
img {
  width: 100%;
  aspect-ratio: 16/9; /* 固定宽高比,布局阶段确定占位 */
}

总结
  1. 设置 img 的 width/height 核心作用是让浏览器在第一次布局时确定准确占位,避免图片加载后触发重排导致布局偏移。
  2. 布局偏移的本质是「无预设尺寸 → 临时占位 → 二次重排」,设置尺寸能将重排转为轻量的重绘。
  3. 移动端最优解是「宽高比占位」(padding-top 或 aspect-ratio),兼顾适配和无偏移。

回顾上述:

浏览器缓存分为 Memory Cache、Disk Cache、Service Worker Cache 和 Push Cache,其中最常用的是内存缓存和硬盘缓存。

强制缓存由 Cache-ControlExpires 控制,生效时浏览器不发送任何请求,直接从本地读取 ,表现为 200 OK (from memory/disk cache);如果发送请求并返回 304,则是协商缓存,说明强制缓存已失效。

Memory Cache 和 Disk Cache 不是按资源类型分的 ,而是按是否在使用、内存压力决定。图片、CSS、JS 都可内存可硬盘。

图片先占位、后显示,是因为浏览器布局 (Layout) 不等待图片加载与解码,只根据宽高占好位置,图片异步加载解码完成后才执行绘制 (Paint)。

即使图片在内存缓存 ,也需要异步解码,所以仍然会先占位再显示。

文字先出、样式后出,是因为 CSS 阻塞渲染 ,图片占位是因为 布局与加载异步分离,两者原理完全不同。


深度拓展:内存缓存 vs 硬盘缓存的核心知识点

一、存储优先级与加载逻辑(完整流程)

浏览器加载资源时,缓存的查询顺序是多层级的,内存 / 硬盘缓存仅属于 "强制缓存" 的存储载体,完整流程:

javascript 复制代码
    A[浏览器请求资源] --> B{查内存缓存}
    B -->|有且未过期| C[from memory cache,0请求]
    B -->|无| D{查硬盘缓存}
    D -->|有且未过期| E[from disk cache,0请求]
    D -->|无/已过期| F{强制缓存失效}
    F --> G[发请求走协商缓存]
    G --> H[服务器返回304/200]
    H --> I[更新硬盘/内存缓存]

关键补充:

  • 内存缓存的优先级高于硬盘缓存,但仅对 "当前会话未销毁" 的资源有效(比如刷新页面时,内存缓存未清空,优先读取);
  • 关闭标签页重新打开时,内存缓存已清空,会优先读取硬盘缓存。

二、核心区别对比表

维度 内存缓存(from memory cache) 硬盘缓存(from disk cache)
存储位置 浏览器进程内存 本地硬盘(缓存文件夹)
读取速度 极快(0ms 级,无 I/O) 较快(ms 级,需硬盘 I/O)
持久性 会话级(关闭标签 / 浏览器即清空) 持久化(直到缓存过期 / 清理)
容量限制 小(受进程内存限制) 大(受硬盘空间限制)
存储资源类型 JS、渲染后图片、DOM 结构 CSS、字体、大体积静态资源
触发刷新(F5) 大概率保留(进程未销毁) 完全保留
强制刷新(Ctrl+F5) 清空 清空

三、影响缓存存储位置的关键因素

并非资源类型决定存储位置,浏览器会综合判断以下条件:

  1. 资源体积:体积<100KB 的小资源(如小图标、短 JS)更易存入内存;体积大的资源(如大图片、完整 CSS)优先存入硬盘;
  2. 访问频率:高频访问的资源(如页面核心 JS)会被浏览器 "升级" 到内存缓存;
  3. 浏览器策略:不同浏览器(Chrome/Firefox/Safari)的缓存策略略有差异(如 Firefox 对 CSS 的缓存更倾向于内存);
  4. 内存占用率:当浏览器内存占用过高时,会自动将部分内存缓存 "降级" 到硬盘缓存,释放内存。

四、如何区分内存 / 硬盘缓存?

通过 Chrome DevTools 可直观验证,步骤如下:

  1. 打开 DevTools(F12)→ 切换到 Network 面板 → 勾选「Disable cache」(先取消勾选);
  2. 访问目标网站,首次加载所有资源显示200 OK(服务器返回);
  3. 第一次刷新(F5)
    • JS / 图片显示from memory cache(内存缓存生效);
    • CSS 显示from disk cache(硬盘缓存生效);
  4. 关闭标签页,重新打开
    • 所有资源均显示from disk cache(内存缓存已清空);
  5. 强制刷新(Ctrl+F5)
    • 所有资源显示200 OK(跳过内存 / 硬盘缓存,发全新请求)。

五、性能优化视角:如何利用内存 / 硬盘缓存提升体验?

  1. 优先让核心资源进内存缓存
    • 页面首屏的核心 JS(如框架代码、初始化逻辑)尽量精简体积(<100KB),提升进入内存缓存的概率;
    • 图片资源优先使用 Base64 内嵌(小图标),解析后直接存入内存,减少硬盘 I/O。
  2. 合理设置硬盘缓存的有效期
    • CSS / 字体文件设置较长的max-age(如max-age=86400*7),利用硬盘缓存的持久性,减少重复请求;
    • 动态资源(如用户头像)设置no-cache+配置ETag,跳过强制缓存,但仍可利用硬盘缓存做协商缓存验证。
  3. 避免不必要的缓存占用
    • 非核心资源(如非首屏图片)通过lazyload延迟加载,避免过早占用内存缓存;
    • 敏感资源(如支付页面)设置no-store,禁止存入内存 / 硬盘缓存。

六、常见误区纠正

  1. 误区 1from memory cachefrom disk cache 更 "高级"→ 正确:两者是不同存储载体,无优劣之分 ------ 内存缓存快但不持久,硬盘缓存慢但持久,浏览器会自动适配;
  2. 误区 2:CSS 一定存在硬盘缓存→ 正确:并非绝对!如果 CSS 体积极小(如仅几行)且高频访问,浏览器也会将其存入内存缓存;
  3. 误区 3:刷新页面会清空所有缓存→ 正确:普通刷新(F5)仅清空部分内存缓存,硬盘缓存完全保留;只有强制刷新(Ctrl+F5)才会清空所有缓存。

总结

  1. 浏览器强制缓存的存储载体分为内存缓存(极速、临时)和硬盘缓存(稍慢、持久),读取顺序为「内存→硬盘」;
  2. 存储位置由资源体积、访问频率、浏览器策略共同决定,而非仅由资源类型(JS/CSS)决定;
  3. 优化缓存的核心是:让核心资源进内存缓存提升速度,让非核心资源进硬盘缓存减少请求,同时通过Cache-Control控制缓存有效期。

晚安啦煲仔们!!!

明天又是新的一天,加油加油!!!😀😀😀

相关推荐
李江林2 小时前
IPSec协议技术分析文档
网络协议·网络安全·vpn·ipsec
AI-小柒2 小时前
OpenClaw技术深度解析:从智能助手到自动化引擎的范式革命(附DataEyes实战)
大数据·运维·开发语言·人工智能·python·http·自动化
我命由我123452 小时前
React - React 初识、创建虚拟 DOM 的两种方式、jsx 语法规则、React 定义组件
前端·javascript·react.js·前端框架·html·html5·js
青青家的小灰灰2 小时前
深入理解 JavaScript 箭头函数:从语法糖到核心机制
前端·javascript·面试
cxxcode2 小时前
Web Vitals 数据采集机制分析
前端
sniper2 小时前
AI+Shopify 前端开发:实战一年后,聊聊 AI Agent 和前端的生死局
前端
南囝coding2 小时前
OpenClaw 到底能干什么?可以看看这 60 个真实用例
前端·后端
xienda2 小时前
WebSocket 核心定义与用处
网络·websocket·网络协议
Saniffer_SH2 小时前
【高清视频】SerialTek PCIe 5.0/6.0 协议分析仪API自动化编程演示
网络·人工智能·驱动开发·嵌入式硬件·测试工具·自动化·压力测试