浏览器

三种浏览器缓存

localStorage和sessionStorage

浏览器存储localStorage和sessionStorage,用于在客户端持久化存储数据

特性 localStorage sessionStorage
存储时间 永久存储,除非手动删除 会话期间存储,关闭页面/浏览器后清除
存储大小 通常为 5MB 左右(不同浏览器可能不同) 同上
作用域 同一域名下所有页面共享 同一页面/标签页的会话内有效

localStorage只能存储字符串,存取对象需要JSON方法进行转换,否则是[object Objet]
loacl/sssionStorage不同域的数据不共享
sessionStorage同一浏览器窗口的不同标签页可共享数据,新开的窗口不共享

cookie像超市会员卡 ,容量小,每次都会携带。
在服务器第一次返回响应时候,会在响应头添加cookie信息,浏览器自动保存到本地,下次访问同一域名时会在请求头中自动带上cookie,服务器根据cookie识别用户身份

关于token–我的疑惑+详解

因为我只是用过localStorage存储+axios拦截器从里面获取token,没有使用过cookie,所以问了大模型老师:
1.携带token的方法有哪些,如何给后端token,有什么区别?
2.我不理解既然cookie会自动保存token,那么为什么还要通过localStorage保存token呢,这两个token有什么区别吗
详解如下:

Cookie与LocalStorage存储Token的核心区别表格

区别 Cookie存储 LocalStorage存储Token
携带方式 浏览器自动随请求发送,无需前端额外代码。 需前端手动从本地取出并添加到请求头。
安全性 - 可设置HttpOnly防止XSS,但存在CSRF风险(需配合SameSite)。
- 跨域时受同源策略限制。
- 不自动发送,需前端严格控制token使用,避免XSS攻击(如避免在前端JS中直接操作token)。
存储时效 可设置过期时间(如max-age),或随浏览器关闭过期(会话cookie)。 永久存储,需前端手动删除(如用户登出时)。
跨域共享 同域名下共享,跨域需后端配置Access-Control-Allow-Credentials 同域名下共享,不同域名不互通(受同源策略限制)。
容量限制 约4KB,不适合存储大token。 约5-10MB,适合存储JWT等较长字符串。

Token 的携带方法及给后端的方式

