前端性能优化?有做具体性能指标和评估策略?
打开速度怎么变快 - 首屏加载优化
再次打开速度怎么变快 - 缓存优化
操作怎么才顺滑 - 渲染优化
动画怎么保证流畅 - 长任务拆分
回答:先说明应用的问题,怎么衡量加载情况好了多少?(同学会这样说:我的页面从5 > 3s)
指标方式来描述:
首屏加载指标优化:
1、FP(First Paint)首次绘制,一般意义不大,首次绘制就是空壳子,首字节时间
2、FCP(First Contentful Paint)首次内容绘制,FP到FCP中间其实主要的SPA应用js执行,太慢就会白屏时间太长
3、FMP(First Meaningful Paint)首次有效绘制,主要内容(可以通过MutationObserver,监控某个指定的dom变化)呈现的时间(MutationObserver)
4、LCP(Largrst Contentful paint)首次最大内容渲染,加载最大内容块呈现时间
5、INP(Interaction to Next Paint)用户交互时间
6、TTI可交互时间(SSR注意)
7、TBT(Total Blocking Time)阻塞时间从FCP到TTI总的阻塞时间
8、CLS布局偏移情况,Mutation Observer,体现重排 重绘
9、TTFB(Time to First Byte)首字节到达时间,请求发出后到接收到数据整个中间时间
首屏绘制资源体积近可能小来处理?按需 懒加载...
1、优化图片 webp 图片压缩尺寸
2、字体 设计性产品 廋身
3、具体资源懒加载 图片 js资源异步加载
4、css js文件压缩 打包构建(terser 代码压缩 文件合并 文件拆分 Tree shaking 动态加载)
5、Gzip Brotli
6、ssr
动画卡顿优化:
为什么卡顿?单线程 长任务阻塞
1、减少主线程阻塞
- 优化js执行 较少长任务 复杂计算 web worker多线程 任务拆分(react scheduler)
2、GPU 加速(cpu一条单流水执行 gpu就像塞子一样无数孔无数流水,ai大数据模型一样)
- css属性(transform opacity) 注意一点避免会引起重拍重绘的属性(定位 left top)用transform
3、requestAnimationFrame(再不重要的时间去处理不重要的东西)
4、节流 防抖
应用层状态优化
减少全局状态依赖,避免不必要的状态更新,缩小边界
渲染优化 事件优化 交互优化
关注性能优化?性能指标体系是什么样的?
推进从顶层往下,先分析性能问题,提出性能问题解决方案 具体实施,建立完整的指标体系监控,持续优化
我们的低代码平台搭建首屏慢?FMP 5s?很大冗余代码 物料组件 冗余了搭建平台代码(资源优化)怎么做打包优化
性能监控平台?针对不同项目生成不同的id,再在对应项目里引入,体现到时长分布图 P50时长分布图
FP FCP LCP 图形监控 告警
指标体系?
常规的指标:使用Performance / PerformanceObserver API 和 webvital 来做对应计算
自定义采集指标(上面的首屏加载指标优化[1-9]),FMP 通过MutationObserver来自定义计算,监听某个有效dom绘制
额外指标:DNS查询时间 资源加载时间 长任务时间,主线程占用时长超过50ms记录
上报方式设计
实时上报:关键指标(LCP CLS)需要实时,及时监控
批量上报:对非关键指标,利用定时任务进行上报,减少网络开销
xhr(跨域问题),图片上报 首字节 服务器上报
性能评估
监控指标和数据都拿到计算统计评估:
1、目标设备和网络2 3 4G弱网环境
2、基准值的定义一般根据历史数据和行业标准数据,一般定义LCP小于2.5,CLS小于0.1相对行业的标准
后续得到性能报告,具体分析性能问题,持续解决
总结:整个指标策略举措方面,主要做的处理减少体积懒加载预加载,优化图片ssr长列表渲染...这个问题回答的套路:先说你推动了整个性能分析然后给出对应的问题解决方案,再就是具体实施和建立指标体系监控持续优化,整个模块或者内容的一个组织。
在你的前端团队里面具体怎么做的性能优化?性能优化怎么落地?整个团队的质量管理?整体的管理是具体怎么落实?
性能监控的全链路设计,数据说话LCP CLS,当然要与整体业务目标挂钩想要保证首屏加载时间足够短,还是在进去页面之后动画的交互体验足够好这是完全不一样的,这些点优化的具体处理是完全不一样的,首屏加载上面说了,那缓存优化强缓存策略缓存针对操作部分渲染部分还有长任务拆分部分怎么去做都要去探讨的,还有就是针对加载交互稳定性方面要确保整个监控体系是全面的,不能够遗落掉一些关键性的用户体验;一般在这些基础上你还需要再去做些埋点,埋点事为了采集追踪用户浏览痕迹以此来评判整个产品它的用户体验,其实用户体验就是埋点系统来去评判的,我们刚才说的性能指标、性能监控、异常监控,那性能和异常监控它智能够展示出来或者体现出来你的产品稳定性,那至于产品用户体验怎么样你可能还需要额外接入或者设计一套埋点系统才能够采集到用户的体验情况。性能指标[上面加载指标优化[1-9]]、业务指标、交互指标、稳定性指标还有自定义的指标其实就是我们说的MP(针对某个主要内容绘制时间,针对某个特定模块的加载时间的一个评判它属于自定义指标),还有特定用户行为路径的完成时间这个可能就需要结合埋点系统来去看到底操作哪里鼠标经过了哪里 或者拖拽某个元素经历的多是时间,这些去评判用户的行为路径它的完全时间,这是业务的自定义指标
1、指标设计(performance API / web visual)
2、指标采集(图片 ajax xml xhr采集)
3、采集完上报(除了在前端上报完后,上报的数据是非常大的,量大如何处理?)
kafka做削峰 flink做数据实时流数据的处理 落库 日志型的数据一般采用列式存储 非常有代表性的就是clickhouse可以去用它,六边形战士Postgrad sql
4、上报完数据清洗和数据汇总
5、数据分析
6、可视化图表 monitor
_一_般项目不能把scourcemap文件上传到生产环境,那怎么定位报错问题?
企业级性能与异常监控平台,可以托管sourcemap文件,通过sourcemap定位到源码
做过监控设计?那前端性能与异常监控指标怎么样?
性能指标:FP FCP FMP CLS LCP TTI INP
function lcp() {
new PerformacnceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length - 1];
cons lcpTime = lastEntry.startTime;
}
).observer({
type: "largest-contentful-paint", buffered: true
})
}
异常监控:
异常有哪些?内存溢出 白屏(MutaionObserver) 资源加载异常(img font) JS执行异常(异常监听) 异步处理异常(promise,unhandlerejection) 请求(网络)异常
// 资源异常,胡乱一个图片地址
<img src="http://www.xx.wxx.com" onerror="() => {}" />
window.addEventListener('error', (event) => {
console.log(event);
}, false)
window.onerror = (message, source, lineno, colno, error) => {
console.log('js异常:', message, source, lineno, colno, error)
}
上报方式
- img.gif, 动态创建 img, src 为上报地址(为什么用图片来做,跨域问题)
- fetch
- navigator.sendBeacon
上报时机
batch + requestIdleCallback
数据处理
后端:Nestjs
消息队列:kafka
实时数据加工:Flink
数据落库:clickhouse
查询数据
可视化:json echarts d3
性能优化做了什么?具体优化用什么数据来衡量?
打包构建,工程层面
代码,懒加载 异步加载 虚拟列表 tree shaking(esm)
网络,https cdn prefetch preload
用户行为埋点?
SDK 埋点
埋点类型:
手动埋点,侵入型比较强;
无痕埋点,对于服务端压力比较大,所有操作都会上报(事件冒泡eventpath来处理),document.addEventListerner('click', () => {});
可视化埋点
常规指标:pv uv 跳出率 回话时长 取决于运营指标
Ant Design组件库架构设计?
组件库?通用库结构设计?
组件库方案选型?细节设计与实现?
组件库构建发布与持续迭代?
定义好theming(样式体系):
UI设计把组件设计好,组件库的色值它的基础组件,变体不同的形态颜色等属性,设计体系也有tokens概念
- color tokens颜色色泽系统
- 样式模块化方案:css-in-js(弊端:运行时的样式框架,运行时的性能损耗),module css
文字排版 size
图标
阴影 圆角 间距
开发组件库吗?说说你的设计与开发思路?
架构设计:
业务架构:
- 分层设计
1、rc-xxx提供基础组件,unstyled (或者 headless ) component只具备功能交互不具备ui表现,可以理解成封装的组件样式都是通过使用地方传入props进来
2、样式体系,theming赋予1的ui表示整体完成ui库组件风格
3、基础组件
4、复合组件
5、业务组件
- 解耦
对于每个组件都需要定义样式、ts类型、基础操作、工具方法到对应文件夹里存放
- 响应书设计
媒体查询、resizeObsever、Grid
- 状态管理
1、全局状态,基础配置 国际化配置 主题配置,react (Context)vue(vue-demi)
2、局部状态,表单场景,受控 非受控
- 模块化
可复用性 公共方法(@ant-design/utils 工具函数)
- 组件库开发流程
1、工程架构:monorepo, core(主函数包)+components+hooks+utils+shared 每个包都是各独立的npm
2、TS选择
3、流程化 规范化 自动化,script如何定义(CI CD 的源头),规范化:eslint9 stylelint spellcheck commitlint;自动构建 增量构建
4、构建打包:rollup / esbuild
5、测试,单元测试jest
peerDependencies react react-dom typescript
组件的数据协议设计(组件属性设置,组件事件设置)组件属性传递
请从零到一实现一个组件库基础框架
- 技术选型与方案评审
1、包管理:pnpm workspace 多包管理
2、语音选择:typescript
3、打包构建:roollup esbuild
4、样式管理:css-in-js
5、组件组织:模块化设计与分层
6、测试jest
7、CI CD
8、构建产物发布
初始化工程 依赖选择 ts配置 构建配置 monorepo分包 组件库文档编写
构建发布: pnpm build npm publish
组件文档发布:选择docker,nginx静态资源托管处理
9、版本管理 `np`
版本号规则
1.0.0 主.次.修复
x.x.x-alpha 内测版
x.x.x-beta 公开测试发行版
x.x.x-rc 最终版,稳定可上线正式版
Babel有了解过吗?基础使用及原理?
babel用来做什么?
将高版本(ECMA)js转为低版本js
将typescript转为js
降级处理,polyfill,vite esbuild,rollup
taro早期就是使用了babel将react语法转为小程序
插件化机制实现,预设机制preset
预设是为了给开发者足够的便捷,babel又在插件的基础上封装了一层,预设包含很多的插件组合一起
编译原理?有没有了解编译原理,了解过编译器的底层实现吗?
代码的本质是什么?
字符串,编辑其实就是字符串的操作
字符串语义化些,语句、说话
语法,这些词连起来组成句子,才能把事物说明白
编译原理简单理解就是把一句话转为为其他的说话,加修饰转化过去
分词分析(将句子劈开—分词totenizer分词器)(token)
大 家 好 , 今 天 是 周 一
语法分析(组合起来成词)(连字成词)(parser 形成ast)
大家 好,今天 是 周一
语义分析(组合成句)
生成器(generate)or 执行器(interpret)
1、将句子劈开—分词器
2、分词链接—词法分析
3、分词处理理解—语义分析
4、生成器generator,执行器interpretor
程序里面没有什么特征不能用json来描述的
- 低代码平台 —> dsl(domain specific language)领域特定语言
- 代码 —>ast,Abstract Syntax Trees
ast优先级如何处理?,平衡二叉树 反转
之前的项目当中比较棘手的难点有哪些?
一面:
小程序 h5 N端工作量 x N
组件同构化
- 自研了跨端框架(类型Taro)
- 跨端实现原理
dsl协议,类似ast
编译时compile与运行时runtime
插件化
单位 px rpx —>babel-plugin-px2rem babel-plugin-px2rpx
层次感?总分 ->1、N端小程序的适配 2、编译时compile与运行时runtime的处理 3、插件化;再对某个点细化来说
框架本身都有生命周期,自研小程序生命周期和钩子,事件循环机制怎么理解?说下生命周期和钩子如何处理,然后过渡到事件循环机制?
生命周期
钩子实现 钩子注册
为什么需要有个事件循环机制?js单线程 同步任务 ->微任务队列
fiber react发展历史 req
- stack reconciler -> fiber reconciler
- scheduler
谈谈你对函数式编程的理解?
开放性题目
1、什么时函数编程
纯函数 不可变性 函数组合 高价函数
OOP 面向对象
2、FP优势
3、在你项目的应用
4、开源社区,前端生态为什么拥抱FP
vue3抛弃option api拥抱comositon api
低代码编辑器undo redo实现思路
快照 snapshot,存一个临时变量下次进入的时候拿到快照恢复
指令集(指令队列)
优化:- 怎么调研方案 - undoRedoManager -> (plugins: xx) 类型 axios.interceptors AOP(面向切面编程)
二面:
前端异常监控用户、行为埋点
基于sentry
性能指标
- 发现sentry性能指标问题
- 尝试自己优化性能指标采集 Performance MuationObserver ResizeObserver
MuationObserver ResizeObserver有什么性能问题?
trigger 优化 借鉴fiber思想
性能优化?
交代背景:是做首屏加载优化还是 应用层优化 动效优化 资源优化
指标支持LCP FP是多少 优化之后多少
资源优化
怎么实现
三面:
团队中间最大的贡献?
低代码物料系统管理,200个物料组件,AtomComponent 原子组件 仓库融合不好管理
物料管理平台
编码规范分享 推进技术分享
CICD 组件发布全流程发布管理
卡点设计:devops 工作流的设计 pipeline 源拉取 代码检测卡点(eslint stylelint commitlint unittest)
定义发布规范
形成文档组件
现在团队怎么保证代码质量和研发节奏
- 代码规范
- code review
-unittest jest 覆盖主流程
研发节奏和产品 测试有效沟通在前期把估时顺利交付
敏捷
跨部门沟通
结束:有什么想问我的地方?
加入进来的话,负责什么业务,我提前去了解一下
有什么挑战等着我
对接技术的追求
有没有了解Echarts 或 Antv原理吗?简单说下?
- 合理的数据协议(数据结构 setOptions)
- 针对不同场景需要不同渲染引擎:
canvas:位图,优点:性能更好 webgl -> skia(chore)缺点:事件交互都需要自己实现(点阵计算)因为没有真实dom节点(缓冲区)
svg:矢量图,任意缩放,canvas优点就是svg的缺点,缺点性能较弱,无法渲染大数据量
对应到可视化场景,选择什么技术?
图形学:
坐标系 直角
样式体系
可视化引擎设计与开发细节?
架构层面分析
数据层处理 渲染层处理 工具层 交互 动画体系 布局系统
你之前的项目工程化规范是怎么定的,你怎么看项目规范化这个问题?
提要:工程化,规范化是为来解决什么问题?
代码风格 文件名字 目录结构 提交规范统一化
目的项目可维护性 一致性 可读性,成员协作
细化:
- 文件结构
- 代码规范,变量命名,函数,风格统一,eslint9+prettier+stylelint
- 提交规范
- 单词拼写规范
这一切都需要以编译原理作为基础,操作代码,解析代码,eslint parser 转化代码后再对代码进行规范格式化操作
eslint,专门来做语言 js ts vue...的质量检查
eslint首先依然需要构建ast,前端工具链打包构建相关的工具他们没有一个标准,ast标准没有(ast:babel typescript eslint)
eslint规范约定:
- 规范等级:off wran error
- 核心规则:语法检查,变量命名了但是没有用,console没有删除;风格一致性,分号 空格 缩进 换行;实践 evel(重构:编译+js+sandbox) ,原型污染
- 大量的规范来控制这些代码编写
- eslint+prettier 集成
- ci cd `pnpm lint`
针对编码规范化,你在团队中都有过哪些尝试,ESLint 9有深入实践经验吗?
规范配置 文件配置 语言配置 ignores文件哪些需要检查
请以ESLint作者视角,拆解一下完备的前端代码规范校验与格式化工具架构?
- 核心引擎,eslint初始化 配置加载 文件解析 规则处理
- parser 解析器,转为ast expree/@typescript-eslint/parser
- rules 规则集
- plugins 插件
- 配置层
整体流程:
开始:代码输入
读取ESLint配置文件
选择适用的解析器(espree 解析js代码 babel parser 解析含有jsx或实验语法代码 typescript parser 解析ts代码)
生成ast
遍历ast节点
应用已配置的规则
节点是否符合规则?
符合 - 继续遍历 不符合报告提示或错误
解析结束
在你们团队沉淀专属eslint规范,通过插件集的沉淀以此来提升团队代码规范?如何编写插件?
- 插件
- 规则rule
- eslint 9使用规范
实例:不让团队成员使用 bamboo 来定义变量名称
- 针对这个规范需求编写一个rule 原理是通过ast (描述语言结构)节点来处理完成
- 将rule进行插件化 提供外部使用
- 将插件引入到eslint配置文件中,使用插件
rules/no-bamboo-vars.js
// 规则的本质是一个对象,约定好的对象
// 插件化体系里,这个对象的属性约束就是我们所说的插件化协议
{
meta: {
noBamboovars: "不允许使用baoboo变量" }, // 插件元信息
create(context) {
// babel也是是这个是访问者模式,访问到某一个ast的节点,就进行处理
Identifier(node) {
console.log(node)
if (node.name === 'bamboo') {
context.report({
node,
messageId: "noBamboovars",
data: {
name: node.name
}
})
}
}
} // 插件入口,上下文
}
plugins/eslint-plugin-bamboo.js
// 插件的本质是对象,符合插件的基础协议
import { noBamboovars } from 'rules/no-bamboo-vars.js';
export const eslintBambooPlugin = {
rules: {
"no-bamboo-vars": noBamboovars
}
}
eslint.config.js
import { eslintBambooPlugin } from 'plugins/eslint-plugin-bamboo.js'
export default [
{
plugins: {
bamboo: eslintBambooPlugin // 插件定义好以后,插件名称就是规则的作用域
},
rules: {
"bamboo/no-bamboo-vars": "error"
}
}
]
微前端?核心概念?
基座生命周期,基座只需要关心子应用的:
- 初始化:bootstrap
- 挂载:mount
- 卸载:unmount
注册子应用需要的什么配置?
1、应用名称
2、统一入口(子应用的接入协议:指的就是上面的三个子应用bootstrap mount unmount)
3、路径匹配
// single-spa为例
import { registerApplication, start } from "single-apa";
registerApplication({ name: 'app1',
app: {
bootstrap: bootstrap1,
mount: mount1,
unmount: unmount1
},
activeWhen: ['/app1']
})
start()
webpack5
Module Federation (umi) 微前端:动态共享单个组件,也可以共享整个应用组成微前端
如果你接下来实现的是低代码、物料平台、统一调度中心等等,远程物料的管理更好
你们低代码平台的物料是怎么管理的,远程物料是怎么加载的,请详细说下核心流程与方案?
插件化设计
webpack eslint vue babel vite,都有插件化的身影,如
{
plugins: [
vue(), // 负责vue相关代码
react(), // 负责react相关代码
splitChunk()
]
}
- 插件化基座
- 插件化协议
- 插件整个生命周期
- 插件开发
不管物料管理还是通用化的资源管理都可以是插件化管理
所以这些很多的插件组合成了这种低代码平台的物料体系
具体模块化定义
物料首先要取名,Button Image Text Container
物料最重要的两个东西是什么?
- 数据协议,json 数据
// 数据协议
type ButtonBlock = {
type: 'button',
props: {
text: string;
},
style: {
color: string;
},
events: {
}
}
- 物料渲染引擎,组件将json数据渲染成页面内容,引擎有点神话简单理解抽离组件,然后对应的组件及物料,放置到 :is去渲染
渲染始终关联两个点:它是什么类型?它是是数据?
有这两个概念我们就需要设计个统一的一个渲染器,Renderer(通过策略模式来负责数据转化加工、数据到组件的传递、组件渲染)
vue <component :is={Button}></component>
react children 插槽
远程物料只有满足数据协议定义和物料引擎的渲染即可
插件化设计在物料管理中的应用
插件化思想可以简单理解和发布订阅,注册规则类似;像vue.use() 的插件化
看你的简历写了自研低代码远程物料管理基座与页面编排渲染引擎,说说核心实现以及详细技术点?
远程物料
- 发布
1、物料协议统一
2、产物模块化规范
- 构建
- 渲染
pnpm-workspace.yaml
tsup 是一款基于 esbuild 的 TypeScript 库打包工具,无需配置即可使用。
packages
blocks
tsup.config.js/ts
vue defineAsyncComponent 可以获取到远程物料来消费
远程物料优化与扩展
缓存优化,本地存储
CDN加速,将远程物料部署到CDN提高加载加速
版本管理,为远程物料添加版本控制v1.2.2,避免兼容问题
存量数据处理?
后端做数据升级;前端和后端共同来去沟通降级兼容方案;想办法在版本控制好,在数据版本和物料版本对应的方案
作为leader说说低代码平台物料体系与编排引擎的核心思路、方案与成果?
基于flex布局引擎方式拖拽鼠标事件;定义标准的数据协议,支持复杂布局描述与动态配置;统一协议布局编排;数据动态更新持久化存储
请说说你之前负责的低代码平台都有哪些功能,具体什么业务,以及核心流程与方案?
优化前:
1、组件的拖拽
2、组件在页面中布局渲染
3、数据表
4、流程编辑
5、资源管理
优化后:
1、物料编排
2、物料渲染引擎
3、数据源管理
4、流程编辑器(负责配置)+流程引擎(负责执行(内存型流程,工作流流程引擎【OA 审批流 自动化批处理】))
5、资源中心(静态资源)
沉淀产物(monorepo packages):
1、layout-engine-sdk
2、material-renderer
3、online-database(千万行数据渲染 canvas-table)
4、flow-engine(flow-editor、flow-interpretor 执行)
5、resource(大文件上传)
### layout-engine
基础功能:
引擎分类(grid flex canvas(Figma) block)
### material-renderer
基础功能(渲染方式 设备兼容 主题定制(样式 token / 消费))
### online-database-sdk
canvas table
表设计(shema(管理字段)业务表(存储字段数据))
外部数据连接
monorepo设计实战,如何实现自定义构建流,怎样通过增量编译与缓存加快构建?
pnpm.workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
packages/
core
package.json
hooks
shared
ui
// 内部使用
"devDependencices": {
"@bamboo/core": "workspace:*"
}
统一的依赖管理 版本同步 模块共享 统一工具链 相同代码风格 统一CICD 增量部署
增量构建 构建缓存
turbo turbo.json
$schema tasks
你负责过项目前期的打包构建流程设计吗?有了解过哪些打包构建方案,请详细说说?
- babel - tsc -rollup - tsup - vite - webpack5
tsc: Typescript Compiler
rollup特点
tree-shaking,简化配置,丰富的插件生态,将功能的生态构建交给全世界开发者,框架插件规则制定者
tsup
基于esbuild的打包工具,默认支持ts零配置,性能非常好多格式输出,代码动态导入,代码分割
vite
整合esbuild rollup 按需加载 热更新 生产环境,rollup
webpack
自定义loader 和 plugin
- loading本质函数,转换资源,操作代码转为新代码
通过babel swc typescript esbuild tsup rollup 处理babel-loader swc-loading ts-loader...
- plugin本质对象(calss new),增强功能,有个apply方法,compiler参数是基于tapable实现的钩子
站在前端leader角度,从原理层面分析常规和新兴构建方案异同,详述rust重构工具链的优势?
表现出新技术的追求
rust驱动工具链:swc rurbo oxc 编译速度稳定性超越
性能 单线程瓶颈 内存安全稳定性 社区繁荣
内置支持ts es6+ 现代框架 未来可期
自动化、批处理生成式AI相关业务?流程引擎理解?
自动化、批处理:重复性认为,并且抽象层次比较高,将期望的任务列一个步骤,然后依次执行
流程引擎:自动化管理和执行既定的业务流程,业务流程:自动化处理 批处理 Ai生成详细过程
- 工作流流程建模(编辑器)
- 任务调度
- 继承外部系统 插件化实现流程功能生态
1、约定流程协议JSON(节点 node 定义功能,边 edge 用来约束节点流程)
2、编辑器编排工作流数据
3、开发工作流执行器
TS 7 微软发布用go重写 体验至少提升10%+
项目里执行npx tsc --init 自动生成tsconfig.json配置文件
extends
- 继承
- 泛型约束
class UserBlock {}
- 条件类型
type IsString = T extends string ? 'yes' : 'no'
- infer(用来做类型推断)结合,提取bm类型,现在bm后面可能bm1 bm2...
type BambooName = 'hello, bm';
// 提取BambooName中的bm
type ExtractName = T extends `hello, ${infer Name}` ? Name : never
let bmName: ExtractName // bm
// 从函数中提取参数类型和返回值类型
const say = (a: number) => `${a + 1}`;
type ExtractParamsAndReturn<T> = T extends (...args: infer Params)
=> infer Return ? [Params, Return] : never
// 定义返回都行
type ExtractParamsAndReturn<T> = T extends (...args: infer Params)
=> infer Return ? { u: Parsms, v: Return } : never
let sayType: ExtractParamsAndReturn<typeof say>;
infer
- 类型提取
interface接口一般情况下用来抽象对象的特征,属性 方法,一种面向对象编程思想
接口可以被继承 实现,type不能(联合 交叉)
可以结合泛型使用
接口可以声明可以合并,type不会
如果想把几个接口合并做个联合实现不了,这个时候就借助type来 |联合,type定义类型别名
使用场景:
interface:面向对象 接口继承场景下,优先
**type:**复杂类型,频繁派生新类型,例如类型推到出来新类型,优先
泛型:在使用时才知道类型,解决定义不明确类型的问题
1、函数的参数类型不明确
2、类的属性类型不明确
3、类的方法返回值类型不明确
4、工具类型在做类型处理的时候不明确类型
Nodejs开发过服务端?
架构设计
monorepo架构
分层:
请求、响应(Controller)
服务核心层(Service)
消息机制(kafka flink clickhouse)
缓存(内存 redis)
数据持久化层(Postgresql)
数据中台
结构设计(松散, IoC(依赖注入) AOP,思想:函数式编程 响应式编程rxjs)
websocket
打怪升级,连接的时候使用http协议,连接完协商升级协议
upgrade升级协议标志
处理数据帧 帧缓存Buffer处理 标志位
登录安全
身份认证,cookie、jwt、双token、cokie+token、OAuth2
单点登录,oss
巨量数据具体怎么优化?
虚拟表格/列表,首屏渲染数据量非常大
canvas + 可视区
详细说说webpack5工程化配置细节,常见配置和优化手段?
Vite 对比,bundleless(esm)、webpack bundle工具
模块化支持
构建过程
编译环节(编译时)
优化输出
架构层(钩子函数(hooks),执行时机(执行时函数预埋好),Tapable(tap用于向钩子注册事件处理函数;call用于触发钩子执行;promise用于返回一个promise对象,支持异步钩子;全流程)
webpack使用了Tapable管理插件的钩子;插件在构建过程中通过apply beforeRun done等与构建流程进行交互;每个插件可以通过钩子接入到webpack的构建周期中,在构建前、构建中、构建后执行自定义操作。
// webpack.config.js
export default {
entry: {
main: "src/index.js"
}, 单入口
entry: [], 多入口
output: {
filename: "[filename].[contenthash].js",
clean: true, === CleanWebpackPlugin 零配置
environment: {
arrowFunction: false
}
},
黑盒:编译 转化 优化 压缩,抽象成loader plugin
loader 本质是个函数 plugin本质是一个类对象
module: {
rules: {
test: /\.js/
use: {
loader: "babel-loader"
}
}
},
plugins: [new HtmlWebpackPlugin({
template: "./public/index.html"
})],
以前,CommonsChunkPlugin,SplitChunksplugih,现在5只需要配置optimization属性
optimization: {
压缩 拆分等等
minimize: false,
chunks 拆分
splitChunks
},
mode: "development"
}
有没有了解过微内核设计思想?webpack5多loader plugin设计思想是怎样完成个性化打包构建需求的?
loader 本质是个函数 plugin本质是一个类对象,两者都是微内核实际思想的具体落地
webpack5核心执行过程主要包括了以下4个阶段:
1、初始化阶段
创建webpack实例并加载用户的配置文件webpack.config.js
解析配置文件,处理配置中entry output module(模块规则)等配置项
2、编译阶段
初始化时创建一个Compiler实例,负责整个构建过程
处理模块根据entry配置项从入口开始递归处理所有依赖模块
模块解析根据配置详细解析模块路径
3、构建阶段
生成模块,所以模块都被打包成一个个chunk代码块,并输出文件
执行插件钩子,tap emit done afterEmit等
4、输出阶段
生成输出文件,根据output配置生成最终打包文件
执行插件钩子
详细说说vite5工程化配置细节,常见配置优化手段?
bundleless - 少打包,浏览器esm支持
- 模块化规范,commonjs and cmd esm umd
- 浏览器esm拥抱新技术
- 本地生成构建提速,本地esbuild、生产rollup可能会产生与本地构建产物差异问题?(VoidZero - rolldown oxc)
- 产物构建优化,rollup优化
了解微内核设计思想吗?vite5的插件化设计思想是怎样完成个性化打包构建需求的?
- 插件化设计思想(插件化底座:底层的那个调度器叫插件化底座 插件协议,数据协议定义方式 生命周期钩子)
- 自定义插件(config transform transformIndexHtml generateBundle)钩子
vite插件本质是个函数返回,在上面插件钩子操作想做的事情
从零到1实现vite?
bundleless 统一化ast统一工具链描述语言 vite - oxc - rolldown - vitest
打包构成:
1、初始化,vite.config.ts
2、解析入口,两种解析形式(应用构建,html script;子包、构建产物,build)
3、插件底座初始化,插件生命周期调度
4、优化处理
5、拆分
6、输出代码
7、资源优化
const app = express()
// 中间件设计,AOP 面向切面编程
app.use('/*.js', (req, res) => {
const reqPath = req.path;
const file = fs.readFileSync(path.resolve(__dirname, `.${reqPath}`), 'utf-8');
// 很多处理都是在这里来做
// 编译 插件处理 esbuild做编译 swc做编译 babel 做编译 rollup做编译
// 产物的处理 产物的压缩 产物的混淆
res.type('js') // 返回类型js文件
res.send(file)
})