Skip to content

前端面试题整理(三)

🕒 Published at:

什么是协商缓存和强缓存?两者有什么区别?

关于 HTTP 缓存

HTTP 缓存是基于 HTTP 协议的一种机制,通过存储和重用之前请求的资源副本(如 HTML、CSS、JavaScript、图片等),减少客户端与服务器之间的重复数据传输,从而提高网页加载速度、降低服务器负载、节省带宽。其核心目的是通过重用已有的响应数据,避免每次都从源服务器获取资源。

HTTP 缓存标准把缓存分为两类:

  • 私有缓存: 私有缓存是绑定到特定客户端的缓存,通常指浏览器缓存。它存储的响应仅对当前用户可见,不与其他用户共享。适用场景:存储用户的个性化内容(如登录后的页面、用户特定数据)。
  • 共享缓存:共享缓存位于客户端和服务器之间,存储的响应可被多个用户共享,用于减少服务器负载和网络流量。典型实现:代理服务器(如 Squid、Nginx 反向代理)、CDN 节点、ISP 缓存等。

关键性区别总结

特性私有缓存共享缓存
存储位置客户端中间层(代理服务器、CDN、反向代理服务器)
共享性私有共享
适用场景个性化、登录后的页面、用户特定数据公共资源、静态资源(图片、css)
控制指令Cache-Control: privateCache-Control: public
安全性仅对当前用户可见,安全可被多个用户共享,不安全

HTTP 缓存控制指令

HTTP 缓存主要通过请求头和响应头中的字段(如 Cache-ControlExpiresLast-ModifiedETag 等) 控制缓存策略,分为以下两种工作方式:

  1. 强缓存: 强缓存是指浏览器在第一次请求资源并得到响应后,将响应存储在客户端缓存中,后续再请求相同的资源时,浏览器会直接从缓存中获取响应,而不会向服务器发起请求。 由 Cache-Control(HTTP 1.1) 或 Expires(HTTP 1.0) 指令控制,如 Cache-Control: max-age=3600,表示缓存 1 小时。
  2. 协商缓存:协商缓存是指客户端在请求资源时,会携带一些请求头信息,如 Last-Modified/If-Modified-Since(使用资源最后修改时间判断)、ETag/If-None-Match(使用资源唯一标识符判断) 等, 服务器根据这些请求头信息判断客户端是否需要更新资源,如果客户端不需要更新,则返回 304 Not Modified,否则返回 200 OK。

缓存破坏(解决前端部署后的缓存问题)

在现代 Web 开发中,JavaScript 和 CSS 资源会随着开发的进展而频繁更新。但由于其静态资源文件名未改变,浏览器会优先从缓存中获取,从而导致页面加载时出现旧版本的资源。为了解决这个问题,我们可以通过一些方法来破坏缓存:

  1. 使用基于版本号或哈希值的文件名: 在构建时,使用基于版本号或哈希值的文件名,如 main.js?v=1.0.0,这样每次部署后文件名都会改变,从而破坏缓存。(一些成熟的构建工具如 Webpack、Vite 等,都提供了内置的版本号或哈希值生成功能)
  2. 对于主资源禁用缓存: 与子资源不同,主资源的 URL 不能像子资源 URL 一样被修饰,这时我们可以在 html 的 head 标签中添加以下内容,防止其被浏览器缓存。
html
<meta
	http-equiv="Cache-Control"
	content="no-cache, no-store, must-revalidate"
/>
<meta
	http-equiv="Pragma"
	content="no-cache"
/>
<meta
	http-equiv="Expires"
	content="0"
/>

注意: 现代浏览器可能忽略 Meta 标签,因此必须结合 HTTP 头使用。

Nginx
location / {
    add_header Cache-Control "no-store, no-cache, must-revalidate";
    add_header Pragma "no-cache";
    expires 0;
}

如果优化 SPA 应用的首屏渲染速度?

首屏加载时间: 指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容

最后更新于: