前端面试通关包(2026版,完整版)

前端面试通关包(2026版,完整版)

适用人群:1~5 年及以上前端工程师

使用方式:先按模块通读,再挑你最薄弱的题目反复复述。

目标:不是"背答案",而是能把问题讲清楚、讲完整、讲出工程思维。


一、JavaScript 核心高频题

1. 什么是事件循环?宏任务和微任务有什么区别?

面试回答

JavaScript 是单线程执行的,但浏览器和 Node.js 运行时会把一些异步任务交给宿主环境处理,例如定时器、网络请求、DOM 事件等。

当主线程执行完当前调用栈里的同步代码后,会去任务队列里取下一批任务执行,这个不断"执行同步代码 -> 清空微任务 -> 取下一个任务"的过程,就是事件循环。

通常可以这样理解:

  • 宏任务(Task):script、setTimeout、setInterval、I/O、UI 渲染、postMessage 等
  • 微任务(Microtask):Promise.then/catch/finally、MutationObserver、queueMicrotask 等

执行顺序一般是:

  1. 执行一整个宏任务
  2. 执行该宏任务产生的所有微任务,直到微任务队列清空
  3. 进行必要的页面渲染
  4. 再进入下一个宏任务

所以微任务优先级通常高于宏任务。最常见的面试题就是判断一段代码的输出顺序,本质就是看:

  • 同步代码先执行
  • 当前宏任务结束后,微任务全部清空
  • 然后再执行下一个宏任务

一句话记忆

同步代码先走,当前轮次的微任务全部清空,最后才轮到下一个宏任务。

常见追问

  • 为什么 Promise 比 setTimeout 先执行?
  • 浏览器渲染是在微任务前还是后?
  • Node.js 事件循环和浏览器事件循环有何差异?

易错点

很多人把"异步"直接等同于"setTimeout"。实际上 Promise 也是异步,但它进入的是微任务队列,不是宏任务队列。


2. Promise 的本质是什么?为什么能解决回调地狱?

面试回答

Promise 本质上是一个表示异步操作最终结果的对象。它把"未来会得到的值"抽象成统一的数据结构,并且把异步流程变成可以链式书写的形式。

Promise 有三个状态:

  • pending:进行中
  • fulfilled:已成功
  • rejected:已失败

状态一旦从 pending 变为成功或失败,就不可再逆,这叫状态不可逆

Promise 能缓解回调地狱,主要有三个原因:

  1. 链式调用

    • 以前多层异步要一层层嵌套回调
    • Promise 可以 .then().then().catch() 平铺下来
  2. 统一的错误传递

    • 回调风格里每层都要手动处理错误
    • Promise 链中抛出的错误会一直向后冒泡到最近的 catch
  3. 更适合组合多个异步任务

    • Promise.all
    • Promise.race
    • Promise.allSettled
    • Promise.any

例如:

js 复制代码
requestA()
  .then(resA => requestB(resA))
  .then(resB => requestC(resB))
  .catch(err => handleError(err))

这样比层层嵌套的回调更清晰,也更容易维护。

常见追问

  • Promise.allPromise.allSettled 的区别?
  • then 为什么可以链式调用?
  • 手写 Promise 时为什么要用队列保存回调?

易错点

Promise 并不是"让异步变同步",它只是让异步代码更容易组织和管理。


3. async/await 和 Promise 是什么关系?

面试回答

async/await 本质上是 Promise 的语法糖
async 函数执行后一定返回一个 Promise;await 会等待一个 Promise 完成,然后拿到它的结果。

例如:

js 复制代码
async function getData() {
  const res = await fetch('/api/data');
  return res.json();
}

等价思路大致可以理解为:

js 复制代码
function getData() {
  return fetch('/api/data').then(res => res.json());
}

async/await 的优势是:

  1. 代码更接近同步写法

    • 可读性更强
    • 更适合复杂业务流程
  2. 错误处理更自然

    • 可以直接用 try...catch
  3. 便于写条件分支和循环

    • Promise 链在复杂逻辑里会越来越绕
    • async/await 在控制流上更直观

但是它不是性能优化工具。多个独立异步任务如果写成连续 await,反而会串行执行,导致变慢。

这时应该用:

js 复制代码
const [a, b] = await Promise.all([taskA(), taskB()]);

