🗒️前端面试准备

比尔盖子

|2025-8-31|最后更新: 2025-9-1|
type
status
date
slug
summary
tags
category
icon
password

虚拟DOM

虚拟DOM是什么?
  • 在传统的Web应用中,数据的变化会实时地更新到用户界面中,于是每次数据微小的变化都会引起DOM的渲染。
  • 虚拟DOM是将所有的操作聚集到一块,计算出所有的变化后,统一更新一次虚拟DOM。
虚拟DOM作用
  • 提高开发效率,只需要关注业务代码。无需关注DOM更新,React会将这一切计算好。
  • 虚拟DOM感受到变化的时候,只会更新局部,而非整体。同时,虚拟DOM会减少了非常多的DOM操作 ,所以性能会提升很多

React Diff算法

  • Tree Diff:认为跨层级移动节点操作比较少,只比较同一层级的节点。
  • Component Diff:组件类型不一样,React就认为不是同一个组件。
  • Element diff:同一层级的子节点,比较唯一Key。有三类操作:插入,移动,删除。

React Hook原理

Fiber结构
  • parent:指向父级Fiber节点:
  • child:指向子Fiber节点
  • sibling:指向右边的兄弟节点
notion image
为什么要用Fiber
  • 在 react16 引入 Fiber 架构之前,react 会采用递归方法对比两颗虚拟DOM树,找出需要改动的节点,然后同步更新它们,这个过程 react 称为reconcilation(协调)。在reconcilation期间,react 会同步执行操作,提交到真实 DOM 的更改,会一直占着浏览器的资源,不能中断,中断后就不能恢复,使得我们一些用户操作定时器等等事件无法得到响应,是一个非常糟糕的用户体验。
怎么实现的
  • 一个节点就是一个Fiber任务,在浏览器的requestIdleCallback回调中,判断空余时间执行Fiber任务。
Hooks原理
  • hooks 实现是基于 fiber 的,通常链表形式串起来。每次会执行链表中的Hooks更新,所以不能用在条件和循环语句中。
  • 每个 fiber 节点的 memoizedState 保存了对应的数据,不同的 hooks 通过使用该对应数据完成对应的逻辑功能。
常见Hooks状态
  • useState/useReducer:memoizedState 等于 state 的值
  • useEffect:memoizedState 保存的是 effect 链表(包含 useEffect 第一个参数回调与第二个参数依赖项数组的值)
  • useRef:memoizedState 等于 { current: 当前值 }
  • useCallback:保存两个参数值,memoizedState 等于 [callback, deps],缓存的是函数
  • useMemo:保存两个参数值,memoizedState 等于 [callback(), deps],缓存的是函数执行计算结果。

重排和重绘

  • 解析HTML:浏览器将HTML解析成DOM树。
  • 解析CSS:浏览器将CSS解析成CSSOM树。
  • 构建渲染树:浏览器将DOM树和CSSOM树结合,生成渲染树。
  • 布局(Layout):浏览器根据渲染树计算每个节点的几何信息(位置和大小)。
  • 绘制(Paint):浏览器将渲染树的每个节点绘制到屏幕上。
其中Layout就是重排,Paint就是重绘
notion image

组件间传值

  • 父向子传值:props传值
  • 子向调用父方法:props传入回调函数
  • 父调用子方法:父组件useRef拿到子组件ref,子组件在useImperativeHandle中声明暴露给父组件的方法。
  • 父跨层级向子传值:
    • Redux
    • Provider,userContext
    • EventBus,数据流转会变得不可控,建议用在小项目上。

自己基于Provider实现Redux

  1. provider传参dispatch和state
  1. useContext获取state和dispatch,state数据发生变化时刷新视图
  1. dispatch根据action改变state的值

性能优化

  1. 网络优化
    1. 开启gzip
    2. 使用webp图片
    3. 开启Tree Shaking,移除未使用JS代码。使用MiniCssExtractPlugin进行CSS压缩。
    4. 协商缓存,强缓存
    5. 静态资源CDN
  1. 渲染优化
    1. 减少重排重绘
    2. 虚拟列表优化
    3. 代码分割和懒加载
    4. useMemo,memo缓存组件
    5. 节流和防抖
  1. 进阶优化
    1. 预加载回包
    2. SSR云端预加载回包

媒体适配

CSS中使用@media根据设备的宽高映射不同的样式

JSBridge原理

JSbridge用于JS和Native之间互相通信,方便数据传输和回调方法
JS调用JAVA:WebView.addJavascriptInterface()将对象注册到JavaScript,这个对象中@JavascriptInterface 注解标记的方法,会被暴露给 JS,使得 JS 可以直接调用这些方法。
JAVA调用JS:WebView.evaluateJavascript(),前端注册回调window.jsBridge.receiveNativeMessage

Webpack插件

loader:是个转换函数,输入文件输出处理过的文件。如babel,ts-loader
plugin:插件,基于Webpack的生命周期做些扩展操作。
TerserPlugin:压缩JS
cssnano:减少CSS体积
SplitChunksPlugin:切分代码块
  1. 用正则匹配三方包名,将共用的三方库打包如vender。chunks=”inital”
  1. 非首屏入口,使用懒加载import()。chunks=”all”|”async”
Loading...