沐游虞笔记
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 前端面试题

    • HTML面试题汇总(无答案)
    • HTML面试题汇总
    • CSS 面试题汇总(无答案)
    • CSS 面试题汇总
    • javascript 面试题汇总(无答案)
    • javascript 面试题汇总
    • promise 面试题(无答案)
    • promise 面试题
    • 浏览器面试题汇总(无答案)
    • 浏览器面试题汇总
    • 网络面试题汇总(无答案)
    • 网络面试题汇总
    • 工程化面试题汇总(无答案)
    • 工程化面试题汇总
    • VUE面试题汇总(无答案)
    • VUE面试题汇总
  • 直播课文件

    • 静态页面学习指导
    • 属性的计算过程
    • 层叠继承规则总结
    • BFC
    • JS基础知识回顾
    • DOM 事件的传播机制
    • DOM 事件的注册和移除
    • 阻止事件默认行为
    • 基础领航考试题
    • 基础领航考试题(答案)
    • 2024前端发展
    • JS核心概念学习指导
    • 第三方库与工程化学习指导
    • Vue入门学习指导
    • vue进阶学习指导
    • 前端性能优化
  • 笔面试环节知识讲解

    • 目录
    • 图像处理
    • 图像处理(面试)
    • Webpack构建优化
    • Webpack构建优化(面试)
    • TTS性能优化
    • TTS性能优化(面试)
    • 实时协作
    • 实时协作(面试)
    • 网页复制图片到剪贴板
    • 网页复制图片到剪贴板(面试)
    • vite插件
    • vite插件(面试)
    • 表单数据同步与保持
    • 表单数据同步与保持(面试)
    • 优化虚拟列表
    • 优化虚拟列表(面试)
    • 微前端解决巨石应用
    • 微前端解决巨石应用(面试)
    • DNS解析与优化
    • DNS解析与优化(面试)
    • 前端监控
    • 前端监控(面试)
    • 12.跨标签页通信
    • 12.跨标签页通信(面试)
    • 13.Vite相关优化
    • 13.Vite相关优化(面试)
    • 14.计时器节流问题
    • 14.计时器节流问题(面试)
    • 15.多文件预览支持
    • 15.多文件预览支持(面试)
    • 16.defer优化白屏时间
    • 16.defer优化白屏时间(面试)
  • Vue3整体变化
  • Vue2响应式回顾
  • Vue3响应式变化
  • nextTick实现原理
  • 两道代码题
  • Vue运行机制
  • 渲染器核心功能
  • 事件绑定与更新
  • computed面试题
  • watch面试题
  • 图解双端diff
  • 图解快速dff
  • 最长递增子序列
  • 模板编译器
  • 模板编译提升
  • 组件name作用
  • 路由传参方式
  • 基础篇

    • 序章React介绍
    • JSX基础语法
    • React基本介绍
    • 表单
    • 生命周期
    • 组件与事件绑定
    • 组件状态与数据传递
    • Hooks
    • React--redux介绍
    • React-router介绍
  • 就业篇

    • 属性默认值和类型验证
    • 高阶组件
    • Ref
    • Context
    • Render Props
    • Portals
    • 错误边界
    • 组件渲染性能优化
    • 前端框架的理解
    • Reacti和Vue描述页面的区别
    • 前端框架的分类
    • 虚拟DoM
    • React整体架构
    • React渲染流程
    • Fiber双缓冲
    • MessageChannel
    • Scheduleri调度普通任务
    • Scheduleri调度延时任务
    • 最小堆
    • React中的位运算
    • beginWork工作流程
    • completeWork工作流程
    • 图解diff算法
    • commit工作流程
    • lane模型
    • React中的事件
    • Hooks原理
    • useStateuseReducer.
    • effect相关hook
    • useCallbackuseMemo
    • useRef
    • Update
    • 性能优化策略之eagerState
    • 性能优化策略之bailout
    • bailoutContextAPl
    • 性能优化对日常开发启示
  • 前端监控概述
  • 错误监控
  • 数据上报
  • 页面性能监控
  • 用户行为收集与埋点
  • CSS3手册
  • HTML5手册
  • JavaScript语言提升

    • es补充
    • 事件循环
    • promise基础
    • Promise的链式调用
    • Promise的静态方法
    • async和await
    • Promise相关面试题
  • 网络

    • 客户端与服务器
    • 关于 Apifox 的使用
  • git文档
  • 工程化

    • CommonJS
    • ES module
    • npm文档(包管理)
    • Lass笔记
    • webpack工具
  • canvas详解
  • uinapp笔记
  • 自动化测试
  • oauth2令牌

    • 认识Oauth2
    • 三方应用实现github授权
    • 微信三方应用登录实现
    • 支付宝沙箱支付功能
  • 必看导言

    • 就业的核心问题

      • 课件
    • 表现力的训练

      • 课件
  • 简历制作

    • 课件
    • 简历准备课堂笔记
    • 个人信息课堂笔记
    • 求职意向课堂笔记
    • 技术栈课堂笔记
    • 教育经历课堂笔记
    • 个人优势与评价课堂笔记
    • 工作经历课堂笔记
    • 项目
    • 项目亮难点问题

    • 项目经历

  • 项目准备

    • 课件
    • 课件
  • 技术重点

    • 划重点

    • 非技术环节
  • 简历投递和面试准备

    • 简历投递
    • 面试准备
  • 笔面试环节知识讲解
  • 项目准备
  • 难点攻关
  • 表单数据同步与保持
  • 课件资料