常见追问

  • await 后面如果不是 Promise 会怎样?
  • 为什么说 async 函数一定返回 Promise?
  • 如何把串行 await 改成并行?

易错点

很多人一上来就把多个 await 串起来,这在互不依赖的请求场景里是低效写法。


4. 什么是闭包?闭包有什么实际作用和风险?

面试回答

闭包指的是:函数可以访问并记住其词法作用域中的变量,即使该函数在作用域外执行。

经典例子:

js 复制代码
function createCounter() {
  let count = 0;
  return function () {
    count++;
    return count;
  };
}

const counter = createCounter();
counter(); // 1
counter(); // 2

这里内部函数引用了外部函数的 count,外部函数执行结束后,这个变量没有被销毁,因为还被内部函数引用着,这就是闭包。

实际作用

  1. 数据私有化
    • 可以把变量封装起来,外部不能直接修改
  2. 函数工厂
    • 根据不同参数生成不同功能函数
  3. 缓存
    • 记住计算结果,避免重复计算
  4. 框架底层
    • React Hooks、函数柯里化、模块封装等都大量使用闭包思想

风险

闭包本身不是坏事,但如果引用了大量不再需要的对象,又长期不释放,就可能造成内存无法及时回收

比如:

  • 定时器里引用大对象
  • 事件监听函数里持有 DOM 或大数组
  • 某些缓存没有淘汰机制

常见追问

  • 闭包为什么不会被垃圾回收?
  • 闭包一定会导致内存泄漏吗?
  • React Hooks 和闭包有什么关系?

易错点

闭包不等于内存泄漏。闭包是机制,泄漏是误用。


5. this 的绑定规则有哪些?

面试回答

this 的指向不是在函数定义时决定的,而是在函数调用时决定的。常见规则有四种:

1)默认绑定

独立函数调用,非严格模式下指向全局对象,严格模式下是 undefined

js 复制代码
function fn() {
  console.log(this);
}
fn();
2)隐式绑定

作为对象的方法调用,this 指向调用它的对象。

js 复制代码
const obj = {
  name: 'A',
  say() {
    console.log(this.name);
  }
};
obj.say(); // A
3)显式绑定

通过 callapplybind 指定 this

js 复制代码
function say() {
  console.log(this.name);
}
say.call({ name: 'B' });
4)new 绑定

new 调用构造函数时,this 指向新创建的实例对象。

js 复制代码
function Person(name) {
  this.name = name;
}
const p = new Person('Tom');

特殊点:箭头函数

箭头函数没有自己的 this,它会继承外层作用域的 this

所以箭头函数适合拿来避免普通函数里 this 丢失的问题。

常见追问

  • callapplybind 区别?
  • 箭头函数为什么不能当构造函数?
  • 事件回调里 this 指向谁?

易错点

不要死记"this 指向函数本身"或者"this 永远指向调用者",这两种说法都不完整。


6. 深拷贝和浅拷贝有什么区别?如何实现深拷贝?

面试回答

浅拷贝只复制第一层属性,如果属性值还是引用类型,那么新旧对象仍然共享内部引用。

深拷贝会递归复制所有层级,得到一个完全独立的新对象。

浅拷贝例子

js 复制代码
const a = { info: { age: 18 } };
const b = { ...a };
b.info.age = 20;
console.log(a.info.age); // 20

常见深拷贝方案

1)JSON.parse(JSON.stringify(obj))

优点:简单

缺点:

  • 会丢失 undefined
  • 会丢失 Symbol
  • 会丢失函数
  • Date 会变字符串
  • Map/Set 会丢失
  • 循环引用会报错
2)structuredClone

现代浏览器和新环境支持更好,能处理更多内置类型,且支持循环引用,实际开发更推荐。

3)手写递归深拷贝

适合面试展示基本功,要注意:

  • 区分数组和对象
  • 处理 null
  • 处理循环引用
  • 处理 DateRegExpMapSet

面试建议回答

在业务里优先考虑:

  • 数据是否真的需要深拷贝
  • 能不能通过不可变更新、结构共享解决
  • 需要时优先用成熟能力而不是自己造轮子

常见追问

  • 为什么 JSON 方案不可靠?
  • 如何处理循环引用?
  • structuredClone 和 lodash 的 cloneDeep 如何选?

7. 什么是防抖和节流?分别适合什么场景?

面试回答

