模块分层和容器预热是做了什么,数据怎么测得
模块分层是只把首屏视口内的组件打入主bundle,其余需要滚动才进入视口的组件通过defineAsyncComponent + 动态import导入生成独立chunk,滚动到区域再加载,提高首屏加载速度
容器预热主要是针对秒杀这种高概率跳转场景做的优化,进入秒杀商品超过60s后触发预热,使用link-modulepreload来预下载和解析下单填写页模块,点击下单跳转后可直接开始渲染,省去了下载和解析的时间
体积是直接比较build后的体积,inp在main.js顶部埋点,Vue 实例创建之前,用的web-vitals,inp通常是页面刚加载完的场景是最大的,这时候主线程可能还在做其他任务,没法及时响应,首帧时间缩短是在路由跳转前埋点,使用performance.now标记现在时间,在mounted里结束,计算时间差值
多级资源预加载是做了什么
对资源按重要程度分为三个程度做预加载,首先最重要的首屏资源直接静态import立即加载,然后首屏下需要滚动才能看见的资源使用link-preload在lcp的回调里开始加载,link-proload的优先级比静态import的高,在lcp回调里加载可以避免抢占首屏带宽,lcp加载完时首屏基本已经加载完成,最后是弹窗这种的资源就放在ric里用link-prefecth加载或者到用到的时候再动态import加载
异步并发治理是做了什么
首先采用async/await控制接口执行顺序,避免一些接口的前置条件缺失,同时封装请求调度工具,对重复请求进行拦截,同时对于同接口不同参数高频请求,每次请求前取消旧请求避免竞态问题
大文件上传做了什么
首先通过slice方法对文件进行切片,然后用spark-md5进行增量md5计算,逐片读取计算,然后向后端询问已上传分片列表,过滤掉已上传的后继续上传,最后通知后端合并
说一下虚拟列表实现思路
首先计算整体高度,容器撑开实现滚动条,然后计算索引起始范围,开始索引是(scrollTop / itemHeight)- buffer,结束是开始索引加可视条数+2*buffer,通过索引范围slice可视子集,用translateY来偏移可视窗口模拟真实滚动效果,走GPU合成不会触发重排,对滚动事件用raf做节流,避免高频触发回调计算
实时搜索框竞态怎么解决的及封装思路
实现对输入搜索做防抖处理减少请求次数,然后每次请求先用controler.abort()取消之前的请求,同时用axios.isCancel过滤掉主动取消的请求,不进行错误弹窗,然后再发新的请求。
封装思路,参数传入搜索关键词keywords,请求函数及delay延迟,内部定义data和loading作为返回值,以及封装的核心:定时器和controller,还有清理函数,再使用wantch监听keywords,有变化先调用清理函数清理旧请求,然后新建控制器传入请求函数发送新请求,最后在卸载时自动清理
说一下流式对话的实现思路
正常发送fetch请求,用getReader从response.body上得到可读流对象,然后用read方法持续读取知道done为true,用TextDecoder对读取的流进行解码。和后端约定用双换行分割每条消息,收到的消息先存在buffer里,如果有完整的消息就取出来解析渲染,剩下的继续留在buffer里,解决粘包问题
对md做增量解析,以md中的空行做分割,每次解析的内容先放在暂存区,解析到空行就把暂存区的固化,添加到稳定区