咨询热线:400-888-xxxx 邮箱:contact@kaoacca.cn 微信公众号:前端技术社区

前端面试题目及答案权威解析

覆盖HTML/CSS/JavaScript/框架/工程化/性能优化等全栈技术栈,结合真实企业真题、时间线演进与实战案例,助你高效突破技术瓶颈。

前言:为什么你需要这份《前端面试题目及答案》?

随着互联网技术的飞速发展,前端开发已从“切图仔”演变为覆盖多端、多技术栈的综合型岗位。企业对前端工程师的要求日益提高,不再局限于页面实现,更关注系统设计能力、工程化思维、性能意识与安全素养。

本页面整理了前端面试题目及答案的完整知识体系,涵盖:

  • ✅ JavaScript 核心机制(原型链、闭包、执行上下文、事件循环、内存管理)
  • ✅ HTML & CSS 高频考点(布局原理、响应式方案、BFC、Flex/Grid 深度解析)
  • ✅ 主流框架原理(React/Vue 生命周期、虚拟 DOM、响应式原理、状态管理)
  • ✅ 性能优化实战(首屏加载、资源压缩、懒加载、CDN、LCP优化)
  • ✅ Web 安全攻防(XSS/CSRF/重放攻击、CSP、HTTPS、输入校验)
  • ✅ 工程化体系(Webpack/Vite原理、模块打包、CI/CD、TypeScript进阶)
  • ✅ 浏览器原理(渲染流程、重绘重排、GPU加速、Service Worker)

所有题目均基于真实企业面试题库(BAT/TMD/外企/创业公司),每道题附带标准答案 + 扩展解析 + 实战示例 + 常见误区,避免“背题式复习”,真正实现知识内化与迁移应用。

📌 本页面设计特色

  • • 采用时间轴演进视角:如“HTTP协议演进”、“浏览器渲染优化路径”,理解技术发展逻辑
  • • 多维度对比分析:如“Flex vs Grid”、“Vue vs React”、“localStorage vs sessionStorage”
  • • 代码示例丰富:每个核心概念均配可运行的代码片段,支持直接复制测试
  • • 错题警示区:标注高频失分点(如“注意:此题易被误答为同步行为!”)

🎯 谁适合阅读?

应届生

系统梳理知识体系,弥补学校课程与企业需求的断层,快速掌握面试高频考点。

1-3年经验

查漏补缺,深化底层原理认知,突破技术瓶颈,为晋升/跳槽做好准备。

转行者

从零构建前端知识框架,避免碎片化学习,掌握企业真正需要的核心能力。

📚 学习建议

  1. 按模块顺序阅读,理解后再记忆,避免死记硬背
  2. 对每个代码示例亲手运行,观察输出结果与预期的差异
  3. 结合自身项目经验,思考“如果是我,会如何优化?”
  4. 定期回顾错题与易混淆点,建立个人知识库

JavaScript 核心:执行机制与高级特性

1. 事件循环(Event Loop)详解

面试题:请描述浏览器中的事件循环机制,并说明宏任务与微任务的执行顺序。

事件循环是浏览器处理异步任务的核心机制。其执行流程如下:

  • ① 执行栈清空 → ② 执行所有微任务(microtask) → ③ 渲染更新(如有需要)→ ④ 执行一个宏任务(macrotask)→ 重复

微任务包括:Promise.then/catch/finally、MutationObserver、queueMicrotask

宏任务包括:script、setTimeout、setInterval、I/O、UI渲染、postMessage

注意:微任务总在当前宏任务结束后、渲染前执行,确保异步逻辑的及时性。

常见误区:

  • ❌ “setTimeout 100ms 就会在100ms后执行” → 实际:至少100ms(取决于调用栈空闲时间)
  • ❌ “Promise 是同步的” → 构造函数同步,then/catch 异步
  • ❌ “async/await 是多线程” → 本质仍是单线程,基于Promise实现

浏览器 vs Node.js 差异:

  • 浏览器:宏任务 → 渲染 → 微任务 → 宏任务...
  • Node.js(v11+):与浏览器一致;v10-:微任务在宏任务后、I/O前执行