Token本质是客户端向服务器证明身份的凭证,常见携带方式如下:

  1. 请求头(Header)携带:最主流的方式
    实现:在HTTP请求头中添加Authorization 字段,格式通常为 Bearer <token>(如 JWT 场景)

    JWT(JSON Web Token)是一种轻量级的开放标准(RFC 7519),常用于身份验证和信息安全传输

    1
    2
    3
    4
    5
    6
    7
    axios.interceptors.request.use(config => {
    const token = localStorage.getItem('token');
    if (token) {
    config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
    });

    优势:
    跨域请求时可通过设置 withCredentials: true 携带(需后端配合)。
    与前端框架(如 Vue/React)集成方便,可统一拦截处理

  2. Cookie 存储并自动携带
    实现:服务器返回token时通过Set-Cookie响应头写入浏览器cookie,后续请求自动携带。
    注意事项:
    需设置 HttpOnly: true(防止 XSS 攻击)和 SameSite: Strict/Lax(防止 CSRF 攻击)。
    跨域场景下需后端配置 Access-Control-Allow-Credentials: true。
    缺点:
    cookie大小限制(通常 4KB),不适合存储大token。
    域名共享问题(不同子域名需配置SameSite为None并配合HTTPS)。

  3. LocalStorage/SessionStorage存储,手动携带
    实现:前端将 token 存入本地存储,发送请求时从本地取出并添加到请求头

    1
    2
    3
    4
    5
    6
    7
    8
    // 存储
    localStorage.setItem('token', response.data.token);
    // 携带
    fetch('api/resource', {
    headers: {
    'Authorization': `Bearer ${localStorage.getItem('token')}`
    }
    });

    优势:
    存储容量大(一般 5MB+),适合存储 JWT 等较长的 token。
    不依赖域名,可在同一浏览器的不同标签页共享(localStorage)

其实这两种方式各有优缺点。比如 cookie 的好处是自动携带,不用前端写额外代码,但安全性较弱,容易被 XSS 攻击(所以一般会加 HttpOnly)。而 localStorage 需要手动管理,但容量大,适合存 JWT 这样的长 token。实际项目中可能会结合用,比如用 localStorage 存 token,用 cookie 存一些非敏感信息,同时通过前端拦截器统一在请求头里携带 token,这样既能保证安全,又方便管理。

Token 是怎么生成的?存在哪里

Token是服务器生成的一串加密字符串,用于标识用户身份,类似 “电子钥匙”

存储位置:
客户端:存储在 cookie、localStorage 等位置。
服务器:不强制存储(如 JWT 无需存储,服务器通过密钥验证签名),或存储在数据库(如 Session Token 需记录会话状态)

Token 一般是服务器生成的。比如JWT的话,服务器会用密钥把用户信息(像 ID、权限)加密成一个字符串,直接返回给前端,服务器自己不用存这个 token,下次用户带 token 来的时候,服务器用同样的密钥验证签名对不对就行。
如果是 Session Token,服务器会生成一个随机字符串,存在数据库里,然后把 token 给前端,后续前端带 token 来,服务器就查数据库确认是不是有效。

根据场景选择存储方式

优先用请求头 + localStorage:适合大多数前后端分离项目,前端手动管理 token,配合拦截器统一携带,安全性和灵活性较高。
配合 cookie 使用:需开启 HttpOnly 和 SameSite,适合对兼容性要求高或需要跨域携带 token 的场景(如 SSR 项目)。
核心原则:token 的存储和携带方式需平衡安全性、开发效率和项目需求,避免单一方案的缺陷(如 cookie 的 CSRF 风险、localStorage 的 XSS 风险)

浏览器缓存策略

浏览器缓存的工作流程

首次请求:服务器返回资源及缓存策略(强缓存 / 协商缓存参数)
再次请求:
先检查强缓存是否有效,若有效则直接使用缓存(状态码200 (from cache))
若强缓存失效,发送协商缓存请求头(If-Modified-Since/If-None-Match)到服务器。
服务器验证后,若资源未更新,返回304,浏览器使用缓存;若更新,协商缓存失效,返回新资源

强缓存和协商缓存

  1. 强缓存(本地缓存)
    浏览器直接读取本地缓存,不与服务器交互,状态码为200

    关键响应头:
    Expires:资源过期时间(绝对时间戳),若未过期则直接读取缓存
    Cache-Control(优先级高于Expires):
    max-age=秒数:资源在多少秒内有效,如max-age=3600表示 小时内缓存有效。
    public:资源可被客户端和代理服务器缓存
    private:资源仅可被客户端缓存
    no-cache:并非不缓存,而是需要经过协商缓存验证
    no-store:禁止任何形式的缓存,每次请求都从服务器获取

  2. 协商缓存(服务器验证)
    浏览器向服务器发送验证请求,验证资源是否更新,状态码为304,若未更新则使用缓存

    关键响应头:
    第一次请求时服务器返回:
    Last-Modified:资源最后修改时间。
    ETag:资源的唯一标识(如文件哈希值)。
    后续请求时浏览器发送:
    If-Modified-Since:携带Last-Modified的值,询问服务器资源是否修改。
    If-None-Match:携带ETag的值,询问服务器资源是否变更

服务器响应:
若资源未更新,返回304 Not Modified,浏览器使用本地缓存
若资源更新,返回200 OK及新资源内容

缓存策略的选择场景

强缓存适合:
静态资源(如图片、CSS、JS),版本稳定,更新频率低。
可设置max-age为较长时间(如 1 周),并通过 URL 版本号控制更新。
协商缓存适合:
动态数据(如用户信息页面),或更新频率较高但需缓存的资源。
避免强缓存导致数据过期,通过协商缓存确保数据时效性。

Cache-Control有哪些常用值

max-age=N:资源在 N 秒内有效,过期后需重新验证。
public:资源可被客户端和代理服务器缓存(如 CDN)。
private:资源仅客户端可缓存,代理服务器不可缓存(如用户登录信息)。
no-cache:强制浏览器发送协商请求到服务器,验证资源是否更新。
no-store:禁止任何缓存,每次请求都从服务器获取(如敏感数据)。

ETag相比Last-Modified有什么优势?

Last-Modified:资源最后修改时间。
ETag:资源的唯一标识(如文件哈希值

  1. Last-Modified有局限性:
    只能精确到秒级,若资源在 1 秒内多次修改,无法识别
    服务器时间同步问题可能导致判断不准
  2. ETag的优势:
    基于文件内容生成哈希值,更精准判断资源是否变更
    可解决Last-Modified的时间精度问题和服务器时间不一致问题

如何强制更新浏览器缓存?

  1. 修改资源 URL(最常用):
    如将index.js改为index.v2.js,浏览器会视为新资源,跳过缓存。
  2. 利用Cache-Control: no-cache:
    每次请求强制走协商缓存,由服务器验证是否更新。
  3. 修改响应头ETag或Last-Modified:
    服务器主动变更标识,使协商缓存失效。

如何强制更新浏览器缓存?

  1. 修改资源 URL(最常用):
    如将index.js改为index.v2.js,浏览器会视为新资源,跳过缓存。
  2. 利用Cache-Control: no-cache:
    每次请求强制走协商缓存,由服务器验证是否更新。
  3. 修改响应头ETag或Last-Modified:
    服务器主动变更标识,使协商缓存失效。

缓存策略进阶问题:缓存与性能优化的结合

如何利用缓存提升首屏加载速度?

对静态资源启用强缓存,减少重复请求。
对 HTML 文件使用协商缓存(因 HTML 更新频率高,避免强缓存导致页面不更新)。
利用Service Worker实现 PWA 缓存,进一步提升离线加载能力。

缓存可能带来的问题及解决方案?

问题:资源更新后,旧缓存未失效,导致用户看到旧内容。
解决方案:
对静态资源使用Contenthash命名(如index.abc123.js),内容变更时 URL 自动更新。
对 HTML 文件设置Cache-Control: no-cache,确保每次请求验证最新内容。

场景:用户反馈页面更新后,部分图片 / JS 未刷新,如何排查?

检查服务器响应头是否正确设置了缓存策略(如Cache-Control的max-age是否过长)。
查看浏览器DevTools的Network面板,确认资源是否走了强缓存(200 from cache)或协商缓存(304)。
若资源应更新但未更新,可手动清除浏览器缓存,或强制刷新页面(Ctrl+Shift+R,跳过强缓存)。

  • 长期解决方案:对静态资源添加版本号后缀(如img?v=2.0),强制浏览器加载新资源。

网络

跨域问题如何解决

是否跨域首先要看两个资源是否同源,如果两个资源的协议协议、域名、端口号有不一样的,就会触发跨域限制。

  • 跨域限制目的:保护数据安全,浏览器要限制跨域为了防止恶意网站读取或修改用户数据。
  • 哪些操作会触发跨域限制:
    前端AJAX请求跨域接口浏览器会报错
    cookie、session、loaclStorage共享时,跨域无法自动携带
    DOM操作:iframe产生的页面如果跨域,只能显示页面,无法进行js操作
    本地存储,跨域无法读取localStorage
  • 例外情况:浏览器允许静态资源跨域加载

跨域解决方案

  • CORS(最常用,生产环境也能用):是一种后端配置规则,允许特定源的请求访问数据。适用于前后端分离的项目,安全性高
  • Nginx的代理:是生产环境正式解决方案,需要服务器配置
  • 反向代理(开发用):在前后端之间添加“中间层”,把跨域请求变成同源请求。只在本地有效,是开发环境的临时解决方案
  • JSONP(旧项目用):利用<script>标签可以跨域加载JS脚本的特性间接获取数据。仅适用GET请求,安全性低

Nginx

是一款轻量级的高性能 Web 服务器、反向代理服务器以及电子邮件(IMAP/POP3)代理服务器

作用

  1. 反向代理与负载均衡
    Nginx可作为反向代理服务器
    可以将客户端请求均匀分配到多个后端服务器上,使各服务器负载均衡,避免单点服务器压力过大,提高系统整体处理能力和可靠性
  2. 静态资源服务器
    对静态资源(如 HTML、CSS、JavaScript、图片等)的处理效率极高
    Nginx 可配置缓存,将经常访问的静态资源缓存到内存或磁盘中,当有相同请求再次到来时,直接从缓存中读取并响应,减少后端服务器的负载和响应时间,进一步提高网站性能和用户体验
  3. HTTP 请求处理与优化
    Nginx 支持 HTTP/2 协议
    能对 HTTP 请求进行过滤和处理,如检查请求头、URL 等信息,根据规则拒绝非法请求或进行相应的处理,防止恶意攻击,如 SQL 注入、XSS 攻击等,增强系统安全性

HTTP的多个版本

HTTP 协议有多个版本,常见的有 HTTP/1.0、HTTP/1.1 和 HTTP/2

兼容性:
HTTP/1.0 和 HTTP/1.1 兼容性较好,被大多数浏览器和服务器支持
HTTP/2 虽然越来越普及,但仍有一些旧设备或环境可能对其支持不完全,不过随着技术发展,兼容性问题在逐渐改善

HTTP/1.0

每个请求都需要建立一个新的 TCP 连接,请求完成后连接即被关闭,意味着每次请求和响应都有较高的延迟,因为建立和拆除连接需要消耗时间和资源
适用于一些简单的、对性能要求不高的小型网站或应用,不过现在已较少单独使用

HTTP/1.1

1.0 基础上进行了改进。支持持久连接,即多个请求可以复用同一个 TCP 连接,减少了连接建立和关闭的开销,提高了性能
还支持请求管道化,允许客户端在一个连接上连续发送多个请求,而无需等待前一个请求的响应,但服务器仍需按顺序响应请求
广泛应用于各种类型的网站和应用,能较好地满足大多数常规网络应用的需求

HTTP/2

采用了二进制分帧层,将数据分割成更小的帧,并以二进制格式传输,提高了传输效率
多路复用,多个请求和响应可以在同一个连接上同时进行,且相互不干扰
它支持服务器推送,服务器可以主动向客户端推送资源,提前将客户端可能需要的资源发送给客户端,减少客户端的请求次数
特别适合高并发、对性能要求极高的场景,如大型电商网站、在线视频平台等,能显著提高页面加载速度和用户体验

HTTP 状态码分类

HTTP 状态码是服务器对请求的响应结果标识,用 3 位数字表示,首位数字定义类别

  • 1xx(信息响应):请求已被接收,需要继续处理(临时状态)。
    • 例如:101 Switching Protocols(协议切换,如 WebSocket 握手)。
  • 2xx(成功):请求已成功处理。
    • 例如:200 OK(标准成功响应)、201 Created(资源创建成功)。
  • 3xx(重定向):需要客户端进一步操作以完成请求。
    • 例如:301 Moved Permanently(永久重定向)、302 Found(临时重定向)、304协商缓存
  • 4xx(客户端错误):请求包含错误或无法完成。
    • 例如:400 Bad Request(请求语法错误)、404 Not Found(资源不存在)。
  • 5xx(服务器错误):服务器处理请求时发生错误。
    • 例如:500 Internal Server Error(服务器内部错误)、503 Service Unavailable(服务不可用)。

高频状态码详解

  • 200 OK
    • 场景:GET 请求成功获取资源,或 POST 请求提交数据成功(后端可能返回 200 或 201)。
    • 前端关注:正确处理响应数据(如 JSON 解析、渲染页面)。
  • 301 vs 302
    • 301:永久重定向(浏览器缓存跳转,后续直接访问新 URL)。

    • 302:临时重定向(每次需向原 URL 发起请求)。

  • 304 Not Modified
    • 场景:协商缓存生效,资源未修改,直接使用本地缓存。
    • 前端关联:通过 Cache-ControlETag 控制缓存策略。
  • 401 Unauthorized
    • 含义:请求未携带有效身份凭证(如 Token 过期)。
    • 前端处理:跳转登录页或自动刷新 Token(通过 Axios 拦截器)。
  • 403 Forbidden
    • 含义:服务器理解请求,但拒绝执行(如无权限访问接口)。
    • 与 401 区别:401 是未认证,403 是已认证但无权访问。
  • 404 Not Found
    • 场景:请求资源不存在(如 URL 错误、未部署静态文件)。
    • 前端优化:自定义 404 页面,提升用户体验。
  • 500 Internal Server Error
    • 含义:服务器处理请求时发生未知错误(如代码异常)。
    • 前端处理:提示用户“服务异常,请稍后重试”,并上报日志。

JWT

JWT(JSON Web Token)是一种用于网络间安全传输声明的标准,它通过数字签名确保传输信息的完整性和真实性,常用于身份验证和授权场景。

如何防止 CSRF 攻击

CSRF(跨站请求伪造):攻击者诱导用户向已认证的网站发送恶意请求
防御 CSRF 攻击的核心是验证请求来源。常用方法包括添加 Anti-CSRF Token、设置 SameSite Cookie,以及验证 Referer 头。例如,Spring Security 默认使用 CSRF Token 防御攻击

get post put PATCH

GET:请求数据,不会修改服务器数据
POST:提交数据,修改服务器数据
PUT:更新数据,完整替换现有资源
PATCH: 部分更新现有资源

POST 用于创建新资源(URI 由服务器分配)
PUT 用于更新已有资源(URI 由客户端指定)

get

幂等:多次相同请求结果相同(如刷新页面不会重复创建数据)。
参数暴露:数据通过 URL 参数(?key=value)传递,有长度限制(约 2KB)。
可缓存:浏览器默认缓存 GET 请求(如图片、CSS 文件)

POST

非幂等:重复提交可能创建多条相同数据(如多次提交表单)。
参数隐蔽:数据放在请求体(Body)中,适合传输大量或敏感数据。
不可缓存:浏览器默认不缓存 POST 请求

PUT 请求

幂等:多次相同请求结果相同(如多次修改同一数据)
完整替换:需提供资源的全部字段,缺失字段会被删除
避免大量小 PUT 请求,可合并为一次 POST 批量更新

工程化能力

前端工程化包含:1)构建(Webpack/Vite),2)编译(Babel/PostCSS),3)优化(代码分割、Tree Shaking),4)性能监控(Lighthouse)。通过这些环节,实现代码模块化、自动化构建和性能调优。