它们都是为了控制高频触发事件,核心区别在于"执行时机"。

防抖(debounce)

事件触发后,不立即执行,等停止触发一段时间后再执行。

如果这段时间内又触发了,就重新计时。

适合场景:

  • 搜索框输入联想
  • 窗口 resize 后重新布局
  • 表单输入校验

核心目标:

只关心"最后一次"。

节流(throttle)

规定一个时间间隔,在这个间隔内无论触发多少次,只执行一次。

适合场景:

  • 页面滚动监听
  • 鼠标移动
  • 拖拽
  • 高频上报

核心目标:

把执行频率降下来,稳定输出。

一句话区分

  • 防抖:等你停下来我再执行
  • 节流:你一直触发也没关系,但我按固定频率执行

常见追问

  • 如何实现立即执行版防抖?
  • 节流如何在最后一次也执行?
  • React/Vue 中如何正确清理防抖节流?

二、浏览器与网络高频题

8. 从输入 URL 到页面渲染完成,中间发生了什么?

面试回答

这是一个典型综合题,建议按阶段回答:

1)URL 解析

浏览器先解析输入内容,判断是 URL 还是搜索关键字。

2)缓存检查

浏览器会先看:

  • 是否命中强缓存
  • 是否需要协商缓存
    如果缓存可用,就可能不用真正发请求。

3)DNS 解析

把域名解析成 IP 地址。

4)建立连接

  • HTTP:TCP 三次握手
  • HTTPS:TCP + TLS 握手,协商加密参数和证书校验

5)发送 HTTP 请求

浏览器发出请求头、请求体等。

6)服务器处理并返回响应

响应包括:

  • 状态码
  • 响应头
  • 响应体

7)浏览器解析页面

如果是 HTML:

  • 解析 HTML,构建 DOM
  • 解析 CSS,构建 CSSOM
  • 合并生成 Render Tree
  • Layout(回流/布局)
  • Paint(重绘)
  • Compositing(合成)

8)遇到资源继续加载

HTML 解析过程中可能继续加载:

  • CSS
  • JS
  • 图片
  • 字体
  • 异步接口数据

9)JS 执行影响页面

JavaScript 可能修改 DOM、样式、数据,触发再次渲染。

10)页面可交互

关键资源完成后,页面逐渐达到可交互状态。

面试答题技巧

这个题不要只背"DNS/TCP/HTTP/渲染"四个名词,重点是把它们串成一个完整流程。


9. 强缓存和协商缓存分别是什么?

面试回答

HTTP 缓存的目标是减少重复请求、降低延迟、减轻服务器压力。

强缓存

浏览器直接使用本地缓存,不发请求到服务器。

常见响应头:

  • Cache-Control: max-age=3600
  • Expires

只要缓存没过期,就直接用缓存。

协商缓存

本地有缓存,但浏览器会发请求问服务器"我这个缓存还能不能继续用?"

常见字段:

  • ETag / If-None-Match
  • Last-Modified / If-Modified-Since

如果资源没变,服务器返回 304 Not Modified,浏览器继续使用本地缓存。

区别总结

  • 强缓存:连请求都不发
  • 协商缓存:会发请求,但可能不传资源内容

实战建议

静态资源常用:

  • 文件名加 hash
  • 配合强缓存长期缓存
    动态 HTML 一般缓存更谨慎

常见追问

  • Cache-ControlExpires 谁优先?
  • ETagLast-Modified 有什么区别?
  • 为什么打包文件要带 hash?

10. HTTP/1.1、HTTP/2、HTTP/3 有什么区别?

面试回答

这道题建议从"性能瓶颈是如何一步步被解决的"去讲。

HTTP/1.1

特点:

  • 支持长连接
  • 支持管线化(但实际使用有限)
  • 一个 TCP 连接里请求仍容易队头阻塞
  • 浏览器通常通过开多个连接缓解问题

HTTP/2

主要改进:

  1. 二进制分帧
  2. 多路复用
    • 一个连接里并发多个请求
  3. 头部压缩
  4. 服务器推送(实际使用有限)

它明显改善了 HTTP/1.1 的并发效率问题。

HTTP/3

基于 QUIC,而 QUIC 基于 UDP。

主要优势:

  • 更快的连接建立
  • 更好地处理丢包和弱网
  • 减少 TCP 层队头阻塞带来的影响
  • 移动网络切换场景更友好