// 示例:事件循环执行顺序
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
queueMicrotask(() => console.log('D'));
setTimeout(() => console.log('E'), 0);
// 输出顺序:A → C → D → B → E
// 解析:
// 1. 'A' 同步输出
// 2. setTimeout 进入宏任务队列(2个)
// 3. Promise.then 进入微任务队列
// 4. queueMicrotask 也进入微任务队列
// 5. 宏任务执行完毕后,清空微任务:C → D
// 6. 渲染后执行第一个宏任务:B
// 7. 执行第二个宏任务:E

2. 原型链与继承

关键关系:

  • obj.__proto__ === Constructor.prototype
  • Function.prototype.__proto__ === Object.prototype
  • Object.prototype.__proto__ === null(原型链终点)

继承实现方式:

  • 原型链继承 → 共享引用类型属性问题
  • 构造函数继承 → 无法复用方法
  • 组合继承(原型+构造)→ 调用两次父构造函数
  • 寄生组合继承(最优解)→ 最佳实践

高频错误案例:

// 错误写法:共享引用属性
function Parent() {
  this.colors = ['red', 'blue'];
}
function Child() {}
Child.prototype = new Parent();
const c1 = new Child();
const c2 = new Child();
c1.colors.push('green');
console.log(c2.colors); // ['red', 'blue', 'green'] ← c2被意外修改

解决方案:属性在构造函数中定义,方法在原型上定义

ES6 Class 本质:语法糖,底层仍是原型继承

  • class 声明提升(但无变量提升)
  • 方法不可枚举(Object.defineProperty 设置 enumerable: false)
  • 必须用 new 调用
  • 内部默认严格模式

建议:现代开发优先使用 class,但需理解其原型本质

3. 闭包与内存管理

闭包 = 函数 + 其词法环境

当内部函数引用外部函数的变量时,即使外部函数执行完毕,其变量仍被保留,形成闭包。

典型应用:

  • 模块化封装(私有变量)
  • 函数柯里化
  • 事件回调中保持上下文

常见内存泄漏:

  • 意外的全局变量(未使用 strict mode)
  • 被遗忘的定时器(未调用 clearInterval)
  • DOM 引用未移除(事件监听器未解绑)
  • 闭包中引用大对象未释放

检测工具:Chrome DevTools → Memory → Heap Snapshot

// 安全闭包:限制引用范围
const createCounter = (() => {
  let count = 0; // 私有变量
  return {
    increment() { count++; },
    decrement() { count--; },
    getCount() { return count; }
  };
})();
// 避免:引用大对象
const badClosure = (() => {
  const largeData = new Array(1000000).fill('data'); // 可能泄漏
  return () => console.log(largeData.length);
})();

4. this 指向与绑定

4种绑定规则:

  1. 默认绑定(严格模式下 this=undefined)
  2. 隐式绑定(obj.method() → this=obj)
  3. 显式绑定(call/apply/bind)
  4. new 绑定(this=新创建的对象)

优先级:new > 显式 > 隐式 > 默认

箭头函数 this 特点:

  • 不绑定自己的 this,继承外层作用域的 this
  • 不能用作构造函数(无 [[Construct]])
  • 无 arguments,需用 rest 参数
  • 不能用作事件处理函数(this 不指向 DOM 元素)

使用场景:回调函数、Promise 链、避免 this 丢失

// 面试题:输出结果?
const obj = {
  name: 'Alice',
  getName: function() {
    return this.name;
  }
};
const getName = obj.getName;
console.log(getName()); // undefined(默认绑定,严格模式)
// 修正方案:
const getNameBound = obj.getName.bind(obj);
console.log(getNameBound()); // Alice

5. 深拷贝 vs 浅拷贝

浅拷贝方法:

  • Object.assign()
  • 展开运算符 {...obj}
  • Array.prototype.slice()
  • Array.prototype.concat()

问题:仅复制第一层属性,引用类型仍共享

// 深拷贝:递归 + 类型判断
function deepClone(source, map = new WeakMap()) {
  if (source === null || typeof source !== 'object') return source;
  if (map.has(source)) return map.get(source); // 处理循环引用
  const target = Array.isArray(source) ? [] : {};
  map.set(source, target);
  for (const key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      target[key] = deepClone(source[key], map);
    }
  }
  return target;
}
// 测试:
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = deepClone(obj1);
obj2.b.c = 99;
console.log(obj1.b.c); // 2 ← 原对象未修改