luzhichang
2024-09-18
目录

07-面试讲解

# 公共表单模块面试讲解

# 技术点图谱

涉及到的技术点如下:

  • 类的设计
  • localstorage
    • sessionstorage
  • BroadcastChannel
    • 其他标签页通信方案
  • 测试与压缩
  • 包的发布
image-20240627010219130

# 难点描述

模拟问题:我看到你写的项目亮点是“实现表单数据的同步与状态保持”,你能简单说一下这具体是做了什么事情么

问题分析

  1. 先介绍项目背景
  2. 描述清楚遇到的问题
  3. 你拿到这个问题是如何思考的
  4. 你思考出来的落地方案
  5. 落地方案的效果,最好有具像化的数据
  6. 强调封装为了公共模块,并发布至npm

参考答案

当时我们的项目是一个比较复杂的后台管理系统,里面涉及到很多的表单需要用户填写。由于表单内部涉及到的表单项比较多,往往需要用户填写的时间会比较长,再加上还有多标签页、多窗口之间的操作,所以当时遇到了几个不得不解决的问题:

  1. 数据丢失风险:就是用户在填写表单过程中,可能会因为浏览器意外关闭、系统崩溃等原因导致填写的数据丢失
  2. 表单数据恢复:用户在未提交表单数据的情况下,重新打开页面时需要恢复之前填写的内容
  3. 跨标签页数据同步:当用户在多个标签页同时编辑一个表单时,需要确保不同标签页之间的数据同步,避免数据不一致
  4. 去除本地冗余数据:表单提交后,需要及时清理本地的数据,防止存储数据冗余。

(阐述项目背景以及遇到的问题)

当时拿到这些需求后,我先对功能需求进行了归类和拆解,最终整理出来其实就是两大块:

  1. 数据自动保存与恢复
  2. 多标签页间数据广播

这两个功能要实现起来其实并不难,而且实现的方案还不止一个。但有一个非常关键的点,就是我考虑将这个功能模块封装为一个不受框架限制的公共模块,无论是在 Vue 还是在 React 里面可以使用。(你是怎么思考的)

因此最终在对这个模块进行设计的时候,我将其设计为了类的结构,并且内部代码不会使用某个框架特定 API. 这样才能确保这个模块无论是在 Vue 中还是 React 中都是适用的,哪怕是放到 Svelte 或者 Solid.js 里面,我封装的这个模块也能正常工作。(落地方案)

有了这个模块做支撑后,前面我所说的那个问题都得到了有效的解决,并且为了方便团队其他成员使用,我先将其发布到了公司内部的包管理服务器上面。后面由于该模块在公司多个项目里面都工作良好,最后还将其发布到了 npm 上面。

# 技术点讲解

# 1. 类的设计

模拟问题:既然是封装成公共模块,那么要考虑的地方肯定相比业务代码就要多一些,你能讲一下你当时在封装这个模块时,有哪些考虑么?

问题分析

贴合你的项目,说一下你当时在设计类的时候,是怎么考虑的?每一个类它的职责是什么?