面试总结版

  • HTTP/1.1:文本协议,连接效率一般
  • HTTP/2:多路复用、头部压缩,显著提升并发能力
  • HTTP/3:基于 QUIC,弱网和连接迁移体验更好

常见追问

  • HTTP/2 已经多路复用了,为什么还需要 HTTP/3?
  • TCP 队头阻塞和 HTTP 队头阻塞是什么关系?

11. HTTPS 比 HTTP 安全在哪里?

面试回答

HTTPS = HTTP + TLS/SSL。

它主要解决三个问题:

  1. 加密

    • 数据传输过程中不容易被窃听
  2. 完整性

    • 数据不容易被篡改
  3. 身份认证

    • 通过证书机制确认你访问的是正确服务器

握手简化理解

  1. 客户端发起连接
  2. 服务器返回证书和公钥相关信息
  3. 客户端验证证书是否合法
  4. 双方协商出会话密钥
  5. 后续数据用对称加密传输

为什么既有非对称加密又有对称加密?

  • 非对称加密安全,但慢
  • 对称加密快,适合大量数据传输
    所以一般用非对称加密来协商密钥,再用对称加密传输数据。

常见追问

  • 为什么 HTTPS 还是可能被中间人攻击?
  • 证书链是什么?
  • TLS 握手为什么会影响首包时间?

12. 什么是跨域?常见解决方案有哪些?

面试回答

跨域本质上是浏览器的同源策略限制

协议、域名、端口三者只要有一个不同,就算不同源。

例如:

  • https://a.comhttps://b.com 跨域
  • https://a.comhttp://a.com 跨域
  • https://a.com:3000https://a.com:8080 跨域

常见解决方案

1)CORS

最正规、最常用。

后端通过响应头声明允许哪些源访问,例如:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
2)反向代理

开发环境常见:

  • Vite proxy
  • Webpack devServer proxy
  • Nginx 代理

本质是让前端请求同源服务器,再由服务器转发。

3)JSONP

只支持 GET,现在很少用了,面试里知道原理即可。

4)postMessage

适用于不同窗口、iframe 之间通信。

面试提醒

跨域是浏览器限制,不是服务器限制。

服务端之间互相请求通常不受浏览器同源策略影响。

常见追问

  • 什么是预检请求(OPTIONS)?
  • 为什么有些请求会触发预检,有些不会?
  • Cookie 跨域传输要注意什么?

三、Vue3 / React 高频题

13. Vue3 为什么用 Proxy 替代 Object.defineProperty?

面试回答

Vue2 使用 Object.defineProperty 劫持对象属性,Vue3 则用 Proxy 代理整个对象。

Vue3 这样做主要是为了解决 Vue2 响应式的一些天然缺陷。

Vue2 的痛点

  1. 无法直接监听对象新增/删除属性
  2. 数组某些操作需要特殊处理
  3. 需要递归遍历对象,初始化成本较高

Proxy 的优势

  1. 代理整个对象
    • 不用一开始就把所有属性都递归劫持
  2. 可以监听新增、删除属性
  3. 可以原生拦截更多操作
    • get
    • set
    • deleteProperty
    • has
    • ownKeys
  4. 更适合复杂数据结构
    • Map
    • Set
    • 嵌套对象

但要说明

Proxy 不是"绝对更快"的万能答案。它更大的优势在于能力更完整、设计更现代、便于维护框架底层

常见追问

  • Vue3 依赖收集是在哪一步完成的?
  • refreactive 的区别?
  • 为什么 reactive 不能直接代理基本类型?

14. ref 和 reactive 有什么区别?

面试回答

它们都是 Vue3 响应式 API,但适用对象不同。

reactive

用于代理对象类型

  • Object
  • Array
  • Map
  • Set
js 复制代码
const state = reactive({ count: 0 });
state.count++;

ref

通常用于包装基本类型,当然也能包装对象。

js 复制代码
const count = ref(0);
count.value++;

区别总结

  1. ref 访问值要用 .value
  2. reactive 更适合对象整体状态
  3. ref 更适合单值、可解构、组合式封装
  4. 模板里会自动解包,所以模板中经常不用写 .value

使用建议

  • 单个数字、字符串、布尔值:优先 ref
  • 一个表单对象、页面状态对象:优先 reactive