循环引用处理:

  • 使用 WeakMap 存储已拷贝对象,避免无限递归
  • Symbol 和 BigInt 需特殊处理(Symbol.for() / BigInt.asIntN())
  • 函数无法深拷贝(需特殊约定)

现代方案:structuredClone(原生 API,支持循环引用)

const obj = { a: 1 };
obj.self = obj;
const cloned = structuredClone(obj); // ✅ 支持循环引用
console.log(cloned.self === cloned); // true

HTML & CSS:布局原理与样式优化

1. BFC(块级格式化上下文)详解

触发条件(满足其一即可):

  • 根元素(<html>)
  • float ≠ none
  • position: absolute/fixed
  • display: inline-block/table-cell/table-caption
  • overflow ≠ visible
  • display: flow-root

三大核心应用:

  1. 清除浮动(自适应高度容器)
  2. 防止 margin 塌陷
  3. 自适应两栏布局

.container { overflow: hidden; }
.sidebar { float: left; width: 200px; }
.content { margin-left: 200px; }
.container {
  display: flex;
  flex-wrap: wrap;
}
.left, .right { flex: 0 0 200px; }
.center { flex: 1; min-width: 300px; }
@media (max-width: 768px) {
  .container { flex-direction: column; }
  .left, .right { flex: 0 0 auto; }
}

3. CSS 布局方案对比

方案 适用场景 优点 缺点
浮动(float) 早期布局 兼容性好 需清除浮动;脱离文档流
定位(position) 绝对定位元素 精准控制 脱离文档流;难响应式
Flex 一维布局 自动对齐;简单响应式 复杂网格需嵌套
Grid 二维布局 网格控制力强;响应式优雅 IE不支持;学习曲线陡
多列(columns) 报纸式排版 自动分栏 控制力弱;内容顺序混乱

4. 响应式设计最佳实践

推荐断点(移动优先):

  • 📱 <576px:手机竖屏
  • 📱 ≥576px:手机横屏
  • 📱 ≥768px:平板
  • 💻 ≥992px:桌面
  • 💻 ≥1200px:大屏桌面
  • 🖥 ≥1400px:超大屏

注意:优先使用内容驱动断点(content-based),而非设备尺寸

vw/vh 实用场景:

  • 等比缩放容器:width: 90vw; max-width: 1200px;
  • 全屏高度:min-height: 100vh;
  • 字体响应式:font-size: clamp(16px, 2vw, 24px);

clamp() 语法:clamp(最小值, 理想值, 最大值)


@media print {
  @page { margin: 2cm; }
  body { background: white; color: black; }
  .no-print { display: none; }
  a { text-decoration: none; }
  a[href]::after { content: " (" attr(href) ")"; }
}

5. CSS 变量(Custom Properties)

:root {
  --primary-color: #d65e38;
  --spacing: 16px;
}
.button {
  background-color: var(--primary-color);
  padding: var(--spacing);
  border-radius: 4px;
}

主题切换实现:


:root {
  --bg: #fff;
  --text: #333;
}
[data-theme="dark"] {
  --bg: #1a1a1a;
  --text: #f0f0f0;
}
body {
  background-color: var(--bg);
  color: var(--text);
  transition: background 0.3s;
}

与 Sass/Less 对比:

特性 CSS 变量 Sass/Less
运行时修改 ✅ 支持(JS 动态设置) ❌ 编译后固定
媒体查询作用域 ✅ 局部定义 ❌ 全局变量
浏览器原生支持 ✅ 现代浏览器 ❌ 需编译

框架原理:React & Vue 核心机制

1. React 生命周期演进

挂载阶段:

  1. constructor()
  2. static getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

更新阶段:

  1. static getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

卸载阶段:

  • componentWillUnmount()

废弃的生命周期(v16.3+):

  • componentWillMount() → 改用 constructor 或 useEffect
  • componentWillReceiveProps() → 改用 getDerivedStateFromProps
  • componentWillUpdate() → 改用 getSnapshotBeforeUpdate

原因:异步渲染导致多次调用,引发 bug

最佳实践:

  • 初始化逻辑 → constructor
  • 副作用(API请求/订阅)→ useEffect
  • 性能优化 → useMemo/useCallback
  • 跨组件通信 → Context + useReducer

注意:函数组件中避免使用 class 生命周期

2. Vue 响应式原理