Webpack/Vite 构建工具

模块打包:将 JS、CSS、图片等资源打包成少量文件,减少HTTP请求
资源处理:通过Loader(Webpack)或原生ESM(Vite)处理非JS资源(如SASS转CSS、图片压缩)
Vite利用浏览器原生ESM,开发环境无需打包,启动极快。生产环境用Rollup打包,适合现代框架
示例配置项:

  • entry:起点文件
  • output.path:输出目录
  • module.rules:配置Loader
  • plugins:扩展功能”

Babel、PostCSS 等编译工具

两者都是构建流程中的‘翻译官’
Babel:将新版JS(ES6+)转译为旧版(ES5)以兼容老浏览器。支持JSX等语法扩展
PostCSS:用JS插件转换CSS(如自动加前缀、用CSS变量、嵌套写法等)
PostCSS 本身不处理样式,通过插件(如autoprefixer)实现功能

代码分割、Tree Shaking 等优化手段

代码分割(Code Splitting):将代码拆分成多个文件,按需加载(如路由懒加载)
Tree Shaking:删除未使用的代码(依赖ESM静态结构)

前端性能优化意识

加载阶段:减小资源体积(压缩、懒加载)、加快首屏(SSR、预渲染)
运行时性能:减少重绘重排、防抖节流、Web Worker长任务拆分
缓存策略:CDN加速静态资源、Service Worker实现离线可用