常见追问

  • 为什么 setup 解构 reactive 后会失去响应式?
  • toRefs 是干什么的?
  • ref 包对象和 reactive 有什么取舍?

15. React Hooks 为什么不能放在条件语句里?

面试回答

因为 React Hooks 的底层依赖调用顺序稳定

React 在函数组件渲染时,会按顺序把每个 Hook 挂到内部链表或对应位置上。它不是靠变量名识别,而是靠"第几个 Hook"。

如果你把 Hook 写在条件里:

js 复制代码
if (flag) {
  useEffect(() => {}, []);
}

那么第一次渲染和第二次渲染的 Hook 顺序可能不同,React 就无法正确把状态和对应 Hook 对上,结果会错乱。

正确写法

把 Hook 始终写在顶层,再把条件放进 Hook 内部:

js 复制代码
useEffect(() => {
  if (flag) {
    // do something
  }
}, [flag]);

本质

Hooks 规则不是语法限制,而是为了保证 React 在多次渲染之间,能够稳定找到同一个 Hook 的状态。

常见追问

  • useState 为什么调用后状态能记住?
  • Hooks 和闭包有什么关系?
  • 为什么自定义 Hook 也必须遵守同样规则?

16. useEffect 和 useLayoutEffect 有什么区别?

面试回答

两者都会在组件渲染后执行副作用,但执行时机不同。

useEffect

通常在浏览器完成绘制后异步执行。

适合:

  • 请求数据
  • 订阅事件
  • 打日志
  • 非阻塞副作用

useLayoutEffect

会在 DOM 更新后、浏览器绘制前同步执行。

适合:

  • 读取布局信息
  • 同步修改 DOM,避免闪烁

举例

如果你要测量元素尺寸并立刻修正位置,useLayoutEffect 更合适;

如果只是发请求、绑定事件,用 useEffect 就够了。

风险

useLayoutEffect 会阻塞浏览器绘制,用多了会影响性能。

常见追问

  • 为什么某些 UI 闪动问题要用 useLayoutEffect
  • 服务端渲染环境下它有什么注意点?

17. key 在 diff 算法里有什么作用?为什么不能乱用 index?

面试回答

key 的作用是帮助框架在新旧节点比较时,识别哪个节点是同一个元素,从而尽量复用 DOM,减少不必要的删除和重建。

为什么需要 key

列表更新时,如果没有稳定 key,框架只能按位置猜。

当插入、删除、排序发生时,可能导致:

  • 原本可复用的节点没复用
  • 组件状态错位
  • 输入框内容错乱
  • 渲染性能变差

为什么不建议用 index

当列表是静态的、不增删排序时,用 index 问题不大;

但一旦列表顺序会变化,index 就不稳定了。

例如:

js 复制代码
items.map((item, index) => <Row key={index} />)

如果头部插入一项,后面所有 index 都变了,React/Vue 可能会把旧节点错误复用到新位置。

最佳实践

优先使用业务上真正唯一且稳定的 id 作为 key。

常见追问

  • key 改了为什么组件会重新挂载?
  • 为什么有时故意改 key 来强制重置组件状态?

四、工程化高频题

18. Vite 和 Webpack 的核心区别是什么?

面试回答

Webpack 和 Vite 都是前端构建工具,但思路不同。

Webpack

Webpack 的核心是打包一切资源,构建依赖图

开发环境下也会先做较完整的打包流程,所以大型项目启动和热更新可能偏慢。

Vite

Vite 利用现代浏览器原生支持 ES Module 的能力:

  • 开发时按需加载模块
  • 不必一开始打完整包
  • 启动很快
  • 热更新更轻量

生产环境下,Vite 通常仍会借助 Rollup 做正式构建优化。

通俗理解

  • Webpack:先把仓库都整理打包好再给你用
  • Vite:开发时谁用谁加载,生产时再统一打包优化

选择建议

  • 新项目一般更偏向 Vite
  • 老项目、复杂历史包袱项目可能还在 Webpack 体系里

常见追问

  • Vite 为什么冷启动快?
  • HMR 为什么更快?
  • Vite 插件生态和 Rollup 有什么关系?

19. Tree Shaking 是什么?为什么有时不生效?

面试回答

Tree Shaking 指的是:在打包时移除没有被使用到的代码

它常依赖 ES Module 的静态结构,因为 ESM 的导入导出关系在编译阶段就可以分析。

