整理
🚀 性能优化
- 如何做性能优化?(如何做首屏优化)
- 性能优化的三个指标分别是哪三个?
- FCP是什么?如何做FCP优化?
- Vue项目刚打开页面时出现白屏,怎么优化?
- 哪些CSS会影响重排和重绘?
- 后端返回了一个十万的数据量要显示在前端,如果做优化?
- 虚拟滚动列表的原理是什么?
- 防抖和节流的区别、应用场景、实现代码?
- 影响性能的问题有哪些?
🟢 Vue
- Vue2 和 Vue3 的区别?
- defineProperty和Proxy的区别
- 组件间的通信有哪些?
- vue3 diff算法做了哪些优化?
- vue3 的 setup是在什么生命周期?
- data定义一个对象为什么用一个函数来返回一个对象?
- v-for循环为什么要添加key?
- watch和computed的区别?
- vue3生命周期有哪些?
- 父组件嵌套子组件,父子组件的生命周期执行顺序是怎样?
- vue3怎么调用子组件的方法?
- 使用虚拟DOM有什么好处?
- vue中nextTick有什么作用?
- ref和reactive的区别?
- proxy怎么实现响应式?
📜 JavaScript
- 事件循环是什么?
- 微任务和宏任务有哪些?
- ES6有哪些新特性?
- JS数据类型有哪些?
- Map和Object有什么区别?WeakMap 和Map有什么区别?
- 说说原型链
- new操作符做了哪些工作?
- 垃圾回收机制工作原理
- 说说对 promise 的了解?
- 前端有一个大量的计算需要处理,造成页面卡顿,如何优化?
- require和import有什么区别?
- 什么是闭包?在什么时候用?
🔷 TypeScript
- type和interface有什么区别?
- 泛型是什么?
- 联合类型是什么?
- 类型里面的问号和感叹号有什么作用?
- vue3项目里面,TS类型推断不出来,如何解决?
🎨 CSS
- css隐藏元素有哪些方法?
- css伪元素、伪类有哪些?
🛠 项目难点亮点
- Monorepo相关问题
- 大文件分片上传相关问题
- 大数据处理和性能优化相关问题
📦 前端工程化(前端架构)
- webpack和vite的区别?
- vite的配置有哪些?
- pnpm和yarn、npm的区别?
- eslint 配置有哪些?版本8和9有什么区别?
🌐 HTTP和通信
- 从浏览器地址栏输入网址回车后到看到页面经过了哪些流程?
- 强缓存和协商缓存的区别?
- 如何做实时通信?
- 语音通话用什么协议?
- http常见的状态码有哪些?分别代表什么?
- 前端怎么接收服务端推送?有哪些方法?
- https和http的区别?为什么说https安全性更高?
🔍 SEO
- 如何做SEO优化?
- 页面里怎么让爬虫忽略一些链接?
🛡 安全
- XSS和CSRF是什么?如何防御?
🔗 其它
- 页面上通过iframe嵌套了一个第三方页面,如何进行通信?
- CDN具体是怎么实现的?
- qiankun怎么用,比如有哪些方法等等?
- 不同项目使用不同版本的公司组件库,怎么去做区分管理?
- 单页面应用和多页面应用的区别?
- uniapp有哪些生命周期?
📄 针对简历的提问
- 做了哪些公共组件?
🖊️ 手写代码
- 手写防抖函数
- 手写节流函数
- 手写Promise
🚀 性能优化
如何做性能优化?(如何做首屏优化)
- 代码分割(路由懒加载)
- 图片懒加载、压缩、WebP 格式
- 使用 CDN 加速静态资源
- 开启 Gzip 压缩
- 减少 HTTP 请求(合并文件、雪碧图、字体图标)
- 使用缓存(强缓存、协商缓存)
- SSR 服务端渲染(如 Nuxt.js)
- 预加载(
<link rel="preload">)、预渲染
性能优化的三个指标分别是哪三个?
- LCP:最大内容绘制(加载性能)
- FID:首次输入延迟(交互性)
- CLS:累计布局偏移(视觉稳定性)
FCP:首个文本或图片绘制
FCP是什么?如何做FCP优化?
+ **FCP**:首次内容绘制,测量用户看到内容的时间。 + 优化方法: - 减少阻塞渲染的CSS/JS - 使用内联关键CSS - 使用CDN - 缓存静态资源 - 压缩图片,使用webp - 服务器响应时间优化 - 使用预加载Vue项目刚打开页面时出现白屏,怎么优化?
+ 路由懒加载 + 使用SSR(如Nuxt.js) + 压缩代码,移除未使用的代码 + 使用Loading组件或骨架屏哪些CSS会影响重排和重绘?
+ 重排:改变几何属性(width、height、margin、padding、border、border-width) + 重绘:改变颜色、背景、visibility等 + 优化:使用`transform`、`opacity`,避免频繁操作样式后端返回了一个十万的数据量要显示在前端,如果做优化?
+ 虚拟滚动(如vue-virtual-scroller) + 分页加载 + 使用Web Worker处理数据 + 前端缓存 + 搜索过滤虚拟滚动列表的原理是什么?
只渲染可视区域内的元素,通过动态计算位置和高度,减少DOM节点数量。防抖和节流的区别、应用场景、实现代码?
+ **防抖**:连续触发只执行最后一次(如搜索输入) + **节流**:每隔一段时间执行一次(如滚动事件、窗口调整、鼠标移动事件)javascript
// 防抖
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流
function throttle(fn, delay) {
let flag = true;
return function (...args) {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, args);
flag = true;
}, delay);
};
}影响性能的问题有哪些?
+ 未压缩的资源 + 过多HTTP请求 + 未使用缓存 + 大量重绘/重排 + 长任务阻塞主线程 + 内存泄漏🟢 Vue
Vue2 和 Vue3 的区别?
+ 响应式原理:Vue2使用`Object.defineProperty`,Vue3使用`Proxy` + 组合式API(Composition API) + 更好的TypeScript支持 + 更小的打包体积 + 生命周期函数改名(如`beforeDestroy` → `beforeUnmount`)defineProperty和Proxy的区别
+ defineProperty无法检测对象属性的添加和删除,以及数组的索引和长度变化,以及数组的一些方法比如push shift pop 等,需要另外写包装方法。 + proxy则原生支持对象和数组的全量操作和监听。 + proxy做到了对象属性的按需劫持,只在真正访问到的属性上创建代理,初始化速度更快,占用内存更少。组件间的通信有哪些?
+ props / $emit + ![]()children + provide / inject + $refs + Vuex / Pinia + 事件总线(event bus)vue3 diff算法做了哪些优化?
+ 静态提升(Hoist Static) + 靶向更新(Patch Flag) + 块树(Block Tree) + 事件缓存(Cache Handler)vue3 的 setup是在什么生命周期?
处于生命周期的 `beforeCreate` 和 `created` 之间data定义一个对象为什么用一个你们函数来返回一个对象?.
避免多个组件实例共享同一个数据对象,导致状态污染。v-for循环为什么要添加key?
帮助Vue识别节点身份,优化diff算法,提高渲染效率。watch和computed的区别?
+ `computed`:缓存结果,依赖变化才重新计算 + `watch`:监听数据变化,可执行异步操作vue3生命周期有哪些?
+ `setup` + `onBeforeMount`、`onMounted` + `onBeforeUpdate`、`onUpdated` + `onBeforeUnmount`、`onUnmounted` + `onErrorCaptured`父组件嵌套子组件,父子组件的生命周期执行顺序是怎样?
父`beforeCreate` → 父`created` → 父`beforeMount` → 子`beforeCreate` → 子`created` → 子`beforeMount` → 子`mounted` → 父`mounted`vue3怎么调用子组件的方法?
子组件内使用defineExpose暴露方法,在父组件中使用`ref`获取子组件实例,然后调用其 方法。使用虚拟DOM有什么好处?
+ 跨平台渲染 + 高效的 diff 算法 + 减少直接操作 DOM 的开销vue中nextTick有什么作用?
在下次DOM更新循环结束后执行回调,用于获取更新后的DOM。ref和reactive的区别?
+ `ref`:适用于基本类型,通过`.value`访问 + `reactive`:适用于对象类型,不需要`.value`proxy怎么实现响应式?
通过拦截对象的读取、设置、删除等操作,实现依赖收集和触发更新。📜 JavaScript
事件循环是什么?
1. **执行全局同步代码**:这是最初的执行栈,所有同步代码会一行一行地执行。 2. **执行完同步代码后**:调用栈变空,事件循环开始工作。 3. **检查微任务队列**: - 如果队列中有任务(例如 Promise 的 `.then`, `.catch`, `.finally` 回调),事件循环会**依次执行所有微任务**,直到队列清空。 - 注意:如果在执行微任务的过程中,又产生了新的微任务,这些新微任务也会被加入到当前队列中,并在本次循环中被执行完毕。这意味着微任务可以“插队”。 1. **检查是否需要渲染页面(浏览器)**:根据浏览器的刷新率(如 60Hz),可能会在此处进行页面的重绘与重排。 2. **检查宏任务队列**: - 取出队列中的**第一个**任务(例如 `setTimeout` 的回调),将其放入调用栈中执行。 1. **重复循环**:回到第 3 步,检查微任务队列,如此循环往复。一个简单的比喻:
把 JavaScript 引擎想象成一个只有一个收银台的餐厅(单线程)。
- 同步顾客:直接点餐付款,不耽误时间。
- 异步顾客:点一些需要时间准备的菜(比如现炒的菜)。
- 宏任务:像是点了大餐的顾客,服务员(事件循环)记下订单后,先去服务其他顾客,等后厨(Web APIs)做好了,再按顺序把菜端给他。
- 微任务:像是需要一包餐巾纸的顾客,服务员在端大餐给任何宏任务顾客之前,会先把所有需要餐巾纸的顾客的需求都满足掉。
微任务和宏任务有哪些?
**微任务**微任务是在当前同步任务执行结束后、下一个宏任务开始之前立即执行的任务。它们拥有更高的优先级。
常见的微任务包括:
- Promise 的回调:
.then(),.catch(),.finally() - queueMicrotask():专门用于将函数加入微任务队列的 API。
- MutationObserver(浏览器环境):监听 DOM 变化的回调。
- process.nextTick(Node.js 环境):这是 Node.js 中的一个特殊微任务,它甚至比 Promise 的微任务优先级还要高。
宏任务
宏任务代表一个个独立的、离散的工作单元。浏览器会在完成一个宏任务后,在下一个宏任务执行前,进行页面的渲染,并处理所有的微任务。
常见的宏任务包括:
- setTimeout / setInterval:定时器回调。
- I/O 操作:如读取文件、网络请求(Ajax)的回调。
- setImmediate(Node.js 环境):一个特殊的宏任务。
- UI 渲染(浏览器环境):严格来说,渲染本身也是一个宏任务。
- 事件回调:如
click,scroll,load等 DOM 事件的回调函数。 - requestAnimationFrame(浏览器环境):通常被认为在渲染阶段之前执行,可以视作一个特殊的宏任务。
ES6有哪些新特性?
+ let/const + 箭头函数 + 模板字符串 + 解构赋值 + Promise + 模块化(import/export) + ClassJS数据类型有哪些?
+ 基本类型:string、number、boolean、null、undefined、symbol、bigint + 引用类型:object、array、function、date等Map和Object有什么区别?WeaKMap 和Map有什么区别?
+ Map:键可以是任意类型,有序,有size属性 + Object:键只能是字符串或Symbol,无序 + WeakMap:键必须是对象,弱引用,不可遍历说说原型链
每个对象都有一个`__proto__`指向其构造函数的`prototype`,形成链式结构,用于实现继承。new操作符做了哪些工作?
1. 创建一个空对象 2. 将空对象的`__proto__`指向构造函数的`prototype` 3. 将构造函数的`this`指向这个对象 4. 执行构造函数,返回对象(若构造函数无返回,则返回新对象)垃圾回收机制工作原理
+ 标记清除:标记不再使用的变量,然后清除 + 引用计数:记录引用次数,为0时回收(易循环引用)说说对 promise 的了解?
Promise是异步编程的解决方案,有三种状态:pending、fulfilled、rejected。支持链式调用`.then`、`.catch`。前端有一个大量的计算需要处理,造成页面卡顿,如何优化?
+ 使用Web Worker + 使用`requestIdleCallback`或`setTimeout`分片计算 + 使用异步更新(如Vue的nextTick)require和import有什么区别?
+ `require`是CommonJS,同步加载,可动态引入 + `import`是ES6模块,静态加载,支持tree shaking什么是闭包?在什么时候用?
函数内部返回一个函数,并保留对外部变量的引用。常用于:- 私有变量
- 函数工厂
- 回调函数
🔷TypeScript
type和interface有什么区别?
+ `interface`可重复声明合并,`type`不可 + `type`可定义联合类型、元组等 + `interface`更适合对象类型泛型是什么?
类型参数化,提高代码复用性和类型安全typescript
function identity<T>(arg: T): T {
return arg;
}联合类型是什么?
表示一个值可以是多种类型之一。typescript
let value: string | number;类型里面的问号和感叹号有什么作用?
+ `?`:可选属性 + `!`:非空断言,表示该值不为null/undefinedvue3项目里面,TS类型推断不出来,如何解决?
🎨 CSS
css隐藏元素有哪些方法?
+ `display: none` + `visibility: hidden` + `opacity: 0` + `position: absolute; left: -9999px`css伪元素、伪类有哪些?
+ 伪类:`:hover`、`:active`、`:focus`、`:first-child` + 伪元素:`::before`、`::after`、`::first-line`、`::selection`🛠 项目难点亮点
Monorepo
大文件分片上传
大数据处理和性能优化
📦 前端工程化(前端架构)
webpack和vite的区别?
vite的配置有哪些?
pnpm和yarn、npm的区别?
eslint 配置有哪些?版本8和9有什么区别?
🌐 HTTP和通信
从浏览器地址栏输入网址回车后到看到页面经过了哪些流程?
强缓存和协商缓存的区别?
如何做实时通信?
+ WebSocket + Server-Sent Events (SSE) + 长轮询语音通话用什么协议?
WebRTChttp常见的状态码有哪些?分别有代表什么?
+ 200:成功 + 301/302:重定向 + 404:未找到 + 500:服务器错误前端怎么接收服务端推送?有哪些方法?
+ WebSocket + SSE + 长轮询https和http的区别?为什么说https安全性更高?
HTTPS = HTTP + SSL/TLS,对数据进行加密传输,防止窃听和篡改。🔍 SEO
如何做SEO优化?
+ 合理的title、description、keywords + 语义化HTML + 使用SSR + 使用sitemap、robots.txt + 外链建设页面里怎么让爬虫忽略一些链接?
使用`rel="nofollow"`🛡 安全
XSS和CSRF是什么?如何防御?
+ **XSS**:跨站脚本攻击,防御:转义输入输出、使用CSP + **CSRF**:跨站请求伪造,防御:使用Token、验证Referer、SameSite Cookie🔗 其它
页面上通过iframe嵌套了一个第三方页面,如何进行通信?
使用`postMessage`和`onmessage`进行跨域通信。CDN具体是怎么实现的?
将资源分发到全球节点,用户访问时从最近的节点获取,加速访问。qiankun怎么用,比如有哪些方法等等?
+ `registerMicroApps`:注册微应用 + `start`:启动微前端 + 生命周期:bootstrap、mount、unmount不同项目使用不同版本的公司组件库,怎么去做区分管理?
+ 使用npm别名安装不同版本 + 使用Monorepo + 符号链接 + 使用动态导入单页面应用和多页面应用的区别?
+ SPA:一个HTML,通过JS动态更新内容,体验好,SEO差 + MPA:多个HTML,每次跳转刷新页面,SEO好,体验差uniapp有哪些生命周期?
📄 针对简历的提问
做了哪些公共组件?
根据实际项目回答,如:- 表单组件(Form、Input、Select)
- 表格组件(支持排序、筛选、分页)
- 弹窗组件(Modal、Drawer)
- 上传组件(支持拖拽、预览)
- 图表组件(基于 ECharts 封装)
🖊️手写代码
手写防抖函数
```javascript // 防抖 function debounce(fn, delay) { let timer; return function(...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; } ```手写节流函数
```javascript // 节流 function throttle(fn, delay) { let flag = true; return function(...args) { if (!flag) return; flag = false; setTimeout(() => { fn.apply(this, args); flag = true; }, delay); }; } ```手写Promise
来自: 面试题汇总