Lighthouse 评测工具

  1. 核心指标
    FCP(First Contentful Paint):首次内容绘制时间。
    LCP(Largest Contentful Paint):最大内容绘制时间。
    TTI(Time to Interactive):页面可交互时间。
    CLS(Cumulative Layout Shift):累积布局偏移(避免内容跳动)
  2. 优化建议
    Performance:减少阻塞渲染的资源。
    Accessibility:添加 ARIA 标签、合理的颜色对比度。
    Best Practices:使用 HTTPS、避免弃用 API。
    SEO:确保标题、元描述有效。

web标准,可用性,可访问性:

web标准

web标准是网页开发的规范合集,想要网页在不同设备、浏览器中具有一致的表现和功能,就要遵守web标准进行开发
常见的标准规范有html5的语义化标签、css3的flex布局、grid布局、javascript的标准规范。
遵循web标准能提高网页的兼容性、可维护性、优先被搜索引擎发现、提高无障碍访问能力。

可用性(用户体验)

用户要使用网页,作为开发人员,肯定希望网页能让用户高效、清晰地完成任务,侧重用户体验,这就是可用性。
核心内容有:
课件原则:当前状态和操作的可见:比如点击按钮后有明确反馈;
匹配原则:符合大部分用户的认知和习惯,比如购物车通常放在右上角或者右下方,就不能放在左上角。
容错原则:允许用户撤销,提供清晰的错误提示。
效率原则:提供快捷方式减少用户操作步骤,比如搜索框支持回车键查询,比如设计面包屑导航。