Vue 2 核心:Object.defineProperty

  • 遍历 data 对象所有属性,用 getter/setter 拦截
  • 数组通过重写 7 个变更方法(push/pop/shift/unshift/splice/sort/reverse)实现响应

缺陷:

  • 无法监听对象属性的新增/删除
  • 无法监听数组索引变化
  • 需深度遍历,初始化性能差

Vue 3 核心:Proxy

  • 拦截整个对象,支持新增/删除属性
  • 数组响应通过 target.length 长度拦截
  • 惰性收集依赖,初始化性能提升
// Vue 3 响应式简化实现
const reactive = (obj) => new Proxy(obj, {
  get(target, key) {
    track(target, key); // 依赖收集
    return Reflect.get(target, key);
  },
  set(target, key, value) {
    const result = Reflect.set(target, key, value);
    trigger(target, key); // 触发更新
    return result;
  }
});

响应式局限:

  • 原始值(number/string/boolean)不能直接响应
  • 解构后丢失响应性:const { name } = reactive({ name: 'Alice' })
  • 需用 toRef/toRefs 包装
const state = reactive({ name: 'Alice' });
const { name } = toRefs(state); // ✅ 保持响应性
const nameRef = toRef(state, 'name'); // 单个属性

3. 虚拟 DOM 优劣分析

虚拟 DOM 流程:

  1. JSX → createElement → VNode(虚拟节点树)
  2. 首次渲染:VNode → 真实 DOM
  3. 状态更新:新 VNode + 旧 VNode → Diff → Patch

优势:

  • 跨平台(Web/Node/小程序)
  • 减少直接 DOM 操作
  • 支持服务端渲染(SSR)

Diff 策略:

  • 同层比较:不跨层级移动节点
  • Key 优化:唯一标识避免误判
  • 四类更新:
    • 节点类型不同 → 替换
    • 节点类型相同 → 更新属性
    • 子节点 → 对比新旧子节点
    • 列表 → 移动/添加/删除

性能陷阱:

  • ❌ 频繁全量重渲染 → 用 shouldComponentUpdate / memo
  • ❌ 未设置 key → 导致节点复用错误
  • ❌ 大列表渲染 → 虚拟滚动(react-window)

何时不需要虚拟 DOM?

  • 简单静态页面(直接 DOM 操作更快)
  • 高性能动画(直接操作 DOM 属性)

4. 状态管理方案对比

方案 适用场景 学习曲线 核心优势
Context API 全局配置/主题 ⭐ 零依赖;轻量
Redux 大型项目;时间旅行调试 ⭐⭐⭐⭐ 可预测;中间件生态
MobX 复杂状态;实时更新 ⭐⭐ 响应式;代码简洁
Pinia Vue 3+ 项目 ⭐⭐ TypeScript友好;组合式API
Zustand React 轻量状态 ⭐ 极简API;无样板代码

性能优化:从首屏加载到 LCP 优化

1. 首屏加载优化策略

关键优化点:

  • 压缩资源:CSS/JS/图片(WebP/AVIF)
  • CDN 加速:静态资源分发
  • HTTP/2 多路复用
  • 缓存策略:Cache-Control + ETag
  • 字体子集化:仅加载所需字符

代码分割方案:

  • 路由级分割:React.lazy + Suspense
  • 组件级分割:动态 import()
  • 库级分割:按需加载(lodash-es)
// React 懒加载
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function App() {
  return (
    }>
      
    
  );
}

预加载技术:

  • <link rel="preload">:预加载关键资源
  • <link rel="prefetch">:空闲时预取下一页资源
  • DNS 预解析:<link rel="dns-prefetch">
  • 预连接:<link rel="preconnect">

注意:避免过度预加载,占用带宽影响关键资源

2. 运行时性能优化

渲染优化要点:

  • 避免频繁重绘重排:批量 DOM 操作
  • 使用 transform/opacity:GPU 加速
  • 虚拟列表:仅渲染可见区域
  • 防抖/节流:高频事件(scroll/input)
// 防抖输入框搜索
const debounce = (fn, delay) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
};
input.addEventListener('input', debounce(search, 300));

内存管理技巧:

  • 及时移除事件监听器
  • 清除定时器
  • 弱引用:WeakMap/WeakSet
  • 图片懒加载:IntersectionObserver