因为是类的设计,所以最好说一下用到了什么样的设计模式

参考答案

当时我在设计模块的时候,整理出来了两个功能模块。一个 FormStorage 类专门负责处理:

  • 数据本地存储、恢复、删除
  • 多标签的数据广播

而另一个 FormStorageManager 类则是专门管理 FormStorage 类实例。

之所以要用 FormStorageManager 来管理 FormStorage 类实例是为了:

  • 集中管理:通过 FormStorageManager 类来集中管理所有 FormStorage 实例,确保所有实例的统一初始化、数据保存和事件处理。
  • 优化事件监听:避免在每个 FormStorage 实例中重复绑定全局事件监听器,从而减少不必要的性能开销。

另外,FormStorage 类里面用到了 BroadcastChannel 来实现跨标签页的通信,这也算是观察者模式的一种体现。(说到了设计模式,体现对设计模式也是有一定了解的)

  • 广播方:FormStorage 实例通过 BroadcastChannel 发送和接收消息,实现数据同步。
  • 订阅方:多个 FormStorage 实例监听 BroadcastChannel 消息,接收并处理数据变化通知。

# 2. 本地存储

模拟问题:说一下本地存储这一块儿有哪些方案?你为什么选择了 localstorage ?

问题分析

  1. 阐述常见的本地存储的方案有哪些?各自的区别是什么?
  2. 为什么选择了 localstorage?
  3. 设置下一个钩子

参考答案

本地存储这一块儿,其实客户端的解决方案还是挺多的,常见的有:

  1. localstorage:同步存储,每个域名下有 5-10MB 的存储空间,适合存储少量的字符串数据,数据持久性高,即使浏览器关闭,数据仍然存在
  2. sessionstorage:与 localstorage 类似,同样只能存储字符串类型数据。并且存储的数据仅在会话期间有效,也就是浏览器关闭后数据会被清除
  3. IndexedDB:异步存储,支持更复杂的数据结构,例如对象,存储空间较大,通常为数百 MB 甚至更多,还支持数据库中常见的事物等特性,适合存储大量数据和复杂数据。

考虑到当时我们项目的存储场景,存储的是表单控件的值,并非多大的数据量,然后重新打开标签页时值要回填,所以我选择了使用 localstorage 来存储那些表单项的值。(解释了为什么选择localstorage)

存储这一块儿的处理倒不难,但也算是整个模块里面的核心功能之一。另外一个核心功能就是跨标签页数据通信,我这边选择的是 BroadcastChannel 来实现的。(钩子🪝)

# 3. BroadcastChannel

模拟问题:说一下跨标签页数据通信常见有哪些方案?你为什么选择了 BroadcastChannel ?

问题分析

  1. 常见跨标签页通信的方案有哪些?各自的区别是什么?
  2. 为什么选择 BroadcastChannel ?
  3. 设置下一个钩子

参考答案

跨标签页数据通信的方案也很多,像:

  1. localstorage + storage 事件
  • 特点:通过 localStorage 存储数据,利用 storage 事件在不同标签页之间同步数据变化。
  • 优点:浏览器兼容性好,使用简单。
  • 缺点:只能在同源页面之间通信,且数据只能是字符串类型,storage 事件仅在不同标签页间有效,同一标签页的同域页面间无法触发。
  1. service workers
  • 特点:可以在后台脚本中实现消息的接收和发送。
  • 优点:可以实现更复杂的逻辑,如离线处理、网络请求拦截等。
  • 缺点:实现较为复杂,需要 HTTPS 支持,初次设置和调试成本较高。
  1. postmessage
  • 特点:通过 window.postMessage 在不同窗口或 iframe 之间发送消息。
  • 优点:支持跨域通信,可以在不同来源的页面之间发送消息。
  • 缺点:需要手动管理消息的接收和处理,适合窗口间或 iframe 间的通信,标签页间通信需要通过父窗口代理。
  1. broadcastChannel
  • 特点:通过 broadcastChannel 实现多个浏览器上下文(标签页、iframe、窗口)之间的消息广播。
  • 优点:使用简单,API 友好,支持多标签页、iframe 和窗口之间的即时通信,不受同源限制。
  • 缺点:浏览器支持情况较新,不支持所有旧版浏览器。