可访问性(包容性):

像无障碍坡道,让残障人士也能平等使用功能的能力。
图片添加alt文本、使用语义化标签、ARIA属性为非语义化元素添加额外语义信息;颜色对比度:文本与背景对比度至少达到4.5:1;按钮可以通过tab键聚焦。

其他问题:

为什么移动优先设计符合可用性原则?

移动优先设计从手机端开始规划,逐步适配大屏幕,这符合可用性的“效率原则”:

  • 手机屏幕小,必须精简内容,反而促使设计师提炼核心功能(如电商APP优先展示“搜索”和“购物车”);
  • 移动设备网络环境更复杂,优化加载性能(如图片懒加载、资源压缩)后,桌面端体验也会提升;
  • 触摸操作需要更大的点击区域(如按钮至少44px×44px),这让鼠标操作也更轻松。

公司项目中如何落实Web标准?

1. 技术选型:使用HTML5语义化标签、CSS3新特性,避免过时语法(如表格布局);
2. 代码规范:

  • 结构、样式、脚本分离(HTML中不写内联样式和JS);
  • 命名语义化(如 nav-menu 比 div1 更易理解);
    3. 构建工具:
  • 使用ESLint校验JS代码,Stylelint规范CSS格式;
  • 自动转换语法(如Babel将ES6转为ES5,PostCSS添加浏览器前缀);
    4. 测试流程:
  • 用W3C validator校验HTML是否符合标准;
  • 在不同浏览器(Chrome、Firefox、Edge)中测试显示一致性。