动画性能原则:

  • 使用 requestAnimationFrame(同步屏幕刷新)
  • 避免布局抖动:先读取 offsetWidth 再写入样式
  • CSS 动画优先于 JS 动画
  • transform: translateZ(0) 触发 GPU

3. LCP(最大内容绘制)优化实战

影响 LCP 的 3 个因素:

  1. 服务器响应时间(TTFB)
  2. 资源加载时间(图片/字体)
  3. 客户端渲染时间(JS 执行)

优化方案:

  • 服务端渲染(SSR)或静态生成(SSG)
  • 关键 CSS 内联(Critical CSS)
  • 图片 lazy-loading + 尺寸预分配
  • 字体 display: optional
// 使用 Web Vitals 库监测 LCP
import { onLCP } from 'web-vitals';
onLCP(metric => {
  console.log('LCP:', metric.value);
  // 上报到监控平台
  sendToAnalytics('lcp', metric.value);
});

安全攻防:XSS/CSRF/重放攻击防护

1. XSS(跨站脚本攻击)

三大类型:

  • 存储型 XSS:恶意脚本存入数据库(如评论区)
  • 反射型 XSS:URL 参数注入(如 search?q=<script>
  • DOM 型 XSS:客户端 JS 操作 DOM 时注入
// DOM 型 XSS 示例
const urlParams = new URLSearchParams(window.location.search);
const q = urlParams.get('q');
document.getElementById('search').innerHTML = `搜索:${q}`; // ⚠️ innerHTML 直接插入

防护措施:

  • 输入过滤:白名单验证(如邮箱、手机号格式)
  • 输出编码:HTML/JS/URL/Style 编码
  • 使用安全 API:textContent 替代 innerHTML
  • Content Security Policy(CSP)

CSP 响应头示例:

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'unsafe-inline' cdn.example.com;
  style-src 'self' 'unsafe-inline';
  img-src *;
  font-src 'self' fonts.example.com;
  connect-src 'self';

说明:

  • 'self':仅允许同源资源
  • 'unsafe-inline':允许内联脚本(不推荐)
  • cdn.example.com:允许指定 CDN

2. CSRF(跨站请求伪造)

攻击流程:

  1. 用户登录银行网站(设置 cookie)
  2. 用户访问恶意网站
  3. 恶意网站发起转账请求(携带 cookie)
  4. 银行服务器执行转账

关键点:利用浏览器自动携带 cookie 的特性

防护方案:

  • CSRF Token:表单中添加随机 token,服务端校验
  • SameSite Cookie 属性
  • 验证 Origin/Referer 头
  • 双重提交 Cookie(Cookie + Token)

SameSite 属性:

  • Strict:完全禁止跨站携带 cookie
  • Lax:仅允许安全方法(GET)跨站
  • None:必须设置 Secure 属性(HTTPS)
Set-Cookie: sessionid=abc123; SameSite=Strict; Secure;

3. 其他安全威胁

防护:X-Frame-Options

X-Frame-Options: DENY | SAMEORIGIN | ALLOW-FROM https://example.com

现代方案:CSP frame-ancestors

HTTPS 加密链路:

  • TLS 握手:非对称加密协商密钥
  • 对称加密传输数据
  • HSTS 强制 HTTPS
Strict-Transport-Security: max-age=31536000; includeSubDomains

输入验证原则:

  • 白名单验证(如邮箱正则:/^[^\s@]+@[^\s@]+\.[^\s@]+$/)
  • 长度限制(防 SQL 注入、缓冲区溢出)
  • 特殊字符转义(如 < → &lt;)
  • 服务端校验(客户端校验可绕过)

工程化:从构建到 CI/CD 全流程

1. Webpack 核心机制

Webpack 构建四阶段:

  1. 解析(Resolve):解析文件路径、依赖
  2. 编译(Compile):调用 Loader 处理文件
  3. 打包(Pack):合并模块、生成 Chunk
  4. 输出(Emit):生成最终文件

Loader vs Plugin:

类型 作用对象 典型用途
Loader 单个文件 转换文件内容(Babel/PostCSS/Sass)
Plugin 整个构建过程 优化/压缩/生成文件(Terser/Clean)

性能优化技巧:

  • DLLPlugin:预编译第三方库
  • HappyPack:多线程 Loader
  • Cache:启用文件缓存(cache: { type: 'filesystem' })
  • SplitChunks:自动代码分割

2. Vite 原理与优势

核心创新:利用浏览器原生 ES Modules

  • 启动时:不打包,直接请求源码
  • 开发时:按需编译(仅处理修改的文件)
  • 热更新:HMR 仅发送变更模块

优势:启动速度极快(尤其大型项目)

按需编译流程:

  1. 浏览器请求 /src/main.js
  2. Vite 拦截请求 → 调用 Rollup 解析依赖
  3. 返回转换后的 ES Module 代码
  4. 浏览器继续请求依赖 → 递归处理

SSR 支持:

  • 服务端渲染:Vite SSR Plugin
  • 客户端激活:hydration
  • 预渲染:静态生成 HTML

与 Webpack SSR 对比:

  • Vite:开发体验更流畅
  • Webpack:生产构建更成熟

3. TypeScript 进阶

泛型应用:

interface ApiResponse {
  data: T;
  code: number;
  message: string;
}
const fetchUser = (): ApiResponse => {
  // ...
};

映射类型:

// 将属性设为可选
type Partial = { [P in keyof T]?: T[P] };
// 将属性设为只读
type Readonly = { readonly [P in keyof T]: T[P] };

常用工具类型:

  • Partial/Required:可选/必选
  • Pick/Omit:选择/排除属性
  • Exclude/Extract:联合类型过滤
  • ReturnType:函数返回类型

声明文件(.d.ts):

// 声明 jQuery
declare namespace jQuery {
  function ajax(url: string, options?: any): any;
}
// 声明模块
declare module 'lodash-es' {
  export function debounce any>(
    func: T,
    wait?: number
  ): T;
}

4. CI/CD 实践

GitHub Actions 示例:

name: Build & Deploy
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      - name: Install & Build
        run: |
          npm ci
          npm run build
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

测试策略:

  • 单元测试:Jest/Vitest(覆盖率 ≥80%)
  • 集成测试:Cypress/Playwright
  • E2E 测试:Puppeteer
  • 代码检查:ESLint + Prettier

部署方式:

方式 适用场景 回滚能力
蓝绿部署 高可用要求 ✅ 快速回滚
金丝雀发布 流量分批验证 ✅ 逐步回滚
滚动更新 资源有限场景 ❌ 需重建

浏览器原理:从输入 URL 到页面渲染

1. 浏览器渲染流程

五步渲染流程:

  1. 解析 HTML → 构建 DOM Tree
  2. 解析 CSS → 构建 CSSOM Tree
  3. 合并 DOM + CSSOM → 构建 Render Tree
  4. 布局(Layout):计算几何信息
  5. 绘制(Paint):绘制到屏幕

注意:JS 执行会阻塞解析(除非 async/defer)

重排(Reflow) vs 重绘(Repaint):

  • 重排:布局变化(宽高/位置)→ 触发重绘
  • 重绘:样式变化(颜色/背景)→ 不一定重排
  • 重排代价高:可能触发整个树重排

优化建议:

  • 避免频繁读写布局属性
  • 使用 transform 替代 top/left
  • 批量 DOM 操作(DocumentFragment)

GPU 加速触发条件:

  • transform: translateZ(0)
  • animation: opacity/transform
  • position: fixed
  • will-change: transform

注意:过度使用会导致内存溢出(合成层过多)

2. Service Worker 实战

注册流程:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(reg => console.log('注册成功'))
      .catch(err => console.error('注册失败', err));
  });
}