因此综合考虑了各种方案的优缺点后,我选择了 broadcastChannel,这个 API 现在的兼容性也比较好,大多数浏览器都支持。而对于不支持这个 API 的浏览器,可以通过回退机制使用 localstorage + storage 事件的方案。(体现个人做事儿的风格)

这两个核心功能处理完后,基本上整个模块也就完成了,剩下的就是测试和发布了。(钩子🪝)

# 4. 测试与压缩

模拟问题:说一下你在模块发布前,还做了哪些准备工作?

问题分析

  1. 做了什么测试?使用什么来做的这个测试
  2. 使用什么工具进行的打包?为什么选择的这个工具?你的考量是什么?
  3. 设置下一个钩子

参考答案

首先就是我刚才所说到的测试,毕竟是要对外发布的一个公共模块,必须要确保模块的可靠性和稳定性,因此测试是非常有必要的。我主要对 FormStorage 模块进行了全面的单元测试。测试的内容包括:

  • 基本功能测试:验证数据的保存、恢复和删除功能是否正常。
  • 跨标签页同步测试:检查在不同标签页间数据是否能够即时同步。
  • 防抖机制测试:确保在用户输入时数据不会频繁保存,而是等待一定时间后再进行保存。
  • 边界情况测试:例如浏览器意外关闭、异常数据格式等情况,确保模块能够处理这些异常情况。

使用的测试框架是 vitest,这是一个轻量级、快速的单元测试框架,与 vite 项目高度集成,能够快速进行测试和调试。

另外一个就是打包与压缩,我选择使用的是 rollup,一般在打包公共库的时候用 rollup 要好一些,因为 rollup 有这么一些特点:

  1. Tree Shaking:可以自动去除未使用的代码。这对于公共库特别重要,因为它能够确保打包后的代码尽可能小,从而提高加载性能和使用效率。
  2. 输出格式多样:rollup 支持多种输出格式,例如 CommonJS、ESM、UMD 等。这使得一个库可以在不同的运行环境(Node.js、浏览器、模块打包器等)中使用,增加了库的兼容性和灵活性。
  3. 插件系统:rollup 提供了丰富的插件生态系统,可以方便地进行代码转换、压缩、文件处理等操作。例如,我使用了 @rollup/plugin-node-resolve 和 @rollup/plugin-commonjs 插件来处理模块解析和转换,并使用 rollup-plugin-terser 对代码进行压缩,确保生成的包体积尽可能小。
  4. 代码优化:rollup 能够对代码进行细粒度的优化,例如去除重复的依赖、压缩代码、内联代码等。这些优化能够显著减少打包后文件的大小,提高代码的执行效率。

这些优点使得 rollup 成为打包公共库的理想选择。这些准备工作做完后,差不多就可以发布了。

# 5. 包的发布

模拟问题:最后说一下你包的发布呢,你发布了哪些东西?

问题分析

  1. 发布的是源码还是打包后的代码?根据平台不同而不同
  2. 白名单和黑名单
  3. 收尾
  • 要么突出个人做事儿风格
  • 要么突出项目的收获

参考答案

不同的平台,发布的内容是不太一样的。

例如如果是 github 的话,主要是做源码分享的,所以准备工作这一块儿要多一些,涉及到 CHANGELOG、README 等各种文档。

而如果是 npm 的话,主要是做包的发布,所以一般需要做的就是对代码打包压缩,然后发布的是打包后的代码到 npm 仓库。

我这边主要是发布包到 npm 上面,因此要发布上去的是打包后的代码,这里还要对 package.json 文件进行配置:

  1. 配置包的不同环境下的入口文件
  2. 配置要上传的文件和目录

另外配置要上传的文件和目录也有两种方式:

  1. 白名单:files
  2. 黑名单: .npmignore

这里推荐用白名单的方式。这样即便后面新增了文件,白名单那一块儿也不需要做任何的修改。

通过封装这个公共模块,我对工程化相关的知识也比之前更加熟悉了,特别是 package.json 里面各种配置项,以前其实不怎么关心的,熟悉的就是 devDependencies 和 dependencies. 但是这里涉及到要发布包,所以针对入口文件配置呀、白名单配置呀、都有了更深的了解和掌握,这也算是我做这个项目时一个非常大的收获。


-EOF-

Theme by Vdoing | Copyright © 2021-2024 蜀ICP备2024068710号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式