前端岗位面试高频题库与核心原理解析
深入解析了 React Fiber 架构的设计思想与迭代动机,涵盖可中断、可恢复及优先级调度机制。同时整理了前端岗位面试高频题库,内容覆盖 JavaScript 基础、React/Vue 框架原理、CSS/HTML 规范、Node.js、TypeScript、性能优化、工程化实践及各类场景编程题,旨在帮助开发者系统梳理知识体系,应对技术面试挑战。

深入解析了 React Fiber 架构的设计思想与迭代动机,涵盖可中断、可恢复及优先级调度机制。同时整理了前端岗位面试高频题库,内容覆盖 JavaScript 基础、React/Vue 框架原理、CSS/HTML 规范、Node.js、TypeScript、性能优化、工程化实践及各类场景编程题,旨在帮助开发者系统梳理知识体系,应对技术面试挑战。

在 React 16.x 版本中,其核心的 Diff 算法被重写,以'Fiber Reconciler'的全新面貌示人。Stack Reconciler 存在根深蒂固的局限性,使得 React 不得不从架构层面做出改变。本讲围绕这两个大问题展开讨论。
JavaScript 是单线程的,浏览器是多线程的。浏览器除了处理 JavaScript 线程外,还需处理事件系统、定时器、网络请求及负责处理 DOM 的 UI 渲染线程。JavaScript 线程可以操作 DOM,这意味着 JavaScript 线程和渲染线程必须是互斥的,不能穿插执行,必须串行。当其中一个线程执行时,另一个线程只能挂起等待。
具有相似特征的还有事件线程,浏览器的 Event-Loop 机制决定了事件任务是由一个异步队列来维持的。当事件被触发时,对应的任务不会立刻被执行,而是由事件线程把它添加到任务队列的末尾,等待 JavaScript 的同步代码执行完毕后,在空闲的时间里执行出队。
在这样的机制下,若 JavaScript 线程长时间地占用了主线程,那么渲染层面的更新就不得不长时间地等待,界面长时间不更新,带给用户的体验就是所谓的'卡顿'。一般页面卡顿的时候,你会做什么呢?遗憾的是,事件线程也在等待 JavaScript,这就导致你触发的事件也将是难以被响应的。
Stack Reconciler 所带来的一个无解的问题,正是 JavaScript 对主线程的超时占用问题。为什么会出现这个问题?Stack Reconciler 是一个同步的递归过程。
同步的递归过程,意味着不撞南墙不回头,意味着一旦更新开始,根本停不下来。这里用一个案例来帮你复习一下这个过程。
在 React 15 及之前的版本中,虚拟 DOM 树的数据结构载体是计算机科学中的'树',其 Diff 算法的遍历思路,也是沿袭了传统计算机科学中'对比两棵树'的算法,在此基础上优化得来。因此从本质上来说,栈调和机制下的 Diff 算法,其实是树的深度优先遍历的过程。而树的深度优先遍历,总是和递归脱不了关系。
拿这棵树来举例,若 A 组件发生了更新,那么栈调和的工作过程是这样的:对比第 1 层的两个 A,确认节点可复用,继续 Diff 其子组件。当 Diff 到 B 的时候,对比前后的两个 B 节点,发现可复用,于是继续 Diff 其子节点 D、E。待 B 树最深层的 Diff 完成、逐层回溯后,再进入 C 节点的 Diff 逻辑......调和器会重复'父组件调用子组件'的过程,直到最深的一层节点更新完毕,才慢慢向上返回。
这个过程的致命性在于它是同步的,不可以被打断。当处理结构相对复杂、体量相对庞大的虚拟 DOM 树时,Stack Reconciler 需要的调和时间会很长,这就意味着 JavaScript 线程将长时间地霸占主线程,进而导致我们上文中所描述的渲染卡顿/卡死、交互长时间无响应等问题。
从字面上来理解,Fiber 这个单词翻译过来是'丝、纤维'的意思,是比线还要细的东西。在计算机科学里,我们有进程、线程之分,而 Fiber 就是比线程还要纤细的一个过程,也就是所谓的'纤程'。纤程的出现,意在对渲染过程实现更加精细的控制。
Fiber 是一个多义词。从架构角度来看,Fiber 是对 React 核心算法(即调和过程)的重写;从编码角度来看,Fiber 是 React 内部所定义的一种数据结构,它是 Fiber 树结构的节点单位,也就是 React 16 新架构下的'虚拟 DOM';从工作流的角度来看,Fiber 节点保存了组件需要更新的状态和副作用,一个 Fiber 同时也对应着一个工作单元。
按照 React 官方的说法,是实现'增量渲染'。所谓'增量渲染',通俗来说就是把一个渲染任务分解为多个渲染任务,而后将其分散到多个帧里面。不过严格来说,增量渲染其实也只是一种手段,实现增量渲染的目的,是为了实现任务的可中断、可恢复,并给不同的任务赋予不同的优先级,最终达成更加顺滑的用户体验。
在 React 16 之前,React 的渲染和更新阶段依赖的是两层架构:Reconciler 这一层负责对比出新老虚拟 DOM 之间的变化,Renderer 这一层负责将变化的部分应用到视图上,从 Reconciler 到 Renderer 这个过程是严格同步的。
而在 React 16 中,为了实现'可中断'和'优先级',两层架构变成了三层架构:多出来的这层架构,叫作'Scheduler(调度器)',调度器的作用是调度更新的优先级。
在这套架构模式下,更新的处理工作流变成了这样:首先,每个更新任务都会被赋予一个优先级。当更新任务抵达调度器时,高优先级的更新任务(记为 A)会更快地被调度进 Reconciler 层;此时若有新的更新任务(记为 B)抵达调度器,调度器会检查它的优先级,若发现 B 的优先级高于当前任务 A,那么当前处于 Reconciler 层的 A 任务就会被中断,调度器会将 B 任务推入 Reconciler 层。当 B 任务完成渲染后,新一轮的调度开始,之前被中断的 A 任务将会被重新推入 Reconciler 层,继续它的渲染之旅,这便是所谓'可恢复'。
以上,便是架构层面对'可中断''可恢复'与'优先级'三个核心概念的处理。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online