性能优化

如何优化 CSS 性能?

减少选择器复杂度:避免深层嵌套(如 body div ul li a)
避免行内样式:影响缓存和维护性
减少重排(reflow)和重绘(repaint):
批量修改样式(先修改再应用)
使用 transform 和 opacity 进行动画(触发合成层)
压缩和分割 CSS:减小文件体积,利用浏览器并行加载

如何优化首次加载渲染速度?

压缩资源(CSS/JS 最小化)
懒加载非首屏图片
使用CDN加速
内联关键CSS(Critical CSS)

相关知识

less和sass

都css的预处理器,允许用更强大的语法编写css,然后编译成浏览器 能够识别的普通css
允许变量复用、函数计算、可以嵌套(比如多层选择器时)、代码组织。

  • less: @,客户端编译,轻量级,不可以嵌套属性,不可以@extend,能Mixin,社区生态小,已停止更新
  • sass:&,服务器编译,功能强大,可以嵌套属性,可以@extend集成,有很多第三方库,持续更新中

<script> 标签放在页面底部的原因?

解析阻塞:浏览器遇到 <script> 会暂停 HTML 解析,先下载执行 JS
解决方案:
使用 async(下载异步,执行仍阻塞)
使用 defer(延迟到 HTML 解析完执行)

CSS 为什么要放在 <head> 中?

渲染阻塞:浏览器需先构建 CSSOM 才能渲染页面
避免 FOUC(Flash of Unstyled Content):防止先显示无样式内容再突然变化

DOMContentLoaded和load事件区别?

DOMContentLoaded:HTML 解析完成 + DOM 树构建完毕(此时图片可能未加载)
load:所有资源(图片、样式表)加载完成

为什么修改大量 DOM 会导致页面卡顿?

原因:多次重排:每次 DOM 修改都触发重排(如循环中逐条改样式)
优化方案:
使用 document.createDocumentFragment() 批量操作
先 display: none 修改完再显示
使用虚拟 DOM(如 Vue/React)

重排和重绘

