快手主站二面
- 事件循环相关代码输出分析
可以参考这一个练习
- 如何判断元素是否在视口
判断元素是否在视口内,主要有两种方法:
Intersection Observer API
(推荐,现代、高效)Element.getBoundingClientRect()
(传统,兼容性好但性能稍差)
特性 | Intersection Observer API | getBoundingClientRect() |
---|---|---|
性能 | 极高,异步,不阻塞主线程 | 较差,同步操作,高频触发会引起重排,需手动优化 |
使用复杂度 | 简单,声明式 | 相对复杂,需要手动计算和事件绑定 |
功能 | 强大,支持阈值、自定义根元素 | 基础,只能获取位置,逻辑需自己实现 |
代码可读性 | 好,意图清晰 | 一般,计算逻辑和事件处理混在一起 |
兼容性 | 现代浏览器 (IE 不支持) | 非常好,兼容所有主流浏览器 |
核心思想 | 告诉浏览器:“当这个元素进入/离开视口(或者与另一个元素交叉)时,请通知我。” | 在 scroll 、resize 等事件中,不断调用 getBoundingClientRect() 获取元素的位置,并与视口的尺寸 (window.innerHeight , window.innerWidth ) 进行比较。 |
- 浏览器工具中的 ‘Performance’(性能)有什么用
简单来说,它的核心作用是:记录、分析和可视化你的网页在运行期间(Runtime)的所有活动,帮助你找到导致页面卡顿、缓慢或无响应的性能瓶颈。
具体可以查看Chrome官方的开发者文档
- 如何提升首屏加载速度
可以关注这两个指标(可以在性能页面找到):
- FCP (First Contentful Paint):首次内容绘制。浏览器首次在屏幕上渲染出任何 DOM 内容(文本、图片、Canvas 等)的时间点。这是用户感知到“页面活了”的第一个信号。
- LCP (Largest Contentful Paint):最大内容绘制。视口内最大的图像或文本块完成渲染的时间。它衡量了主要内容对用户的可见速度。
具体提升方法:
优先级 | 优化项 | 效果 | 实现难度 |
---|---|---|---|
极高 | 开启 Gzip/Brotli 压缩 | 显著 | 低 |
极高 | 使用 CDN 加速静态资源 | 显著 | 中 |
极高 | 图片优化(压缩、WebP、懒加载) | 显著 | 低-中 |
高 | 服务端渲染 (SSR) / 静态生成 (SSG) | 巨大 | 高 |
高 | JS 使用 defer 并置于底部 | 显著 | 低 |
高 | 代码分割 (Code Splitting) | 显著 | 中 (框架已支持) |
中 | 代码压缩 (Minify) | 明显 | 低 (构建工具) |
中 | 提取并内联关键 CSS | 明显 | 中 |
中 | 利用浏览器缓存 | 明显 | 中 |
低 | DNS 预解析 | 略微 | 低 |
- Vue中的 nextTick 有什么用
nextTick
是一个让你在下次 DOM 更新循环结束之后执行延迟回调的工具。
你通常在以下情况需要使用 nextTick
:
- 获取更新后的 DOM 元素属性:
- 在一个列表数据更新后,获取列表的实际高度或宽度。
- 在一个元素通过
v-if
从false
变为true
后,立即获取该元素的尺寸或对其进行操作。
- 操作新生成的 DOM 元素:
- 在一个元素通过
v-if
显示后,立即对其聚焦 (focus)。这是一个非常经典的例子。
- 在一个元素通过
- 集成需要操作 DOM 的第三方库:
- 当数据更新导致图表或某些 UI 插件需要重新渲染时,你需要在
nextTick
回调中调用该库的初始化或更新方法,以确保它能操作到最新的 DOM 结构。
- 当数据更新导致图表或某些 UI 插件需要重新渲染时,你需要在
- 如何实现缓存
这个范围比较广,主要从几个方向答,http协议提供的缓存,强缓存和协商缓存;然后js提供的缓存,sessionStorage和localStorage;然后项目实现中的缓存,也就是内存中的缓存。
- 项目相关
- 从零设计一个组件,比如说弹窗组件,会考虑什么?如果需要自定义样式,可以怎么做?
设计props,events和slot,保证其易用性;提前规定好组件会有一些什么行为;考虑可访问性(保证残障人士的使用);
自定义样式的部分,可以:
- 暴露CSS自定义属性,用户可以在自己的CSS的文件或者父容器中定义
- 提供稳定的CSS类名,允许用户进行覆盖
- 通过style、className等相关的props,让用户可以直接注入内敛样式或者类名
- 项目中为什么要同时用Vite + Webpack
- 函数式编程,面向对象编程和过程式编程之间的区别是什么
特性 | 过程式编程 (PP) | 面向对象编程 (OOP) | 函数式编程 (FP) |
---|---|---|---|
核心思想 | 按步骤执行一系列指令 | 模拟现实世界,将事物抽象为对象 | 将计算描述为数学函数的求值 |
关注点 | 过程 (How):如何一步步完成任务 | 对象 (Who/What):谁拥有数据,谁负责行为 | 转换 (What):数据如何流动和转换 |
数据与行为 | 分离:数据结构和操作数据的函数是分开的 | 封装:数据(属性)和行为(方法)被捆绑在对象内部 | 分离:数据(通常是不可变的)和操作数据的纯函数是分开的 |
状态管理 | 通过可变变量,状态是共享和可变的,容易产生混乱 | 状态被封装在对象内部,由对象自己管理 | 避免可变状态,强调数据不可变性 (Immutability) |
主要单元 | 函数、过程 | 类、对象、实例 | 纯函数、高阶函数 |
代码示例 | 使用循环和可变累加器 | 创建一个类,通过实例方法计算 | 使用 map , reduce 等高阶函数链式调用 |
- 手撕:拍平数组并且去重和排序,括号匹配
- 如何学习新的技术栈,印象深刻的学习经历