生命周期:

  • install → activate → 控制页面
  • activate 后才能控制页面
  • 更新后需关闭旧页面

缓存策略:

  • Cache-first:静态资源(图片/字体)
  • Network-first:动态数据(API)
  • Stale-while-revalidate:平衡方案
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then(cached => {
        if (cached) return cached;
        return fetch(event.request)
          .then(response => {
            caches.open('v1').then(cache => cache.put(event.request, response));
            return response.clone();
          });
      })
  );
});

PWA 核心要素:

  • HTTPS(必须)
  • manifest.json(应用元数据)
  • Service Worker(离线支持)
  • 图标尺寸(192/512px)

manifest.json 示例:

{
  "name": "前端面试网",
  "short_name": "前端面试",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#FDF0E0",
  "theme_color": "#d65e38",
  "icons": [
    { "src": "icon-192.png", "sizes": "192x192", "type": "image/png" }
  ]
}

3. HTTP 协议演进

HTTP/1.1 特点:

  • 持久连接(Connection: keep-alive)
  • 管道化(Pipelining,未普及)
  • 分块传输(Chunked)

瓶颈:队头阻塞(Head-of-Line Blocking)

HTTP/2 核心特性:

  • 二进制分帧(Binary Framing)
  • 多路复用(Multiplexing)
  • 头部压缩(HPACK)
  • 服务器推送(Server Push,已废弃)

