前端面试场景题(高频考点全解析)

在前端面试中,场景题和技术细节题占据核心地位,直接考察候选人的技术积累、问题解决能力和工程化思维。本文汇总了前端面试中高频出现的场景题与核心知识点,涵盖工程化、框架、浏览器、性能优化等多个维度,逐一拆解解析,助力高效备战面试。### 前端面试场景题高频考点全解析

JavaScript 核心考点
  • 事件循环与异步编程:宏任务、微任务、Promise 链式调用、async/await 实现原理
  • 闭包与作用域:变量提升、块级作用域、闭包的应用场景与内存泄漏
  • 原型与继承:原型链、ES6 Class 与原型继承的区别、手写 new 或 instanceof
  • 数据类型与类型转换:深拷贝/浅拷贝实现、隐式类型转换规则(如 =====
CSS 布局与渲染
  • 盒模型与布局:标准盒模型 vs IE 盒模型、BFC 触发条件与解决布局问题
  • Flex 与 Grid:常用属性、复杂布局的实现(如圣杯布局)
  • 响应式设计:媒体查询、REM/EM/VW 的应用场景与计算
  • 动画与性能:CSS3 动画优化、重绘与回流(Repaint & Reflow)
框架相关题目
  • React/Vue 生命周期对比:钩子函数执行顺序、组件更新触发条件
  • 虚拟 DOM 与 Diff 算法:Key 的作用、框架优化策略(如 React Fiber)
  • 状态管理:Redux/Vuex 核心流程、手写简易状态管理工具
  • 性能优化:组件懒加载、SSR 原理、长列表渲染方案
浏览器与网络
  • HTTP 相关:缓存策略(强缓存/协商缓存)、HTTPS 握手过程
  • 安全防护:XSS/CSRF 攻击原理与防御方案
  • 浏览器原理:从输入 URL 到页面渲染的完整流程
  • Web 性能优化:Lighthouse 指标、首屏加载优化手段
手写代码与算法
  • 高频手写题:防抖/节流、Promise.all/race、深拷贝、柯里化
  • 数据结构:数组去重、链表操作、二叉树遍历(递归与非递归)
  • 算法题:排序算法(快排、归并)、动态规划(如爬楼梯问题)
项目经验与设计题
  • 项目难点复盘:性能优化案例、技术选型依据
  • 系统设计题:设计一个前端埋点监控系统、实现拖拽排序组件
  • 开放性问题:前端工程化实践(如 Webpack 优化、CI/CD 流程)
综合能力考察
  • 代码调试:Chrome DevTools 高级用法(性能分析、内存快照)
  • 团队协作:Git 工作流、代码审查(Code Review)规范
  • 技术视野:PWA、WebAssembly、微前端等新技术的应用场景### 前端面试场景题高频考点全解析
JavaScript 核心考点
  • 事件循环与异步编程:宏任务、微任务、Promise 链式调用、async/await 实现原理
  • 闭包与作用域:变量提升、块级作用域、闭包的应用场景与内存泄漏
  • 原型与继承:原型链、ES6 Class 与原型继承的区别、手写 new 或 instanceof
  • 数据类型与类型转换:深拷贝/浅拷贝实现、隐式类型转换规则(如 =====
CSS 布局与渲染
  • 盒模型与布局:标准盒模型 vs IE 盒模型、BFC 触发条件与解决布局问题
  • Flex 与 Grid:常用属性、复杂布局的实现(如圣杯布局)
  • 响应式设计:媒体查询、REM/EM/VW 的应用场景与计算
  • 动画与性能:CSS3 动画优化、重绘与回流(Repaint & Reflow)
框架相关题目
  • React/Vue 生命周期对比:钩子函数执行顺序、组件更新触发条件
  • 虚拟 DOM 与 Diff 算法:Key 的作用、框架优化策略(如 React Fiber)
  • 状态管理:Redux/Vuex 核心流程、手写简易状态管理工具
  • 性能优化:组件懒加载、SSR 原理、长列表渲染方案
浏览器与网络
  • HTTP 相关:缓存策略(强缓存/协商缓存)、HTTPS 握手过程
  • 安全防护:XSS/CSRF 攻击原理与防御方案
  • 浏览器原理:从输入 URL 到页面渲染的完整流程
  • Web 性能优化:Lighthouse 指标、首屏加载优化手段
手写代码与算法
  • 高频手写题:防抖/节流、Promise.all/race、深拷贝、柯里化
  • 数据结构:数组去重、链表操作、二叉树遍历(递归与非递归)
  • 算法题:排序算法(快排、归并)、动态规划(如爬楼梯问题)
项目经验与设计题
  • 项目难点复盘:性能优化案例、技术选型依据
  • 系统设计题:设计一个前端埋点监控系统、实现拖拽排序组件
  • 开放性问题:前端工程化实践(如 Webpack 优化、CI/CD 流程)
综合能力考察
  • 代码调试:Chrome DevTools 高级用法(性能分析、内存快照)
  • 团队协作:Git 工作流、代码审查(Code Review)规范
  • 技术视野:PWA、WebAssembly、微前端等新技术的应用场景
    一、工程化与构建相关
  1. babel-runtime 作用是啥?
    核心作用是避免 Babel 转换代码时重复注入辅助函数,减少打包体积。
    Babel 转换 ES6+ 语法(如 class、箭头函数)时,需注入 _classCallCheck 等辅助函数。
    若不使用 babel-runtime,每个转换后的文件都会重复注入这些函数,导致冗余。
    babel-runtime 会将辅助函数集中管理,通过模块引入复用,同时避免污染全局作用域。
  2. 一般是怎么做代码重构的?
    重构核心是 “在不改变外部功能的前提下,优化代码结构、可读性和可维护性”,步骤如下:
    梳理现有代码逻辑,明确功能边界和依赖关系,做好单元测试(保障重构后功能正常)。
    拆分臃肿函数 / 组件,遵循单一职责原则,将重复逻辑提取为工具函数或公共组件。
    优化代码命名和注释,让逻辑更清晰,同时修复潜在隐患(如未处理的异常、不合理的判断)。
    逐步替换老旧语法 / 方案,兼容现有业务,重构后回归测试,确保无功能退化。
  3. 如何清理源码里面没有被应用的代码(JS、TS、CSS)?
    JS/TS:使用工具检测未引用代码,如 webpack-deep-scope-plugin 分析模块依赖,tree-shaking 自动剔除未使用的导出代码;手动排查注释中、废弃分支的死代码。
    CSS:借助 PurgeCSS、uncss 等工具,匹配 HTML/JS 中实际使用的选择器,删除未匹配的样式;避免全局样式冗余,采用模块化样式(如 CSS Modules)。
  4. package.json 里面 sideEffects 属性的作用是啥?
    用于告知 webpack 哪些文件具有 “副作用”,帮助 tree-shaking 更精准地剔除无用代码。
    副作用指文件执行时除了导出内容外的额外操作(如修改全局变量、样式注入)。
    配置 sideEffects: false 表示所有文件无副作用,webpack 可放心删除未引用文件;若部分文件有副作用,需指定文件路径(如 [“*.css”, “./src/utils/global.js”])。
  5. [webpack] 打包时 hash 码是如何生成的?
    hash 码用于实现静态资源缓存更新,生成规则与配置相关:
    项目级 hash:基于整个项目的构建结果生成,任何文件修改都会导致 hash 变化(如 hash: “[hash].js”)。
    chunkhash:基于单个 chunk(代码分割后的模块组)生成,仅对应 chunk 内文件修改时变化,适合多入口项目。
    contenthash:基于文件内容生成,仅文件自身内容修改时变化,是缓存优化的最优选择(如 CSS 抽离后的文件)。
  6. [webpack] 有哪些优化项目的手段?
    代码分割:通过 splitChunks 拆分公共依赖(如 react、vue)、路由懒加载(dynamic import)减少首屏体积。
    缓存优化:使用 contenthash、合理配置 cache-loader 缓存构建结果,提升二次构建速度。
    loader 优化:限制 loader 作用范围(include/exclude)、使用 thread-loader 并行处理 loader 任务。
    资源优化:图片压缩(image-webpack-loader)、字体文件按需加载、CSS 抽离与压缩(mini-css-extract-plugin)。
    Tree-shaking:开启 sideEffects 配置,剔除未使用代码,仅支持 ES 模块(ES Module)。
  7. [webpack] 如何打包运行时 chunk,且在项目工程中如何去加载这个运行时 chunk?
    运行时 chunk 包含 webpack 模块加载、chunk 解析的核心逻辑,默认会内嵌在入口 chunk 中。
    配置 optimization.runtimeChunk: ‘single’ 可将运行时逻辑单独打包为独立 chunk(如 runtime~main.js),避免入口 chunk 频繁变化。
    加载方式:webpack 自动生成脚本标签引入,或通过 import () 动态加载时,runtime chunk 会被优先加载,确保模块解析逻辑可用。
  8. 不使用脚手架,如何用 webpack 构建一个自己的 React 应用?
    初始化项目:npm init -y,安装核心依赖(webpack、webpack-cli、react、react-dom、@babel/core、babel-loader、@babel/preset-react、@babel/preset-env)。
    配置 webpack.config.js:设置入口(src/index.js)、出口(dist),配置 module.rules 让 babel 解析 JSX/ES6+ 语法。
    创建 HTML 模板(src/index.html),使用 html-webpack-plugin 注入打包后的 JS 文件。
    编写 React 入口文件(src/index.js):引入 React 和 ReactDOM,渲染根组件到页面 DOM 节点。
    配置 package.json 脚本:“build”: “webpack --mode production”、“dev”: “webpack serve --mode development”,启动开发服务或打包。
    二、框架相关(React/Vue)
  9. [React] 循环渲染中为什么推荐不用 index 做 key?
    key 是 React 标识列表节点唯一性的依据,用 index 会导致节点复用异常,引发状态错乱。
    若列表元素增删改查(如排序、删除中间元素),index 会重新排序,导致 React 误判 “节点已更新” 而非 “节点新增 / 删除”。
    推荐使用元素自身唯一标识(如 id、uuid)作为 key,确保节点与数据一一对应,避免不必要的重渲染和状态错误。
  10. [React] 如何避免使用 context 的时候,引起整个挂载节点树的重新渲染?
    拆分 context:将不同粒度的状态拆分到多个 context 中,避免单一 context 变化导致全树渲染。
    使用 memo 包装组件:通过 React.memo 浅比较 props,阻止未依赖 context 变化的组件重渲染。
    抽取 context 消费组件:将 context 消费逻辑抽离为独立组件,仅该组件受 context 变化影响,而非整个父组件树。
  11. [React] 如何避免不必要的渲染?
    函数组件:使用 React.memo 浅比较 props,useMemo 缓存计算结果,useCallback 缓存函数引用。
    类组件:使用 PureComponent(浅比较 props 和 state)或 shouldComponentUpdate 手动判断是否需要渲染。
    避免冗余状态:将不变的状态或计算属性抽离,避免因无关状态变化触发渲染。
  12. [React] 如何进行路由变化监听?
    使用 react-router-dom 的 useLocation 钩子(函数组件):通过 useEffect 监听 location 变化。
    jsx
    import { useLocation } from ‘react-router-dom’;
    const Demo = () => {
    const location = useLocation();
    useEffect(() => {
    console.log(‘路由变化:’, location.pathname);
    }, [location]);
    };
    类组件:使用 withRouter 高阶组件注入 history、location、match 属性,监听 history 变化。
  13. [Vue] 中为何不要把 v-if 和 v-for 同时用在同一个元素上,原理是什么?
    原理:Vue 模板编译时,v-for 优先级高于 v-if,会导致每次渲染都先循环再判断条件,即使部分元素无需渲染,也会执行循环,浪费性能。
    优化方案:将 v-if 移到父组件(控制是否渲染整个列表),或用 template 包裹 v-for(循环内部判断),或先通过计算属性过滤列表数据再渲染。
  14. [Vue] 中 Scoped Styles 是如何实现样式隔离的,原理是啥?
    原理:通过给组件 DOM 元素添加唯一 data 属性(如 data-v-xxx),并给样式选择器添加该属性前缀,使样式仅作用于当前组件的 DOM。
    编译后样式示例:.box [data-v-xxx] { color: red; },确保样式不会渗透到子组件或全局。
  15. [React] 如何实现专场动画?
    使用 react-transition-group 库:提供 CSSTransition、TransitionGroup 组件,支持进入、退出、切换动画。
    基于 CSS 的动画:通过条件渲染控制组件的 className,结合 CSS transition/animation 实现动画效果。
    高阶组件封装:将动画逻辑抽离为高阶组件,复用不同组件的动画效果。
    三、浏览器与网络相关
  16. 浏览器有同源策略,但是为何 CDN 请求资源的时候不会有跨域限制?
    同源策略限制的是 “客户端脚本(如 JS)对服务器响应数据的读取”,而非 “资源的加载”。
    CDN 资源(如 JS、CSS、图片)的加载属于 “被动资源获取”,浏览器允许跨域加载这些资源。
    跨域限制的核心是 “防止脚本窃取异源数据”,而 CDN 资源加载后仅用于渲染或执行,不会让脚本主动读取异源服务器的敏感数据,因此不受限制。
  17. cookie 可以实现不同域共享吗?
    默认不可以,cookie 遵循 “同源策略”,仅能在设置它的域名及其子域名下访问。
    特殊场景:通过设置 cookie 的 domain 属性为父域名(如 domain: “.example.com”),可实现子域名(a.example.com、b.example.com)共享 cookie。
    不同顶级域名(如 example.com 和 test.com)无法直接共享 cookie,需通过后端接口中转(如单点登录场景)。
  18. axios 是否可以取消请求?
    可以,通过 Axios 提供的 CancelToken 或 AbortController 实现。
    CancelToken 方式(Axios v0.x):
    js
    const CancelToken = axios.CancelToken;
    const source = CancelToken.source();
    axios.get(‘/api/data’, { cancelToken: source.token }).catch(err => {
    if (axios.isCancel(err)) console.log(‘请求被取消:’, err.message);
    });
    source.cancel(‘手动取消请求’);
    AbortController 方式(Axios v0.22.0+,推荐):
    js
    const controller = new AbortController();
    axios.get(‘/api/data’, { signal: controller.signal });
    controller.abort(); // 取消请求
  19. DNS 协议了解多少?
    DNS(域名系统)核心作用:将域名(如 www.baidu.com)解析为 IP 地址,实现网络通信。
    解析流程:本地 DNS 缓存 → 本地 DNS 服务器 → 根 DNS 服务器 → 顶级域名服务器 → 目标域名服务器,最终返回 IP 地址。
    优化方式:DNS 预解析(link 标签 rel=“dns-prefetch”)、HTTPDNS(跳过本地 DNS 污染,直接向目标 DNS 服务器解析)。
  20. HTTP 是一个无状态的协议,那么 Web 应用要怎么保持用户的登录态呢?
    通过以下方式弥补 HTTP 无状态特性,维持登录态:
    Cookie + Session:客户端登录后,服务器生成 Session 存储用户信息,返回 SessionID 到客户端 Cookie,后续请求携带 Cookie 验证身份。
    Token 认证:服务器生成 Token(如 JWT)返回客户端,客户端存储在 localStorage/sessionStorage,后续请求通过 Header(如 Authorization: Bearer Token)携带验证。
    第三方登录(OAuth2.0):通过微信、QQ 等第三方平台授权,获取 Token 维持登录态。
  21. 浏览器对队头阻塞有什么优化?
    队头阻塞(Head-of-Line Blocking)指同一连接中,前一个请求未完成时,后续请求需排队等待。
    HTTP/1.1 优化:管线化(Pipelining)允许同时发送多个请求,但需按顺序响应,优化有限;增加并发连接(浏览器默认对同一域名开启 6 个 TCP 连接)。
    HTTP/2 优化:采用多路复用(Multiplexing),通过帧和流机制,多个请求在同一 TCP 连接中并行传输,彻底解决队头阻塞。
    HTTP/3 优化:基于 QUIC 协议(UDP 封装),进一步优化连接建立速度和多路复用效率。
  22. JS 放在 head 里和放在 body 里有什么区别?
    head 中:JS 会阻塞 HTML 解析和页面渲染,需等待 JS 下载并执行完成后,才继续解析 HTML。若 JS 无异步加载(async/defer),会导致页面白屏。
    body 末尾:JS 不会阻塞 HTML 解析,页面可先渲染完成,提升首屏加载体验。推荐将 JS 放在 body 末尾,或使用 async/defer 异步加载。
    补充:async 表示 JS 下载完成后立即执行(顺序不确定);defer 表示 JS 下载完成后,等待 HTML 解析完成再执行(顺序与引入顺序一致)。
  23. 前端有哪些跨页面通信方式?
    同源页面:localStorage/sessionStorage(监听 storage 事件)、Cookie(通过后端中转)、Broadcast Channel API(专门用于跨页面通信)。
    异源页面:iframe 通信(postMessage 方法)、共享服务 worker、URL 参数传递(适用于简单数据)。
    全局通信:WebSocket 连接(通过后端转发消息)、IndexedDB(共享数据库)。
    四、性能优化相关
  24. 页面加载速度提升(性能优化)应该从哪些方向来思考?
    资源优化:压缩 JS/CSS/ 图片,使用 CDN 分发静态资源,开启 Gzip/Brotli 压缩。
    加载优化:首屏资源按需加载(路由懒加载、图片懒加载),预加载关键资源(preload/prefetch),减少 HTTP 请求数(合并资源、Sprite 图)。
    渲染优化:避免 CSS 阻塞渲染(精简关键 CSS 并内联),避免 JS 阻塞解析(async/defer),减少回流重绘(避免频繁操作 DOM、使用 will-change)。
    缓存优化:合理设置 HTTP 缓存头(Cache-Control、ETag),利用 localStorage 缓存静态数据。
  25. SPA 首屏加载速度慢的怎么解决?
    资源体积优化:代码分割、Tree-shaking 剔除无用代码,压缩混淆 JS/CSS,图片懒加载。
    渲染优化:服务端渲染(SSR)或静态站点生成(SSG),提前生成 HTML 内容;预渲染关键页面,减少客户端渲染时间。
    缓存与分发:静态资源 CDN 分发,开启 HTTP 缓存,使用 Service Worker 实现离线缓存。
    减少请求数:合并接口请求,内联关键 CSS/JS,避免首屏加载不必要的第三方库。
  26. 当 QPS 达到峰值时,该如何处理?
    前端优化:接口节流防抖,合并重复请求,本地缓存热点数据,减少非必要请求。
    后端优化:接口限流(如令牌桶、漏桶算法),服务集群扩容,数据库读写分离、分库分表。
    缓存策略:增加 Redis 缓存热点数据,减少数据库查询压力;CDN 缓存静态资源,分流访问压力。
  27. 如何解决页面请求接口大规模并发问题?
    接口合并:将多个独立接口合并为一个批量接口,减少 HTTP 请求数。
    分批请求:将大规模并发请求拆分为多个批次(如每批 10 个),分批发送,避免一次性占用过多浏览器连接。
    限流控制:使用 Promise.allSettled 控制并发数,或通过队列管理请求顺序,避免服务器压力过大。
    缓存复用:对于重复请求,返回缓存结果,避免重复发送。
  28. 常见图片懒加载方式有哪些?
    原生方式:使用 img 标签的 loading=“lazy” 属性,浏览器原生支持,无需额外 JS。
    自定义实现:监听 scroll 事件或使用 IntersectionObserver API,判断图片是否进入可视区域,若进入则设置 src 或 data-src 属性加载图片。
    框架组件:使用 React-Lazyload、vue-lazyload 等第三方组件,封装懒加载逻辑。
  29. web 系统里面,如何对图片进行优化?
    格式优化:根据场景选择图片格式(WebP/AVIF 比 JPG/PNG 体积小 30%+,图标使用 SVG)。
    尺寸优化:生成多尺寸图片,通过 srcset 和 sizes 属性适配不同设备,避免大图片在小屏幕上加载。
    压缩优化:使用工具(如 TinyPNG)压缩图片,去除冗余元数据,平衡体积和清晰度。
    加载优化:图片懒加载、预加载关键图片,使用 CDN 分发图片。
  30. 如何一次性渲染十万条数据还能保证页面不卡顿?
    核心思路是 “分批次渲染”,避免一次性操作大量 DOM:
    虚拟滚动:仅渲染可视区域内的数据,滚动时动态替换 DOM 内容(如 react-virtualized 库)。
    分批渲染:使用 requestIdleCallback 或 setTimeout 分批次创建 DOM 节点(如每批 100 条),利用浏览器空闲时间渲染,避免阻塞主线程。
    数据分页:将十万条数据分页,每页渲染 20-50 条,通过分页控件切换数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小百科

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值