HarmonyOS 7 把“冷启动网络预建”列为启动体验的重要增强方向。它解决的不是带宽不足,而是用户点击页面之后,DNS、建连、TLS 握手、鉴权和首个业务请求串行发生,导致首屏数据迟迟不能出现。真正的工程目标不是把所有请求提前发出去,而是在应用生命周期、隐私授权和业务一致性边界内,安全地把确定性网络准备移到关键路径之前。

本文从启动时序、候选请求、连接池、缓存语义、账号切换、失败降级和指标验收七个方面,给出一套可直接落地的冷启动网络预建方案。示例为架构化 ArkTS 伪代码,具体接口与可用范围应以目标 SDK 和设备文档为准。

HarmonyOS 7 新特性(四十一)封面

一、先把启动耗时拆开

“接口用了 800ms”没有诊断价值。至少要拆出进程创建、首帧、网络准备、首包和可交互时间。

interface LaunchTimeline {
  processStart: number
  firstFrame: number
  dnsReady?: number
  connectionReady?: number
  firstByte?: number
  contentReady: number
}

function duration(a?: number, b?: number): number | undefined {
  return a === undefined || b === undefined ? undefined : b - a
}

如果首帧本身就慢,优先处理主线程阻塞、同步 I/O 和资源解码;如果首帧很快但内容长时间骨架屏,网络预建才可能是主要收益点。不要用预连接掩盖 UI 初始化问题。

二、画出真实关键路径

典型首页会经历“读取本地账号—初始化网络栈—解析域名—建立安全连接—换取令牌—请求首页—解析渲染”。其中只有域名和目标服务稳定、且不携带用户业务参数的步骤适合提前。

type LaunchStep = {
  name: string
  dependsOn: string[]
  sideEffect: boolean
  needsAccount: boolean
}

const steps: LaunchStep[] = [
  { name: 'load-local-session', dependsOn: [], sideEffect: false, needsAccount: false },
  { name: 'prepare-connection', dependsOn: [], sideEffect: false, needsAccount: false },
  { name: 'refresh-token', dependsOn: ['load-local-session'], sideEffect: true, needsAccount: true },
  { name: 'load-home', dependsOn: ['refresh-token'], sideEffect: false, needsAccount: true }
]

预建的本质是重新安排依赖图,而不是跳过鉴权或权限检查。

三、候选请求必须通过白名单

适合预建的候选通常包括稳定域名的 DNS、TLS 会话、公共配置和匿名静态资源。不适合提前执行的是下单、写入、计费、曝光上报、精确位置查询以及任何会改变服务端状态的请求。

interface PrebuildPolicy {
  host: string
  allowAnonymous: boolean
  idempotent: boolean
  containsSensitiveQuery: boolean
  ttlMs: number
}

function canPrebuild(p: PrebuildPolicy): boolean {
  return p.allowAnonymous && p.idempotent &&
    !p.containsSensitiveQuery && p.ttlMs > 0
}

白名单要进入代码审查。不能只按 HTTP GET 判断安全,因为 GET 也可能产生曝光、领取或状态迁移。

四、连接预热与数据预取分层

连接预热只准备 DNS、TCP/QUIC 和 TLS,风险小、复用范围大;数据预取会拿到业务内容,必须处理缓存版本、身份和过期。两者应采用不同策略。

enum PrebuildLevel {
  CONNECTION_ONLY,
  ANONYMOUS_DATA,
  ACCOUNT_DATA
}

interface PrebuildTask {
  key: string
  level: PrebuildLevel
  deadlineMs: number
  cancel(): void
}

默认从 CONNECTION_ONLY 开始。只有指标证明首包仍是瓶颈,且数据语义足够稳定,才进入匿名数据预取;账号数据预取必须等待会话恢复完成。

HarmonyOS 7 新特性(四十一)核心链路

五、建立可取消的启动协调器

用户可能在启动过程中切换账号、切换网络或直接退出。预建任务不能成为无法停止的后台工作。

class LaunchPrebuildCoordinator {
  private tasks = new Map<string, PrebuildTask>()

  start(task: PrebuildTask) {
    this.tasks.get(task.key)?.cancel()
    this.tasks.set(task.key, task)
  }

  cancelAll(reason: string) {
    console.info(`cancel prebuild: ${reason}`)
    this.tasks.forEach(task => task.cancel())
    this.tasks.clear()
  }
}

在账号改变、应用退后台、网络从 Wi-Fi 切到蜂窝、隐私授权撤回和环境切换时调用取消。超出首屏时间预算的任务也应主动结束。

六、缓存键必须携带身份与版本

最危险的错误是 A 用户预取的数据在 B 用户页面上短暂出现。缓存键至少包含环境、接口版本、账号范围、语言、地区和业务参数摘要。