问题:仍基于 TCP,队头阻塞

HTTP/3 核心变化:

  • 底层协议:QUIC(基于 UDP)
  • 0-RTT 连接建立
  • 连接迁移(手机切换 Wi-Fi/4G)

优势:解决 TCP 队头阻塞

高频问答(FAQ):网友最关心的10个问题

1. 前端开发需要掌握后端知识吗?

非必需,但强烈建议掌握基础。理解后端架构有助于:

  • 与后端高效协作(接口设计、错误处理)
  • 理解全链路性能瓶颈(网络/数据库)
  • 参与全栈开发(Node.js/云函数)

推荐学习路径:HTTP 基础 → RESTful API → Node.js 基础 → 数据库原理

2. 应该专注一个框架还是多学几个?

分阶段建议:

  • 入门期(0-6个月):精通一个主流框架(React/Vue)
  • 进阶期(6-24个月):掌握原理 + 了解其他框架
  • 专家期(24个月+):横向对比 + 技术选型能力

例如:React 开发者可学习 Vue 源码,理解响应式差异;再对比 Svelte 的编译时优化。

3. 面试如何展示项目经验?

STAR 原则 + 技术深度:

  • Situation:项目背景(用户量/技术挑战)
  • Task:你的职责(架构设计/性能优化)
  • Action:具体方案(代码片段 + 数据指标)
  • Result:量化结果(LCP↓40%、首屏↓2s)

✅ 正确示例:“通过代码分割 + 预加载,将 LCP 从 2.8s 降至 1.2s,转化率↑15%”

❌ 错误示例:“我做了性能优化”(无数据支撑)

4. 应届生如何弥补经验不足?

三步走策略:

  1. 开源贡献:修复小 bug(Good First Issue)
  2. 个人项目:从 0 到 1 完成(带技术文档)
  3. 深度复盘:技术博客(如“Vue3 响应式实现”)

加分项:提交 PR 被合并、技术文章获高赞

5. 35 岁危机如何应对?

提前布局技术深度与广度:

  • 纵向:成为领域专家(如浏览器内核/编译原理)
  • 横向:转向全栈/架构师/技术管理
  • 副业:技术咨询/培训/开源项目维护

关键:持续输出(技术博客/开源)建立个人品牌

6. 如何准备算法题?

按优先级训练:

  1. 高频题(Top 100):数组/链表/树/DFS/BFS
  2. 企业真题:LeetCode 公司题库
  3. 思维题:动态规划/贪心(非必考)

建议:每天 2 题 + 每周复盘,注重思路而非死记

7. 英语不好会影响前端发展吗?

基础英语即可,但需掌握:

  • 技术文档阅读(MDN/React/Vue 官网)
  • 错误信息定位(英文报错)
  • 基础术语(如 callback/promise)

建议:用 DeepL 翻译文档 + 看带中文字幕的英文视频

8. 面试时如何反问面试官?

提问体现深度与思考:

  • “团队当前的技术栈和演进计划?”
  • “前端在项目中的角色和决策权?”
  • “技术债的处理机制和优化空间?”

避免:“加班多吗?”“薪资多少?”(留到谈薪阶段)

9. 如何判断技术栈是否值得学习?

三维度评估:

维度 评估标准
生态 GitHub stars/ npm 下载量/社区活跃度
企业使用 招聘需求/大厂技术分享
个人匹配 是否符合职业规划
10. 面试失败后如何复盘?

结构化复盘模板:

  1. 记录所有问题(含未答出的)
  2. 标注知识薄弱点
  3. 制定改进计划(如“学习 Webpack 源码”)
  4. 3 天后重答所有问题

工具推荐:Notion 建立面试题库 + Anki 记忆卡

斌知网
蜀ICP备2026017620号-5