面试题答案
一键面试数据预取优化
- 在服务器端预取数据
- 方法:在服务器端路由守卫或生命周期钩子中,提前获取需要的数据。例如,在 Vue Router 的
beforeEnter
守卫中,调用 API 获取数据,再将数据填充到 Pinia 的 store 中。 - 示例代码:
import { useStore } from '~/store' export default function (to, from, next) { const store = useStore() store.fetchInitialData().then(() => { next() }).catch((error) => { // 处理错误 next({ name: 'error', params: { statusCode: 500 } }) }) }
- 方法:在服务器端路由守卫或生命周期钩子中,提前获取需要的数据。例如,在 Vue Router 的
- 避免重复预取
- 方法:可以通过在 store 中添加标志位,记录数据是否已经预取过。在预取数据前先检查标志位,避免重复调用 API 造成性能浪费。
- 示例代码:
import { defineStore } from 'pinia' export const useStore = defineStore('main', { state: () => ({ data: null, isDataFetched: false }), actions: { async fetchInitialData() { if (this.isDataFetched) { return } const response = await fetch('/api/data') this.data = await response.json() this.isDataFetched = true } } })
状态序列化优化
- 选择合适的序列化方式
- 方法:JSON.stringify 是最常用的序列化方法,但对于复杂数据结构可能存在问题,比如函数、循环引用等。可以使用诸如
serialize-javascript
库,它能处理更复杂的数据结构。 - 示例代码:
import serialize from'serialize-javascript' const store = useStore() const serializedState = serialize(store.$state)
- 方法:JSON.stringify 是最常用的序列化方法,但对于复杂数据结构可能存在问题,比如函数、循环引用等。可以使用诸如
- 减少序列化数据量
- 方法:只序列化必要的数据。例如,一些临时状态(如 loading 标志)在客户端渲染时可以重新计算,不需要序列化。
- 示例代码:
import { defineStore } from 'pinia' export const useStore = defineStore('main', { state: () => ({ importantData: null, loading: false }), getters: { serializableState(state) { return { importantData: state.importantData } } } }) const store = useStore() const serializedState = serialize(store.serializableState)
内存回收优化
- 及时释放服务器端内存
- 方法:在每个请求处理完成后,手动清除不再需要的 Pinia store 实例或数据。例如,可以在服务器端的请求处理中间件中,在响应发送后,清除相关的 store 数据。
- 示例代码:
import { useStore } from '~/store' app.use((req, res, next) => { const store = useStore() // 处理请求 res.on('finish', () => { // 手动清除store中的一些临时数据 store.resetTemporaryData() }) next() })
- 避免内存泄漏
- 方法:确保在服务器端没有对 store 实例的持久引用,防止旧的实例占用内存。例如,不要在全局变量中保存 store 实例,而是在每个请求中创建新的实例。
- 示例代码:
// 错误示例 let globalStore app.use((req, res, next) => { if (!globalStore) { globalStore = useStore() } //... }) // 正确示例 app.use((req, res, next) => { const store = useStore() //... })
可能遇到的问题及解决方案
- 数据一致性问题
- 问题:在服务器端预取数据并序列化后,客户端渲染时可能由于网络延迟等原因,导致数据不一致。
- 解决方案:在客户端重新获取数据时,进行版本控制或数据比对。例如,在服务器返回数据时带上版本号,客户端在重新获取数据时,比较版本号,如果不一致则重新获取。
- 序列化错误
- 问题:复杂数据结构如循环引用、函数等在序列化时会出错。
- 解决方案:如前文所述,使用
serialize - javascript
库处理复杂数据结构,或者在序列化前对数据进行预处理,移除无法序列化的部分。
- 内存占用过高
- 问题:服务器端处理大量请求时,由于没有及时释放内存,导致内存占用过高。
- 解决方案:严格按照上述内存回收优化方法,在每个请求处理完成后及时释放不再需要的资源,避免内存泄漏。