interface CacheScope {
  env: 'prod' | 'staging'
  apiVersion: string
  accountHash: string | 'anonymous'
  locale: string
  region: string
}

function cacheKey(scope: CacheScope, resource: string): string {
  return [resource, scope.env, scope.apiVersion,
    scope.accountHash, scope.locale, scope.region].join(':')
}

日志记录哈希或枚举,不记录令牌、手机号和完整 URL 查询参数。登出时清除账号域缓存,升级协议时提升 apiVersion

七、结果消费采用“双重校验”

预取完成时的上下文可能已经失效。页面消费前再检查账号、配置版本、数据时间和请求参数,而不是看到缓存命中就直接渲染。

interface PreparedResult<T> {
  value: T
  accountVersion: number
  configVersion: number
  createdAt: number
}

function isUsable<T>(r: PreparedResult<T>, now: number,
  accountVersion: number, configVersion: number): boolean {
  return r.accountVersion === accountVersion &&
    r.configVersion === configVersion && now - r.createdAt < 15_000
}

校验失败只意味着回到普通请求,不应阻断页面。

八、把失败设计成静默降级

预建不是启动前置门禁。DNS 失败、证书变化、超时、系统取消和服务器拒绝都应回退到原始路径。

async function loadHome(): Promise<HomeData> {
  const prepared = preparedStore.take<HomeData>('home')
  if (prepared && isCurrent(prepared)) return prepared.value

  return homeApi.fetch({ timeoutMs: 5000 })
}

禁止为了等待“快请求”而延迟首帧,也不要连续无上限重试。弱网下预建可能与用户真正请求争夺连接和带宽,因此需要并发上限和截止时间。

九、隐私和安全边界

隐私声明确认前,只能做不识别用户、不采集设备标识、不上传行为数据的连接准备。请求必须走 HTTPS,沿用应用既有证书校验和网络安全配置。不要为了提升命中率关闭证书校验、信任用户证书或把令牌写进预建日志。

interface PrivacyGate {
  noticeAccepted: boolean
  sessionReady: boolean
}

function allowedLevel(gate: PrivacyGate): PrebuildLevel {
  if (!gate.noticeAccepted) return PrebuildLevel.CONNECTION_ONLY
  if (!gate.sessionReady) return PrebuildLevel.ANONYMOUS_DATA
  return PrebuildLevel.ACCOUNT_DATA
}

安全约束优先级高于启动速度。

十、指标必须区分命中与未命中

只看总体平均值会掩盖问题。至少分别记录命中率、预建耗时、浪费率、首包改善、流量增量和失败回退。

interface PrebuildMetric {
  hit: boolean
  reason: 'HIT' | 'EXPIRED' | 'ACCOUNT_CHANGED' | 'FAILED' | 'NOT_ELIGIBLE'
  prepareMs: number
  firstByteSavedMs: number
  bytesWasted: number
}

对 P50、P90、P99 分位比较冷启动内容可见时间,并按网络类型、设备档位和账号状态分桶。命中率高但流量浪费严重,也不是成功。

十一、灰度与回滚

使用远端开关控制域名、策略等级、并发数和超时。先在内部账号与少量设备灰度,确认错误率、耗电和流量没有恶化,再逐步放量。

{
  "enabled": true,
  "level": "CONNECTION_ONLY",
  "hosts": ["api.example.com"],
  "deadlineMs": 800,
  "maxConcurrent": 1,
  "sampleRate": 0.05
}

服务端异常时应能立即关闭,不依赖发版。

HarmonyOS 7 新特性(四十一)检查清单

十二、上线检查清单

  • 已用启动时序证明网络是关键瓶颈;
  • 预建请求进入显式白名单且无副作用;
  • 连接预热、匿名预取和账号预取分层;
  • 账号、网络、隐私和环境变化会取消任务;
  • 缓存键携带身份范围、地区和协议版本;
  • 页面消费前再次验证上下文;
  • 所有失败均可回到普通请求;
  • 日志不包含令牌、敏感查询参数和个人信息;
  • 指标区分命中、未命中、浪费与回退;
  • 具备远端灰度和一键关闭能力。

结语

冷启动网络预建不是“启动时多发几个请求”,而是一套受生命周期、隐私、身份和缓存一致性约束的调度系统。先用数据找到真正的网络关键路径,再从低风险的连接预热开始,最后用命中率、首包改善、流量浪费和失败回退共同验收,才能把 HarmonyOS 7 的启动增强转化为稳定、可回滚的业务收益。

官方参考

  • HarmonyOS 7 新能力一览:https://developer.huawei.com/consumer/cn/features/
  • HarmonyOS 版本说明:https://developer.huawei.com/consumer/cn/doc/harmonyos-releases/changelogs-600
  • 网络连接安全配置:https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/network-connection-security-configuration
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