1.如何判断用户设备
- 浏览器API——
User-Agent 检测 优先CSS媒体查询,JS作为补充
2.将多次提交压缩成一次提交
简单场景:使用防抖函数延迟执行,确保连续操作只触发一次复杂场景:实现请求批量处理器,收集一段时间内的所有请求,合并发送到支持批量处理的API接口关键考虑:需要处理请求和响应的对应关系、错误处理、优先级控制,并设置合理的等待时间和批量大小结合使用:在实际项目中,通常会结合防抖(控制频率)、批量(减少请求数)和缓存(避免重复请求)来综合优化”
3.介绍下navigator.sendBeacon方法
4.混动跟随导航(电梯导航)该如何实现
5.退出浏览器之前,发送积压的埋点数据请求,该如何做?
6.如何统计页面的long task(长任务)
7.PerfoemanceObserver如何测量页面性能
PerformanceObserver 是现代浏览器提供的性能监控API
核心使用四步:
- 创建
new PerformanceObserver(callback) - 配置观察类型
observer.observe({entryTypes: [...]}) - 在回调中处理
list.getEntries() - 结束时
observer.disconnect()
主要监控场景:
- Web Vitals:LCP、FID、CLS 核心用户体验指标
- 资源加载:监控慢资源,优化加载性能
- 绘制时间:FP、FCP,了解页面渲染进度
- 长任务:发现阻塞主线程的代码
8.移动端如何实现下拉滚动加载(顶部加载)
9.判断页签是否为活跃状态
10.在网络带宽一定的情况下,切片上传感觉和整体上传消费的时间应该是差不多的这种说法正确吗?
11.大文件切片上传的时候,确定切片数量的时候,有那些考量因素
12.页面关闭时执行方法,该如何做
13.如何统计用户 pv 访问的发起请求数量
14.长文本溢出,展开/收起如何实现
基础层:使用-webkit-line-clamp实现多行省略,max-height控制显示高度交互层:通过JS动态计算文本高度,决定是否显示展开按钮动画层:利用CSStransition实现平滑展开收起效果优化层:考虑按钮精确定位、防抖处理、虚拟滚动等优化手段
15.如何实现鼠标拖拽
事件处理:通过mousedown、mousemove、mouseup事件链实现,注意事件绑定在 document 上确保鼠标移出元素外也能继续拖拽坐标计算:计算鼠标移动的 delta 值,应用 transform 或 left/top 实现位置更新性能优化:使用transform利用 GPU 加速,requestAnimationFrame节流事件,减少重排重绘用户体验:添加拖拽状态样式,支持边界限制、网格对齐、拖拽排序等高级功能兼容性:同时支持鼠标和触摸事件,处理移动端特殊行为"
16.统计全站每一个静态资源加载耗时,该如何做
前端性能指标
First Paint(FP)——》从输入url到开始渲染,第一次渲染页面触发First Contentful Paint(FCP)——》第一次有内容的渲染,比如开始第一次渲染文字,图片等等DomContentLoaded(DCL)——》页面DOM内容加载完毕,html文档被解析加载完成触发Largest Contentful Paint(LCP)——》页面最大的内容渲染完成Load(L)——〉页面所有资源下载完成触发
优化建议
缓存策略:分析缓存命中率,优化缓存配置CDN优化:分析不同CDN节点的性能差异资源合并:分析是否可以通过合并减少请求数预加载:识别关键资源进行预加载懒加载:分析非首屏资源,实现懒加载
17.防止前端页面重复请求
交互层:通过按钮禁用和加载状态给用户明确反馈控制层:使用防抖节流控制请求频率,实现请求锁机制网络层:利用 AbortController 或拦截器取消重复请求缓存层:对 GET 请求合理缓存,减少重复调用架构层:封装统一的请求管理器,结合路由生命周期管理
18.ResizeObserver作用是什么
ResizeObserver 是一个现代浏览器 API,用于监听 DOM 元素的尺寸变化
典型应用场景包括:响应式组件、图表自适应、虚拟列表、动态布局等。使用时要注意及时清理观察者,避免内存泄漏。
19.要实时统计用户浏览器窗口大小,该如何做
20.当项目报错,你想定位是哪个commit引l入的错误的时,该怎么做
21.如何移除一个指定的 commit
22.如何还原用户操作流程
23.可有办法将请求的调用源码地址包括代码行数也上报上去?
24.请求失败会弹出一个 toast,如何保证批量请求失败,只弹出一个 toast
25.如何减少项目里面 if-else
26.babel-runtime 作用是啥
27.如何实现预览 PDF 文件
window.open
28.如何在划词选择的文本上添加右键菜单(划词:标滑动选择一组字符,对组字符进行操作)【热度:100】
29.富文本里面,是如何做到划词的(鼠标滑动选择一组字符,对组字符进行操作)?
30,如何做好前端监控方案
31.如何标准化处理线上用户反馈的问题
32.px 如何转为 rem
33.浏览器有同源策略,但是为何 cdn 请求资源的时候不会有跨域限制
CDN资源不受跨域限制,主要有两个原因:
第一,大多数CDN使用同源域名或配置了CORS
- 企业CDN通常使用子域名:
cdn.your-site.com - 浏览器认为子域名与主站同源(协议、端口相同)
- 第三方公共CDN(如unpkg、jsDelivr)配置了
Access-Control-Allow-Origin: *
第二,HTML标签的天然跨域能力
<script>、<img>、<link>标签天生允许跨域加载资源- 但通过JavaScript(fetch/XHR)加载这些资源仍受CORS限制
34.cookie 可以实现不同域共享吗
35.axios 是否可以取消请求
如何创建和使用CancelToken
- 创建CancelToken:
使用axios.CancelToken.source()方法可以创建一个取消源(cancel source),它包含一个token用于之后的取消操作和一个cancel方法来实际取消请求。 - 发起请求时传递CancelToken:
在发起请求时,将CancelToken对象作为配置项传递。 - 取消请求
当需要取消请求时,调用之前创建的
cancel方法。
36.前端如何实现折叠面板效果?
37.dom 里面,如何判定a元素是否是b元素的子元素
38.判断一个对象是否为空,包含了其原型链上是否有自定义数据或者方法。 该如何判定?
39.js如何判空?「空」包含了:空数组、空对象、空字符串、0、undefined、null、空 map、空 set,都厘于为空的数据
40.css 实现翻牌效果
41.flex:1和flex: auto代表什么
flex: 1和flex: auto的主要区别在于空间分配的基准不同:
flex: 1(等价于flex: 1 1 0%):
- 基准大小为0%,所有项目从同一起跑线开始
- 等分剩余空间,忽略内容大小
- 适用场景:等分布局,如导航菜单、等分卡片
flex: auto(等价于flex: 1 1 auto):
- 基准大小为
auto,即内容本身的尺寸 - 先给内容分配空间,再按内容比例分配剩余空间
- 适用场景:自适应布局,如搜索框、聊天消息
实际选择:
- 要等宽效果:用
flex: 1 - 要内容自适应:用
flex: auto - 要固定宽度:用
flex: none或width
42.一般是怎么做代码重构的
43.如何清理源码里面没有被应用的代码,主要是 JS、TS.CSS 代码
44.前端应用 如何做国际化?
45.应用如何做应用灰度发布
46.「微前端]为何通常在 微前端 应用隔离,不选择 iframe 方案
47.[微前端] Qiankun 是如何做 JS 隔离的
48.[微前端]微前端架构一般是如何做 JavaScript隔离
49.[React]循环渲染中 为什么推荐不用 index 做 key
50.[React]如何避免使用 context 的时候,引起整个挂载节点树的重新浪染
51.前端如何实现截图?
52.当QPS达到峰值时,该如何处理?
53.js 超过 Number 最大值的数怎么处理?
54.使用同一个链接, 如何实现 PC 打开是 web 应用、手机打开是-个 H5 应用?
55.如何保证用户的使用体验
56.如何解决页面请求接口大规模并发问题
57.设计一套全站请求耗时统计工具
58.大文件上传了解多少
大文件上传的核心是分片上传 + 断点续传 + 秒传检测。
实现流程:
- 前端将大文件切成多个小分片
- 计算文件hash用于秒传检测和完整性校验
- 并发上传分片(控制并发数避免服务器压力)
- 记录上传状态,支持暂停和断点续传
- 所有分片上传完成后,服务端合并验证
59.H5 如何解决移动端适配问题
基础设置
viewport设置设备宽度和缩放比例- 禁用用户缩放(根据需求)
- 设置安全区域(iPhone X+)
布局适配(三选一)
- REM方案:通过JS动态计算根font-size,CSS使用rem单位
- VW方案:直接使用视口单位,纯CSS实现
- 媒体查询:断点式适配,适合简单页面
60.站点一键换肤的实现方式有哪些?
CSS变量方案(现代方案):通过修改根元素的CSS变量值,实现实时主题切换,性能好但需要现代浏览器支持。类名切换方案(经典方案):为不同主题预定义CSS类,切换时修改根元素类名,兼容性好,适合大多数项目。多CSS文件方案(企业方案):构建时生成多套CSS,运行时动态加载,适合复杂的主题系统。
61.如何实现网页加载进度条?
是伪进度条:视觉上模拟进度,快速到80%然后等待完成,实现简单但不够真实。是基于真实进度的:通过监听资源加载、标记关键节点或使用Performance API,能真实反映加载情况。是框架集成方案:在React/Vue等框架中,结合路由和组件加载状态显示进度。
62.常见图片懒加载方式有哪些?
63.cookie 构成部分有哪些
64.扫码登录实现方式
"扫码登录的核心是二维码承载临时令牌,手机App确认身份后完成登录。
具体实现:
网页端生成带token的二维码,轮询或WebSocket等待结果手机App扫码后向服务器确认身份服务器验证token,绑定用户,通知网页端网页端收到通知后完成登录
65.DNS协议了解多少
66.函数式编程了解多少?
67.前端水印了解多少?
68.什么是领域模型
69.一直在 window 上面挂东西是否有什么风险
命名冲突风险:多个库或模块都往window上挂属性,容易发生覆盖。比如早期jQuery和Prototype.js的$冲突,或者广告SDK和业务代码的全局变量冲突。安全风险:敏感数据(如token、API密钥)暴露在全局,容易被XSS攻击窃取。全局变量也容易被恶意篡改。维护困难:代码耦合度高,难以追踪来源。全局状态管理混乱,调试困难。性能问题:全局变量查找慢,可能影响性能。还可能导致内存泄漏。
70.深度 SEO 优化的方式有哪些,从技术层面来说
71.小程序为什么会有两个线程
72.web 应用中如何对静态资源加载失败的场景做降级处理
73.html 中前缀为 data- 开头的元素厘性是什么?
HTML中 data-* 开头的属性是HTML5引入的自定义数据属性。
它的主要作用是在HTML元素上存储私有自定义数据,这些数据不会影响页面渲染,但可以通过JavaScript进行读写。
- CSS中也可以通过
attr()函数使用data属性 - 与
MutationObserver结合监控变化
74.移动端如何实现上拉加载,下拉刷新?
75.如何判断dom元素是否在可视区域
通过检测元素相对于浏览器视口的位置关系,来判断元素当前是否被用户看到。
简单场景:使用 getBoundingClientRect() 获取元素位置,与视口尺寸比较,可以判断完全可见或部分可见。
生产环境:推荐使用 IntersectionObserver API,它性能更好,支持阈值检测、容器内检测等高级功能,还能自动监听滚动和尺寸变化。
76.前端如何用 canvas 来做电影院选票功能
77.如何通过设置失效时间清除本地存储的数据?
78.如果不使用脚手架,如果用 webpack 构建一个自己的 react应用
79.用 nodejs 实现一个命令行工具,统计输入目录下面指定代码的行数
80.package,json 里面 sideEffects 厘性的作用是啥
81.script 标签上有那些厘性,分别作用是啥?
82.为什么 SPA 应用都会提供一个 hash 路由,好处是什么?
83.[React]如何进行路由变化监听
使用react-router-dom
对于Web应用,react-router-dom是最常用的库。你可以使用useLocation钩子或者useHistory钩子来监听路由变化。
84.单点登录是是什么, 具体流程是什么
单点登录(Single Sign-On, SSO) 是一种身份验证方案,允许用户使用一组凭证(用户名/密码)登录多个相互信任的应用系统,而无需在每个系统中单独登录。
85.web 网页如何禁止别人移除水印
86.用户访问页面白屏了,原因是啥,如何排查?
快速诊断:打开DevTools,先看Console有无红色错误,再看Network面板资源加载状态资源检查:确认JS/CSS等关键资源是否加载成功,检查HTTP状态码和CORS问题执行排查:如果有JS错误,分析堆栈跟踪,检查变量定义和异步操作渲染检查:确认DOM是否正常渲染,检查CSS加载和布局问题环境验证:检查浏览器兼容性、网络状态和第三方依赖
87.JS中如何实现大对象深度对比
88.如何理解数据驱动视图,有哪些核心要素?
89.图片懒加载组件
技术实现:IntersectionObserver监听元素进入视口性能优化:占位图、加载动画、错误重试、图片预加载用户体验:加载状态提示、渐进式加载、骨架屏兼容性:IntersectionObserver降级方案(scroll监听)扩展性:支持不同图片格式、响应式图片
90.如果用户反馈页面首次加载很慢,你会如何排查和优化?
排查步骤:
- Chrome DevTools - Network查看资源加载
- Lighthouse性能分析
- Webpack Bundle Analyzer分析包大小
- Performance面板记录性能时间线
前端性能指标:
- First Paint(FP)——》从输入url到开始渲染,第一次渲染页面触发
- First Contentful Paint(FCP)——》第一次有内容的渲染,比如开始第一次渲染文字,图片等等
- DomContentLoaded (DCL)——》页面DOM内容加载完毕,html文档被解析加载完成触发
- Largest Contentful Paint (LCP)——》页面最大的内容渲染完成
- Load (L)——〉页面所有资源下载完成触发
优化方案:
代码分割:路由懒加载、组件懒加载资源优化:图片压缩、CDN、HTTP/2缓存策略:强缓存、协商缓存预加载:preload关键资源、prefetch未来可能资源服务端:SSR、边缘计算
91.组件封装
在组件封装时,我会严格区分基础组件和业务组件
基础组件的侧重点是:
- 技术通用性:像乐高积木,可以在任何项目中使用
- 功能纯粹性:一个组件只解决一个技术问题
- 性能最优化:体积小、渲染快、无副作用
- 体验标准化:符合WCAG可访问性标准
业务组件的侧重点是:
- 业务完整性:完整封装一个业务场景的所有逻辑
- 配置灵活性:通过props适应不同业务需求
- 用户体验:符合用户操作习惯和业务流程
- 可维护性:易于跟随业务变化而迭代
实践方法:
- 先设计基础组件:建立稳定的技术基础设施
- 再组合业务组件:用基础组件搭建业务功能
- 明确边界和职责:基础组件不包含业务逻辑,业务组件不重复实现基础功能
- 建立文档和规范:确保团队协作效率
92.如果后端一次性返回10w条数据,前端怎么处理?
-
首先和后端沟通,看是否能改为分页接口或流式传输,这是最根本的解决方案。
-
虚拟列表 (Virtual List)
核心原理:仅创建和渲染可视区域及其附近的列表项,通过绝对定位模拟完整滚动条。关键技术:滚动监听、位置计算、transform定位、动态高度处理(难点)。适用场景:精确滚动的长列表(如表格、聊天记录、联系人列表)。适用场景:滚动流畅,体验如同原生列表。
-
增量渲染 (Incremental Rendering)
核心原理:将整个列表的渲染任务拆分成多个小块,在浏览器空闲时段分批渲染。关键技术:requestAnimationFrame,setTimeout或任务分片(Time Slicing)。适用场景:初始加载体验优先的超长列表(如日志文件、一次性渲染数万条数据)。用户体验:逐步加载,避免页面长时间无响应,但快速滚动可能看到空白。
-
现成实现方案
无需重复造轮子,优先使用成熟库
- Vue 生态:vue-virtual-scroller
- React 生态:react-window,react-virtualized
- 通用方案:各大 UI 组件库(如 Ant Design, Element Plus)的虚拟滚动表格/列表组件。
93.讲一下单页应用与多页应用、SSR/CSR/SSG 的权衡与迁移。
SPA (Single-Page Application) vs MPA (Multi-Page Application)
-
MPA (多页应用)
-
工作方式:传统的网站模式。每次页面跳转(点击链接),浏览器都会向服务器发送一个全新的请求,服务器返回一个完整的 HTML 文件,浏览器重新加载整个页面。
-
优点:
- 首屏加载快:每个页面只加载自身所需的资源。
- SEO 友好:每个页面都有独立的 URL 和完整的 HTML 内容,非常利于搜索引擎爬取。
- 架构简单,易于理解和维护。
-
缺点:
- 页面切换体验差:每次跳转都会有“白屏”等待时间,缺乏流畅的“应用感”。
- 状态管理复杂:跨页面共享数据困难。
-
-
SPA (单页应用)
-
工作方式:整个应用只有一个主 HTML 文件。首次加载时,会下载所有必要的 HTML, CSS, JS。后续的页面导航,实际上是通过 JavaScript 动态地、局部地更新页面内容,并使用History API来管理浏览器 URL,而不重新请求整个页面。
-
优点:
- 用户体验极佳:页面切换流畅、快速,没有白屏,提供了接近原生应用的体验。
- 组件化:非常适合现代前端框架(React, Vue, Angular)的组件化开发模式。
- 前后端分离:职责清晰,后端专注于提供 API。
-
缺点:
- 首屏加载慢:需要一次性加载较大的 JS 文件,导致首次渲染时间(FCP/LCP)较长。
- SEO 难度大:初始返回的 HTML 文件通常是一个空的div容器,爬虫难以抓取到由 JS 渲染出的最终内容(尽管现在 Google 爬虫对 JS 的处理能力有所提升,但仍不完美)。
-
2. 渲染模式的权衡:CSR, SSR, SSG
这些渲染模式主要是在 SPA 的背景下,为了解决其首屏慢和 SEO 差的问题而演进出来的。
-
CSR (Client-Side Rendering) - 客户端渲染
- 过程:浏览器下载一个近乎空白的 HTML 和一个巨大的 JS bundle -> 浏览器执行 JS -> JS 请求 API 获取数据 -> JS 根据数据渲染出页面内容。
- 优点:开发简单,服务器压力小(只需提供静态文件和 API)。
- 缺点:首屏白屏时间长、SEO 极差。这是“纯粹的”SPA 的默认渲染模式。
-
SSR (Server-Side Rendering) - 服务端渲染
-
过程:用户请求页面 -> Node.js 服务器接收请求 -> 服务器请求 API 获取数据 -> 在服务器端将组件渲染成完整的 HTML 字符串 -> 将 HTML 和少量用于“激活”(Hydration) 的 JS 一起返回给浏览器 -> 浏览器直接显示 HTML 内容,然后 JS 执行并接管页面交互。
-
优点:
- 首屏加载极快:用户能立刻看到有内容的页面。
- SEO 完美:返回给爬虫的是完整的 HTML。
-
缺点:
- 服务器压力大:每个请求都需要在服务器上实时渲染。
- 架构更复杂:需要维护一个 Node.js 服务,且需要处理好服务端和客户端的环境差异(所谓的“同构”开发)。
-
-
SSG (Static Site Generation) - 静态站点生成
-
过程:在构建时 (build time) ,预先获取所有需要的数据,为每一个页面都生成一个对应的、完整的 HTML 文件 -> 将这些 HTML 文件和静态资源部署到 CDN。
-
优点:
- 性能极致:用户直接从最近的 CDN 节点获取静态 HTML,加载速度无与伦比。
- SEO 完美。
- 服务器成本极低,甚至无需服务器(只需静态托管服务)。
-
缺点:
- 内容更新不及时:每次数据变更,都需要重新构建和部署整个网站。
- 不适用于高度动态、个性化的内容(如用户个人中心)。
-
94.公司需要建立一套自己的前端组件库,你会如何设计架构?
考察点: Monorepo、规范化、按需引入、文档自动化。
解决方案:
- 仓库管理: 采用 Monorepo 架构(推荐 pnpm workspaces + Turborepo),便于管理多个包和示例代码。
- 构建工具: 使用 Vite 或 Rollup,支持输出 ESM 和 UMD 格式,确保支持 Tree Shaking。
- 样式方案: 考虑 CSS 变量(CSS Variables)以支持主题定制,使用 Tailwind CSS 或 CSS Modules 避免样式冲突。
- 按需引入: 通过插件(如 babel-plugin-import)或让用户直接从子目录引入,确保打包体积最小。
- 质量保证: 引入 Storybook 进行交互式文档开发,并使用 Jest/Cypress 进行单元测试和 E2E 测试。
95.如何配置前端代码规范与自动化检查?
- 代码格式化:Prettier。
- 逻辑校验:ESLint (配合特定框架插件如 eslint-plugin-vue )o
- 提交规范: 使用 Husky 拦截 Git 钩子,结合 lint-staged 只校验暂存区文件,使用commitlint 强制要求提交信息符合 feat: xxx 格式。
96.如何进行权限控制?
前端权限控制通常分三层:1) 路由层用动态路由+守卫控制页面访问;2) 视图层用权限组件/指令控制按钮显示;3) 请求层用拦截器添加token和处理403。权限数据从接口获取,存到全局状态,遵循RBAC模型。
前端权限控制系统包含四个核心模块:
- 认证模块:处理登录/登出,管理token和用户信息
- 权限数据模块:存储用户角色和权限列表,提供校验函数
- 路由控制模块:
- 登录拦截:未登录跳转登录页
- 权限路由:动态生成可访问路由表
- 路由守卫:进入页面前校验权限
- 视图控制模块:
- 权限组件:
<Permission required="user:delete"> - 自定义指令:
v-permission="'edit'" - Hooks:
const { hasPermission } = usePermission()
- 权限组件:
关键实现点:
- 权限编码规范:
模块:操作,如user:delete - 动态路由:根据权限过滤路由表
- 请求拦截:自动添加token,统一处理403
- 持久化:token存localStorage,页面刷新后重新获取权限数据