欢迎光临
我们一直在努力

V1.6.1性能优化:高频路径提速与代码精简

v1.6.1 针对 isSameQuery 和 Object.freeze 两处高频执行路径进行优化,减少不必要的计算开销与重复代码

前言

v1.6.0 引入了 params 页面参数传递和查询参数增强方法,功能更加完整。但在实际使用中,路由状态管理存在两处可优化的细节:

  • isSameQuery 缺少空对象快速路径 — 每次导航、守卫执行、状态同步都会调用 isSameQuery,而空对象是常见场景
  • Object.freeze 逻辑分散 — meta、query、params 的冻结逻辑分散在 setCurrentRoute 和 createStartLocation 中,存在重复代码
  • v1.6.1 针对这两处进行优化,在不改变任何外部行为的前提下提升性能和可维护性。


    一、isSameQuery 空对象快速路径

    问题分析

    isSameQuery 在路由器内部被高频调用:

    • setCurrentRoute 中判断 from 和 to 是否相同
    • syncCurrentRoute 中比较当前查询参数
    • isSameRouteLocation 中作为路由位置比较的一部分

    原始实现无论查询参数是否为空对象,都会执行 Object.keys() 和 every() 遍历:

    // 优化前
    private isSameQuery(a: Record<string, string>, b: Record<string, string>): boolean {
    const keysA = Object.keys(a)
    const keysB = Object.keys(b)
    if (keysA.length !== keysB.length) return false
    return keysA.every(key => a[key] === b[key])
    }

    在空对象场景下(如首页导航、无参数跳转),Object.keys({}) 返回空数组,every 对空数组返回 true,虽然结果正确,但产生了不必要的函数调用开销。

    优化方案

    添加两层快速路径:

    // 优化后
    private isSameQuery(a: Record<string, string>, b: Record<string, string>): boolean {
    if (a === b) return true // 快速路径 1:引用相等
    const keysA = Object.keys(a)
    const keysB = Object.keys(b)
    if (keysA.length !== keysB.length) return false
    if (keysA.length === 0) return true // 快速路径 2:双空对象
    return keysA.every(key => a[key] === b[key])
    }

    快速路径 1:引用相等(a === b)

    当 a 和 b 是同一个对象引用时,直接返回 true。这种情况在路由状态未变化时(如重复导航检测)经常出现。

    快速路径 2:双空对象(keysA.length === 0)

    当 keysA.length === keysB.length 且 keysA.length === 0 时,说明两者都是空对象,直接返回 true。避免了 every 对空数组的调用。

    性能影响

    场景优化前优化后
    引用相等 Object.keys + every 直接返回 true
    双空对象 Object.keys × 2 + every Object.keys × 2 + 长度判断
    非空对象 不受影响 不受影响

    对于高频调用的导航场景(特别是无参数跳转),减少了不必要的 Object.keys 和 every 开销。


    二、Object.freeze 逻辑集中化

    问题分析

    v1.6.0 中,meta、query、params 的冻结逻辑分散在两处:

  • setCurrentRoute — 手动冻结 meta 和 query
  • createStartLocation — 手动创建冻结的初始对象
  • // 优化前:setCurrentRoute 中
    function setCurrentRoute(route: RouteLocation): void {
    const from = currentRoute
    currentRoute = {
    path: route.path,
    name: route.name,
    meta: Object.freeze({ route.meta }), // 手动冻结
    query: Object.freeze({ route.query }), // 手动冻结
    params: Object.freeze({ route.params })
    // …
    }
    }

    // 优化前:createStartLocation 中
    export function createStartLocation(): RouteLocation {
    return {
    path: '/',
    meta: Object.freeze({}), // 手动冻结
    query: Object.freeze({}), // 手动冻结
    params: Object.freeze({}) // 手动冻结
    // …
    }
    }

    这种分散存在两个问题:

  • 重复代码 — 冻结逻辑在多处重复,后续若需条件冻结(如开发模式跳过冻结),需改多处
  • 不一致风险 — 新增字段时容易遗漏冻结
  • 优化方案

    将冻结逻辑集中到 createRouteLocation 工厂函数中:

    // 优化后:createRouteLocation 中统一冻结
    export function createRouteLocation(base: { path: string; name?: string; meta: RouteMeta; query: Record<string, string>; fullPath: string; params?: ParamObject; _synced?: boolean }): RouteLocation {
    const query = Object.freeze(base.query)
    const params: Readonly<ParamObject> = base.params ? Object.freeze({ base.params }) : Object.freeze({})
    return {
    path: base.path,
    name: base.name,
    meta: Object.freeze({ base.meta }),
    query,
    params
    // …
    }
    }

    setCurrentRoute 和 createStartLocation 不再手动冻结,统一委托给 createRouteLocation:

    // 优化后:setCurrentRoute 中
    function setCurrentRoute(route: RouteLocation): void {
    const from = currentRoute
    currentRoute = createRouteLocation({
    path: route.path,
    name: route.name,
    meta: { route.meta },
    query: { route.query },
    fullPath: route.fullPath,
    params: route.params,
    (route._synced !== undefined && { _synced: route._synced })
    })
    // …
    }

    // 优化后:createStartLocation 中
    export function createStartLocation(): RouteLocation {
    return createRouteLocation({
    path: '/',
    meta: {},
    query: {},
    fullPath: '/'
    })
    }

    优化收益

    维度优化前优化后
    冻结逻辑位置 setCurrentRoute + createStartLocation createRouteLocation 一处
    代码行数 分散在多处 集中在工厂函数
    后续维护 改冻结策略需改多处 只需改 createRouteLocation
    一致性 手动保证 工厂函数自动保证

    升级指南

    v1.6.1 是纯内部优化,完全向后兼容,无需修改任何现有代码即可升级。

    本次优化不改变任何公共 API 的行为和签名,所有变更仅限于内部实现细节。如果你正在使用 v1.6.0,直接升级到 v1.6.1 即可享受性能提升。

    赞(0)
    未经允许不得转载:171主机测评 » V1.6.1性能优化:高频路径提速与代码精简
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址