7-3 H5页面如何进行首屏优化
- SSR
- 预取
- 分页
- 图片 lazyLoad
- hybrid
7-4 后端一次性返回10w条数据,你该如何渲染
- 沟通需求和场景,给出自己合理的设计建议
- 虚拟列表
7-5 扩展:文字超出省略
7-6 前端常用的设计模式和使用场景
传统的经典设计模式有 23 个,作为面试题只说出几个前端常用的就可以。
- 工厂模式
- 单例模式
- 代理模式
- 观察者模式
- 发布订阅模式
- 装饰器模式
7-7 【连环问】观察者模式和发布订阅模式的区别
7-8 在实际工作中,你对Vue做过哪些优化
- v-if 和 v-show
- v-for 使用 key
- computed 缓存
- keep-alive
- 异步组件
- 路由懒加载
- SSR
7-9 【连环问】你在使用Vue过程中遇到过哪些坑
全局事件、自定义事件要在组件销毁时解除绑定
- 内存泄漏风险
- 全局事件(如
window.resize
)不解除,则会继续监听,而且组件再次创建时会重复绑定
Vue2.x 中,无法监听 data 属性的新增和删除,以及数组的部分修改 —— Vue3 不会有这个问题
- 新增 data 属性,需要用
Vue.set
- 删除 data 属性,需要用
Vue.delete
- 修改数组某一元素,不能
arr[index] = value
,要使用arr.splice
API 方式
路由切换时,页面会 scroll 到顶部。例如,在一个新闻列表页下滑到一定位置,点击进入详情页,在返回列表页,此时会 scroll 到顶部,并重新渲染列表页。所有的 SPA 都会有这个问题,并不仅仅是 Vue 。
- 在列表页缓存数据和
scrollTop
- 返回列表页时(用 Vue-router 导航守卫,判断
from
),使用缓存数据渲染页面,然后scrollTo(scrollTop)
7-10 7-11 在实际工作中,你对React做过哪些优化
- 循环使用 key
- 修改 css 模拟
v-show
- 使用 Fragment 减少层级
- JSX 中不要定义函数
- 在构造函数 bind this
- 使用 shouldComponentUpdate 控制组件渲染
- React.memo 缓存函数组件
- useMemo 缓存数据
- 异步组件
- 路由懒加载
- SSR
7-12 【连环问】你在使用React时遇到过哪些坑
JSX 中,自定义组件命名,开头字母要大写,html 标签开头字母小写
{/* 原生 html 组件 */}
<input/>
{/* 自定义组件 */}
<Input/>
JSX 中 for
写成 htmlFor
, class
写成 className
{/* for 改成 htmlFor ,class 要改为 className */}
<label htmlFor="input-name" className="xxx">
姓名 <input id="input-name"/>
<label>
state 作为不可变数据,不可直接修改,使用纯函数
// this.state.list.push({...}) // 错误,不符合 React 规范
this.setState({
list: curList.concat({...}) // 使用**不可变数据**
})
JSX 中,属性要区分 JS 表达式和字符串
<Demo position={1} flag={true}/>
<Demo position="1" flag="true"/>
state 是异步更新的,要在 callback 中拿到最新的 state 值
const curNum = this.state.num
this.setState({
num: curNum + 1
}, () => {
console.log('newNum', this.state.num) // 正确
})
// console.log('newNum', this.state.num) // 错误
React Hooks 有很多限制,注意不到就会踩坑。例如,useEffect
内部不能修改 state
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1) // 如果依赖是 [] ,这里 setCount 不会成功
}, 1000)
return () => clearTimeout(timer)
}, [count]) // 只有依赖是 [count] 才可以,这样才会触发组件 update
return <div>count: {count}</div>
}
export default App
再例如,useEffect
依赖项(即第二个参数)里有对象、数组,就会出现死循环。所以,依赖项里都要是值类型。[HTML_REMOVED]
因为 React Hooks 是通过 Object.is
进行依赖项的前后比较。如果是值类型,则不妨碍。
如果是引用类型,前后的值是不一样的(纯函数,每次新建值),就类似 {x:100} !== {x:100}
useEffect(() => {
// ...
}, [obj, arr])
7-13 如何统一监听Vue组件报错
方式
errorCaptured
监听下级组件的错误,可返回false
阻止向上传播errorHandler
监听 Vue 全局错误window.onerror
监听其他的 JS 错误,如异步
建议:结合使用
- 一些重要的、复杂的、有运行风险的组件,可使用
errorCaptured
重点监听 - 然后用
errorHandler
window.onerror
候补全局监听,避免意外情况
7-14 如何统一监听React组件报错
- ErrorBoundary 监听渲染时报错
try-catch
和window.onerror
捕获其他错误
7-15 如果一个H5很慢,如何排查性能问题-通过Chrome Performance分析
7-16 如果一个H5很慢,如何排查性能问题-使用lighthouse分析
- 通过工具分析性能参数
- 识别问题:加载慢?渲染慢?
- 解决问题
- 增加性能统计,持续跟进、优化
7-17 工作中遇到过哪些项目难点,是如何解决的
找到一个问题,按照下面的套路回答
- 描述问题:背景,现象,造成的影响
- 问题如何被解决:分析、解决
- 自己的成长:从中学到了什么,以后会怎么避免
PS:这不是知识点,没法统一传授,我的经验你拿不走,只能靠你自己总结。
7-18 扩展:处理沟通冲突
- 经常遇到哪些冲突
- 解决冲突
- 自己如何规避冲突
总结:
PS:最好再能准备一个案例或者故事,效果会非常好,因为人都喜欢听故事。
- 性能优化的实践
- 设计模式的应用
- 错误监控的实践