重排:当元素位置/尺寸变化(如改宽度、窗口缩放),浏览器重新计算布局
重绘:当元素外观变化但不影响布局(如改颜色),浏览器重新绘制
性能影响:重排 > 重绘 > 合成
优化方法:
批量 DOM 操作(使用 documentFragment)
使用 position: absolute 脱离文档流

移动端适配方案

移动端适配的核心是让网页在不同设备上显示正常、布局合理、交互流畅

常用方法

有响应式布局,通过媒体查询(@media)设置不同屏幕尺寸的样式,比如小屏时让内容撑满,大屏时居中显示。然后会用相对单位配合工具动态调整根字体大小,这样页面元素能根据设备宽度自动缩放。
对于复杂的布局,会用Flexbox或Grid来保证元素对齐和分布。图片适配会用srcset根据分辨率加载合适的资源

基础适配:rem + amfe-flexible + postcss-pxtorem
布局优化:Flexbox/Grid + 媒体查询。
资源适配:srcset + picture。
动态调整:JavaScript 动态计算字体大小或布局参数
amfe-flexible + postcss-pxtorem通过包管理器安装+配置即可

响应式布局

通过媒体查询(@media)设置不同屏幕尺寸的样式,比如小屏时让内容撑满,大屏时居中显示。会用相对单位比如%,em,rem配合工具动态调整根字体大小,这样页面元素能根据设备宽度自动缩放

  • 好处:
  • 代码复用率高,一套代码适配多种设备
  • 适合内容动态变化的场景(如新闻、电商页面)
  • 缺点:
  • 复杂布局需要编写大量媒体查询规则
  • 对图片资源适配需额外处理(如srcset)
    1
    2
    3
    4
    5
    @media screen and (max-width: 600px) {
    .container {
    width: 100%;
    }
    }

rem单位适配:

  • 原理:通过 JavaScript 动态计算根元素()的 font-size,再结合 rem 单位实现缩放。
  • 工具:常用 amfe-flexible + postcss-pxtorem 自动将 px 转换为 rem
  • 需要手动配置或依赖工具链,对旧版浏览器兼容性要求较高

vw/vh单位适配:

  • 原理:vw(视口宽度的 1%)、vh(视口高度的 1%)直接基于视口大小计算。
  • 优点:
    无需 JavaScript,纯 CSS 实现。
    适合现代项目,布局简洁。
  • 缺点:
  • 对字体大小的适配需额外处理(如 clamp() 函数)。
  • 部分设备可能存在兼容性问题(如 iOS 13 以下)
    1
    2
    3
    .container {
    width: 50vw; /* 占屏幕宽度的 50% */
    }

flex和grid布局

复杂的布局,会用Flexbox或Grid来保证元素对齐和分布。最后,图片适配会用 srcset 根据分辨率加载合适的资源
Flexbox快速实现一维布局(如导航栏、卡片列表),兼容性较好
Grid更复杂的布局更灵活,兼容性较差

自适应设计

  • 原理:通过服务器或前端检测设备类型,加载不同的布局文件,如 PC、移动端分开开发
    优点:
    可针对特定设备优化性能(如移动端加载更轻量的资源)。
    缺点:
    维护成本高(需维护多套代码)。
    不适合内容动态变化的场景

如何选择适配方案

选择适配方案需要看项目需求。如果是传统项目,我会优先用 媒体查询 + rem,因为它的兼容性好,适配精度高。
如果是现代项目,可能会用 vw/vh 或 CSS Grid,因为它们更简洁。
对于图片资源,会用srcset和picture 标签。
如果项目需要极致性能,可能会考虑自适应设计,但维护成本会更高。总之,我会根据团队技术栈、项目复杂度和目标用户群体选择最适合的方案

rem 和 vw 的区别

  • rem 是基于根元素()的字体大小计算的,通过 JavaScript 动态调整根字体大小,适合传统的渐进式适配。- - vw 是直接基于视口宽度的百分比单位,比如 1vw 等于屏幕宽度的 1%,完全不需要 JavaScript。
  • rem 更适合需要精确控制字体大小的场景,
  • vw 更适合现代布局,尤其是动态内容较多的页面。
  • 但是vw 在处理字体时可能会导致过小或过大的问题,需要结合clamp()函数优化