为什么 ESM 更适合 Tree Shaking

因为:

  • import/export 是静态的
  • 依赖关系可提前分析
  • 哪些导出没被使用更容易判断

不生效的常见原因

  1. 使用了 CommonJS
  2. 模块有副作用
  3. 打包配置不正确
  4. 引入方式不够精细
  5. 第三方库本身构建质量一般

面试可补充

项目里除了 Tree Shaking,还会配合:

  • 代码分割
  • 懒加载
  • CDN
  • gzip/brotli
  • 图片优化

常见追问

  • 什么是副作用(side effects)?
  • 为什么 import 'xxx.css' 不能被轻易删掉?

20. Babel 的编译流程是怎样的?

面试回答

Babel 的核心流程可以概括为三步:

  1. Parse(解析)

    • 把源代码解析成 AST(抽象语法树)
  2. Transform(转换)

    • 对 AST 做遍历和修改
    • 插件就是在这一层工作
  3. Generate(生成)

    • 把转换后的 AST 再生成新的代码

举例

比如把箭头函数:

js 复制代码
const add = (a, b) => a + b;

转换成 ES5 普通函数,本质上就是 AST 转换。

Babel 的作用

  • 语法降级兼容旧环境
  • 支持 JSX、TypeScript 等语法转换
  • 配合插件做代码增强

常见追问

  • Babel 和 TypeScript 编译器的区别?
  • Babel 能做类型检查吗?
  • 插件和 preset 有什么关系?

五、性能优化高频题

21. 首屏加载慢,通常从哪些方面优化?

面试回答

首屏优化要分层次回答,不能只说"压缩资源"。

1)资源体积优化

  • 代码分包
  • 懒加载
  • Tree Shaking
  • 压缩 JS/CSS
  • 图片压缩、WebP/AVIF
  • 删除无用依赖

2)请求链路优化

  • CDN
  • HTTP 缓存
  • 减少重定向
  • 减少 DNS 查询
  • 使用 HTTP/2 或 HTTP/3
  • 接口合并

3)渲染路径优化

  • 关键 CSS 优先
  • 减少阻塞渲染的脚本
  • 合理使用 defer / async
  • SSR / SSG 提前输出 HTML
  • 骨架屏提升感知速度

4)运行时优化

  • 降低首屏执行 JS 量
  • 避免主线程长任务
  • 延后非关键逻辑
  • 分片计算、Web Worker

面试建议

最好给出你自己的实战案例,例如:

  • 包体从 3MB 降到 900KB
  • 首屏时间从 4.5s 降到 2.1s
  • 通过路由级拆包和图片懒加载完成优化

常见追问

  • 白屏时间和首屏时间有什么区别?
  • CSR、SSR、SSG 怎么选?

22. 什么是虚拟列表?适合解决什么问题?

面试回答

虚拟列表用于解决大数据量列表渲染性能问题

核心思想是:

页面里只渲染"可视区域附近的少量 DOM",而不是把几千条、几万条数据一次性全部渲染出来。

为什么有效

浏览器渲染大量 DOM 成本很高,会影响:

  • 首次渲染
  • 滚动流畅度
  • 内存占用

实现思路

  1. 根据容器高度和单项高度,算出可视区可显示多少项
  2. 根据滚动位置,算出当前应渲染的起止索引
  3. 只渲染这一小段数据
  4. 用一个占位容器撑出完整滚动高度
  5. 内部列表通过 transform 偏移到正确位置

适用场景

  • 聊天记录
  • 日志列表
  • 大表格
  • 商品长列表

常见追问

  • 不定高列表怎么做?
  • 虚拟列表为什么不适合数据量很小的场景?
  • 虚拟列表和分页有何区别?

23. 前端性能指标 LCP、FCP、CLS 分别是什么?

面试回答

这是面试里越来越常见的 Web 性能指标题。

FCP(First Contentful Paint)

首次内容绘制时间。

表示页面第一次把文本、图片、SVG、canvas 等内容绘制出来的时间。

LCP(Largest Contentful Paint)

最大内容绘制时间。

通常反映用户看到主内容的速度,是非常关键的首屏体验指标。

CLS(Cumulative Layout Shift)

累计布局偏移。

衡量页面元素是否"乱跳"。比如图片没预留尺寸、广告插入导致页面抖动,CLS 就会变差。

