1.React 中为什么不直接使用 requestIdleCallback?
React 不直接使用 requestIdleCallback 是因为该 API 的浏览器兼容性和性能限制。requestIdleCallback 的执行依赖于浏览器的空闲时间,可能导致任务延迟不可控。React 实现了自己的调度器(Scheduler),通过优先级控制和时间切片(Time Slicing)更精确地管理任务执行。
React 的调度器能更好地处理高优先级任务(如用户交互),避免低优先级任务阻塞渲染。同时,requestIdleCallback 的触发频率和时机不稳定,而 React 的调度器能通过模拟空闲时间实现更稳定的任务调度。
2.为什么 react 需要 fiber 架构,而 Vue 却不需要?
React 的 Fiber 架构是为了解决大型应用中的渲染阻塞问题。React 的递归渲染过程是不可中断的,可能导致长时间占用主线程。Fiber 将渲染任务拆分为可中断、可恢复的单元,支持增量渲染和优先级调度。
Vue 不需要 Fiber 是因为其响应式系统基于依赖追踪。Vue 的模板编译阶段已确定依赖关系,更新时直接定位到需修改的组件,无需遍历整个树。Vue 的更新粒度更细,避免了 React 的全树对比需求。
3.React 中为什么不直接使用 requestIdleCallback?
React 不直接使用 requestIdleCallback 是因为该 API 的浏览器兼容性和性能限制。requestIdleCallback 的执行依赖于浏览器的空闲时间,可能导致任务延迟不可控。React 实现了自己的调度器(Scheduler),通过优先级控制和时间切片(Time Slicing)更精确地管理任务执行。
React 的调度器能更好地处理高优先级任务(如用户交互),避免低优先级任务阻塞渲染。同时,requestIdleCallback 的触发频率和时机不稳定,而 React 的调度器能通过模拟空闲时间实现更稳定的任务调度。
4.为什么 React 需要 Fiber 架构,而 Vue 却不需要?
React 的 Fiber 架构是为了解决大型应用中的渲染阻塞问题。React 的递归渲染过程是不可中断的,可能导致长时间占用主线程。Fiber 将渲染任务拆分为可中断、可恢复的单元,支持增量渲染和优先级调度。
Vue 不需要 Fiber 是因为其响应式系统基于依赖追踪。Vue 的模板编译阶段已确定依赖关系,更新时直接定位到需修改的组件,无需遍历整个树。Vue 的更新粒度更细,避免了 React 的全树对比需求。
5.子组件是一个 Portal,发生点击事件能冒泡到父组件嘛?
Portal 的点击事件可以冒泡到父组件。Portal 仅改变 DOM 结构,不改变 React 组件树的事件冒泡机制。事件仍按照组件层级冒泡,即使 Portal 的子组件渲染到 DOM 的其他位置。
6.前端性能优化指标有哪些?怎么进行性能检测?
性能指标:
- FCP (First Contentful Paint):首次内容渲染时间。
- LCP (Largest Contentful Paint):最大内容渲染时间。
- TTI (Time to Interactive):可交互时间。
- CLS (Cumulative Layout Shift):累计布局偏移。
- FID (First Input Delay):首次输入延迟。
检测方法:
- Lighthouse:Chrome DevTools 集成工具,提供性能评分和建议。
- WebPageTest:多地点测试加载性能。
- Chrome Performance Tab:录制并分析运行时性能。
- Core Web Vitals:通过 Google 的 RUM(真实用户监控)数据评估。
7.CSS 中的 animation、transition、transform 有什么区别?
- transform:修改元素的视觉表现(如旋转、缩放、平移),不触发动画。
- transition :在属性变化时添加过渡效果,需触发条件(如
:hover)。 - animation :通过关键帧(
@keyframes)定义复杂动画,可自动触发或循环。
8.使用 Promise 实现红绿灯交替重复亮
javascript
function light(color, duration) {
return new Promise(resolve => {
console.log(color);
setTimeout(resolve, duration);
});
}
async function trafficLight() {
while (true) {
await light('红灯', 3000);
await light('绿灯', 2000);
await light('黄灯', 1000);
}
}
trafficLight();
9.React 为什么要废弃 componentWillMount、componentWillReceiveProps、componentWillUpdate?
这些生命周期钩子的问题:
- 异步渲染冲突:可能被多次调用或打断,导致副作用(如数据请求)重复执行。
- 逻辑冗余 :
componentWillReceiveProps易被误用,衍生复杂逻辑。
解决方案:
- 使用
static getDerivedStateFromProps替代componentWillReceiveProps。 - 副作用移至
componentDidMount或componentDidUpdate。 - 引入 Fiber 架构的调度机制,确保渲染安全性。
10.React render 方法的原理?在什么时候会被触发?
原理: render 是纯函数,根据 state 和 props 返回 JSX 或 React 元素。React 通过协调(Reconciliation)比较新旧虚拟 DOM,生成最小 DOM 操作。
触发时机:
- 组件初始化时。
state或props更新时。- 父组件重新渲染(除非实现
shouldComponentUpdate拦截)。
11.什么是 DOM 和 BOM?
- DOM (Document Object Model):文档对象模型,提供 HTML/XML 的结构化表示,允许 JavaScript 操作页面元素。
- BOM (Browser Object Model) :浏览器对象模型,提供与浏览器交互的 API(如
window、navigator、location)。
12.从输入网址到页面显示的过程
- DNS 解析:将域名转换为 IP 地址。
- TCP 连接:与服务器建立三次握手。
- HTTP 请求:发送请求报文。
- 服务器处理:返回响应(HTML、CSS、JS 等)。
- 浏览器渲染:解析 HTML 构建 DOM,CSS 构建 CSSOM,合成渲染树,布局和绘制。
- 加载资源:异步加载图片、脚本等。
13.SPA 首屏加载速度慢怎么解决?
- 代码分割 :使用动态导入(
React.lazy+Suspense)按需加载。 - 预渲染:生成静态 HTML 骨架。
- CDN 加速:分发静态资源。
- 服务端渲染 (SSR):首屏直出 HTML。
- 缓存策略 :强缓存(
Cache-Control)减少重复请求。
14.RESTful 接口规范是什么?
- 资源导向 :URL 表示资源(如
/users)。 - HTTP 方法 :
GET(查询)、POST(创建)、PUT(更新)、DELETE(删除)。 - 无状态:每次请求包含完整信息。
- 返回格式 :通常为 JSON,状态码标准化(如
200、404)。
15.字符串压缩实现
javascript
function compressString(str) {
let result = '';
let count = 1;
for (let i = 0; i < str.length; i++) {
if (str[i] === str[i + 1]) {
count++;
} else {
result += str[i] + count;
count = 1;
}
}
return result.length < str.length ? result : str;
}
console.log(compressString('aabcccccaaa')); // a2b1c5a3
16.new 操作符的作用
- 创建一个空对象,其
__proto__指向构造函数原型。 - 执行构造函数,绑定
this到新对象。 - 如果构造函数返回对象,则作为
new的结果;否则返回新对象。
17.Webpack 5 主要升级点
- 模块联邦:跨应用共享代码。
- 持久缓存:提升构建速度。
- Tree Shaking 增强:支持嵌套模块和 CommonJS。
- 资源模块 :内置 Asset Modules(替代
file-loader)。 - Node.js Polyfill 移除:需手动引入。
18.try...catch 能捕获异步错误吗?
-
同步代码:直接捕获。
-
异步代码 :需在异步回调内捕获(如
Promise.catch或async/await的try-catch)。javascriptasync function foo() { try { await Promise.reject('error'); } catch (e) { console.log(e); } }
19.本地多 Tab 页通信方案
-
BroadcastChannel API :跨 Tab 广播消息。
javascriptconst channel = new BroadcastChannel('chat'); channel.postMessage('Hello'); channel.onmessage = (e) => console.log(e.data); -
LocalStorage 事件 :监听
storage事件(需同源)。 -
SharedWorker:后台线程共享数据。
20.低代码的理解
低代码平台通过可视化拖拽和配置生成应用,减少手写代码量。适用于:
- 快速原型开发。
- 企业内部工具。
- 简单业务流程。 核心能力包括表单生成、工作流引擎和数据绑定。
WebSocket 和 HTTP 的区别
- 协议 :WebSocket 是独立协议(
ws://),HTTP 是应用层协议。 - 连接:WebSocket 全双工长连接,HTTP 短连接。
- 通信模式:WebSocket 支持服务端主动推送,HTTP 需客户端轮询。
21.Vite 的原理
Vite 基于原生 ESM 实现快速开发:
- 开发模式:利用浏览器直接加载 ES 模块,无需打包。
- 生产构建:使用 Rollup 优化代码。
- HMR:通过 ESM 的即时更新实现热替换。
- 预编译 :对
node_modules预打包为 ESM 格式。