如何优化

  • FCP/LCP
    • 优化首屏资源大小
    • 提前加载关键资源
    • 减少阻塞脚本
    • 服务端渲染
    • 图片优化
  • CLS
    • 为图片和广告预留尺寸
    • 避免动态插入内容挤压已有布局
    • 使用稳定布局策略

常见追问

  • 这些指标如何监控?
  • Lighthouse 和真实用户监控有什么区别?

六、前端安全高频题

24. 什么是 XSS?如何防御?

面试回答

XSS(Cross-Site Scripting)指攻击者把恶意脚本注入页面,并在其他用户浏览器中执行。

常见类型

  1. 存储型 XSS
    • 恶意脚本被保存到数据库,别人访问时触发
  2. 反射型 XSS
    • 恶意脚本来自 URL 参数,服务器原样返回
  3. DOM 型 XSS
    • 前端脚本不安全地操作 DOM 导致执行恶意代码

防御手段

  1. 对用户输入做转义/过滤
  2. 避免使用危险 API
    • 如直接拼接 innerHTML
  3. 使用 CSP(内容安全策略)
  4. 富文本场景使用白名单过滤
  5. 后端也要参与校验,不能只靠前端

常见追问

  • Vue/React 为什么能降低部分 XSS 风险?
  • v-html / dangerouslySetInnerHTML 为什么危险?

25. 什么是 CSRF?如何防御?

面试回答

CSRF(Cross-Site Request Forgery)是指攻击者诱导用户在已登录目标网站的情况下,偷偷向目标网站发起非本人意愿的请求。

比如用户登录了银行网站,同时又访问了攻击网站,攻击网站可能诱导浏览器带着银行 Cookie 发请求。

防御手段

  1. CSRF Token
    • 服务端下发随机 token,请求时一起提交并校验
  2. SameSite Cookie
    • 限制跨站请求携带 Cookie
  3. 验证 Referer / Origin
  4. 关键操作二次确认
    • 短信、验证码、密码确认

易混点

  • XSS 是"执行恶意脚本"
  • CSRF 是"冒充用户发请求"

七、AI 前端面试题(2025--2026 明显升温)

26. 现在前端面试会问 AI 相关内容吗?

面试回答

会,而且越来越常见,但通常不是考你训练模型,而是考你如何把 AI 能力接入前端产品

常见考法

  1. AI 聊天产品怎么做

    • 对话 UI
    • 历史消息
    • 流式输出
    • 打字机效果
    • 错误重试
  2. 流式响应怎么接

    • SSE
    • fetch stream
    • WebSocket
  3. Prompt 和上下文管理

    • system prompt
    • 多轮会话
    • token 截断策略
  4. RAG 基本概念

    • embedding
    • 检索
    • 拼接上下文

你可以这样回答趋势

对通用前端岗位,AI 题目不一定每轮都问;

但中高级岗位、平台型岗位、效率工具、企业应用、内容产品、数据平台等方向,被问到 AI 相关工程问题的概率明显更高。

面试建议

你不用把自己包装成算法工程师,但至少要能讲清:

  • 怎么做一个 AI 聊天页面
  • 怎么接流式响应
  • 如何处理 markdown、代码块、复制、重试、停止生成
  • 如何控制上下文长度和历史消息

27. 如何实现一个 AI 聊天应用?

面试回答

可以从前端、服务端、模型接入三个层面讲。

前端层

  • 聊天列表
  • 输入框
  • 停止生成
  • 重新生成
  • markdown 渲染
  • 代码块高亮
  • 打字机效果
  • 历史会话管理

服务端层

不建议前端直接暴露模型密钥,通常由服务端代理:

  • 接收前端消息
  • 拼接上下文
  • 调用模型接口
  • 把流式结果转发给前端

模型交互层

需要考虑:

  • 模型选择
  • token 限制
  • 系统提示词
  • 错误重试
  • 超时控制
  • 审计与安全

关键难点

  1. 流式输出
    • 让用户更快看到回复
  2. 上下文管理
    • 不能无限带历史消息
  3. 消息状态管理
    • 正在生成、已完成、失败、重试中
  4. 异常处理
    • 网络中断、模型报错、限流

面试加分点

如果你能讲到:

  • 消息去重
  • 多轮上下文裁剪
  • 代码块渲染
  • AbortController 停止请求
  • 乐观更新
    那就已经比很多候选人强很多了。

28. 什么是流式响应?前端为什么要做流式渲染?

面试回答

流式响应就是服务端不是等整个结果都生成完再一次性返回,而是边生成边把内容一段段传给前端。

好处

  1. 更快的感知速度
    • 用户先看到一部分内容,而不是一直转圈
  2. 更符合聊天产品体验
  3. 便于做停止生成、增量渲染

前端怎么做

常见方案:

  • SSE
  • fetch + ReadableStream
  • WebSocket

前端拿到每一段内容后,持续拼接到当前回答中,并触发视图更新。

关键实现点

  • 正确处理 chunk 边界
  • 控制滚动到底部
  • 支持停止生成
  • 断流时要有失败兜底
  • 渲染 markdown 时避免频繁全量重算

常见追问

  • SSE 和 WebSocket 怎么选?
  • 为什么很多 AI 聊天产品喜欢流式响应?

29. 什么是 RAG?前端需要懂到什么程度?

面试回答

RAG 是 Retrieval-Augmented Generation,中文一般叫"检索增强生成"。

它的核心思路是:

  1. 用户提问
  2. 系统先去知识库里检索相关内容
  3. 把检索结果作为上下文拼给模型
  4. 模型基于这些资料生成回答

为什么需要 RAG

因为大模型本身不是你的私有知识库,它可能:

  • 不知道企业内部数据
  • 知识过时
  • 容易胡编

RAG 可以让回答更贴近你自己的文档和业务数据。

前端面试里需要懂到什么程度

你不一定要会搭建向量库,但至少要知道:

  • 检索结果不是模型自己"记住"的,而是先查再答
  • embedding 是把文本变成向量,便于相似度检索
  • 前端通常负责:
    • 查询入口
    • 检索结果展示
    • 引用来源展示
    • 生成状态展示

常见追问

  • RAG 和微调有什么区别?
  • 为什么有了 RAG 还是会幻觉?

八、面试收尾建议

30. 面试回答时怎样更像高级工程师?

建议回答方式

每道题尽量按这个顺序讲:

  1. 定义是什么
  2. 为什么出现
  3. 核心原理
  4. 实际应用场景
  5. 优缺点 / 边界
  6. 项目里怎么落地

示例

不要只说:

虚拟列表就是只渲染可视区域。

更好的说法是:

虚拟列表是为了解决大数据量 DOM 渲染导致的首屏慢、滚动卡、内存高等问题。它通过维护可视区域对应的数据窗口,只渲染当前需要展示的部分节点,同时用占位容器保持滚动高度,从而显著降低 DOM 数量和渲染压力。


九、建议你重点反复练习的题

  1. 事件循环
  2. Promise / async await
  3. 闭包 / this
  4. URL 到页面渲染
  5. 缓存 / 跨域 / HTTPS
  6. Vue3 响应式
  7. React Hooks / useEffect
  8. Vite vs Webpack
  9. 首屏优化 / 虚拟列表 / 性能指标
  10. XSS / CSRF
  11. AI 聊天应用 / 流式响应 / RAG

十、最后提醒

这份文档的正确用法不是死记硬背,而是:

  • 先把答案读懂
  • 再用自己的话讲出来
  • 最后结合你的项目经历补上"我实际怎么做过"

只要你能把"原理 + 业务场景 + 工程落地"连起来,面试表现会明显提升。

相关推荐
qq_433502182 小时前
Codex cli 飞书文档创建进阶实用命令 + Skill 创建&使用 小白完整教程
java·前端·飞书
IT_陈寒2 小时前
为什么我的Vite热更新老是重新加载整个页面?
前端·人工智能·后端
一袋米扛几楼982 小时前
【网络安全】SIEM -Security Information and Event Management 工具是什么?
前端·安全·web安全
zhaoshuzhaoshu2 小时前
人工智能(AI)发展史:详细里程碑
人工智能·职场和发展
小陈工3 小时前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python
Cobyte3 小时前
3.响应式系统基础:从发布订阅模式的角度理解 Vue2 的数据响应式原理
前端·javascript·vue.js
竹林8183 小时前
从零到一:在React前端中集成The Graph查询Uniswap V3池数据实战
前端·javascript
Mintopia3 小时前
别再迷信"优化":大多数性能问题根本不在代码里
前端