【HarmonyOS 7新能力|039】冷启网络预建链工程封装:把接入逻辑放进可维护的分层结构

很多应用的冷启动页面很快出现,但首屏数据迟迟不来。真正耗时往往不只在业务接口本身,还包括网络可用性判断、域名解析、连接建立与安全握手。预建链的意义,是在业务请求真正发出前,针对高概率且可信的目标提前完成可复用的连接准备。不过,若把它做成"启动时连接所有域名",只会增加功耗、资源竞争和隐私风险。
说明:本文的
PreconnectPort、ConnectionOrchestrator等是教学抽象,不对应 HarmonyOS SDK 的真实类名。可预建的协议阶段、网络权限、设备支持与 API 签名,请以当前官方文档和目标 SDK 为准。
1. 先确认瓶颈是否真的在建链
开始改造前,要把冷启动拆成应用初始化、请求排队、DNS、连接、安全握手、服务器处理和响应解析。只有连接阶段占据明显比例,预建链才可能有价值。若瓶颈是主线程阻塞或服务端响应慢,提前连接解决不了问题。
ts
export interface NetworkTiming {
requestQueuedAt: number
dnsStart?: number
connectStart?: number
secureReady?: number
requestSent?: number
firstByte?: number
completedAt?: number
}
指标使用统一会话 ID 和单调时钟,区分冷启动、温启动、网络类型与入口页面。不要用单次最快结果证明优化有效。
2. 四层结构隔离网络细节

启动页面只声明即将进入的业务路线;连接编排层选择候选、分配预算并协调生命周期;网络能力适配层封装真实预建与取消;连接状态仓库保存最少的目标元数据、结果和短期复用状态。
ts
export interface PreconnectPort {
prepare(target: ConnectionTarget, signal: AbortSignal): Promise<PrepareResult>
release(key: string): Promise<void>
}
export interface ConnectionStateStore {
get(key: string): Promise<ConnectionSnapshot | undefined>
put(snapshot: ConnectionSnapshot): Promise<void>
}
业务层不接触 socket 或证书对象。平台能力不可用时,适配器返回结构化结果,正常请求仍走原有网络客户端。
3. 候选目标必须来自白名单
预建目标不能由页面任意传入完整 URL,更不能对外部跳转地址自动建链。项目应维护静态或受控配置,只包含自有、可信且首屏高概率使用的服务。
ts
export interface ConnectionTarget {
key: string
scheme: 'https'
hostAlias: string
port: number
route: 'home' | 'account' | 'content'
priority: number
}
hostAlias 由适配层映射到真实配置,页面看不到生产域名。动态配置必须经过完整性、版本和允许字段校验,禁止变成任意网络探测入口。
4. 用启动路线筛选,而不是全量执行
不同入口需要不同后端。通知点击进入详情、桌面图标进入首页、账号过期进入登录页,都不应预建同一组连接。编排器根据已知路线和本地状态选出少量高概率目标。
ts
export function selectTargets(
route: StartupRoute,
candidates: readonly ConnectionTarget[]
): ConnectionTarget[] {
return candidates
.filter(item => item.route === route.kind)
.sort((a, b) => b.priority - a.priority)
.slice(0, route.maxTargets)
}
选择函数保持纯函数,可通过历史采样调整规则,但不要收集超出优化所需的用户行为数据。
5. 冷启网络关键路径

流程从启动意图开始,先判断网络和业务路线,再筛选可信目标,随后执行连接预建。首个请求发出时尝试复用已准备连接;离线、超时或安全校验失败则回到正常网络流程或离线体验。
ts
export type PrepareResult =
| { status: 'ready'; connectionKey: string; expiresAt: number }
| { status: 'skipped'; reason: string }
| { status: 'failed'; code: string; retryable: boolean }
预建失败不是启动失败。除非业务本身要求联网,页面不应因为优化能力失败而白屏。
6. 设置时间、并发和资源预算
冷启动同时有渲染、存储读取和依赖初始化。预建链不能无限抢占资源,应限定启动阶段最多目标数、整体截止时间和同类并发数。
ts
export interface PreconnectBudget {
maxTargets: number
deadlineMs: number
maxConcurrent: number
cancelOnBackground: boolean
}
async function runWithinBudget(targets: ConnectionTarget[], budget: PreconnectBudget) {
return scheduler.run(targets, budget.maxConcurrent, budget.deadlineMs)
}
具体预算由目标设备实测确定。超过截止时间就取消剩余优化任务,不能拖慢首个真实请求。
7. 安全校验不能因预建而降级
预建连接必须遵循与正常请求相同的 HTTPS、证书、主机名与信任策略。任何校验失败都应丢弃连接并记录归一化错误,绝不能回退到不安全协议。
ts
export interface SecurityPolicy {
requireSecureTransport: true
allowedHostAliases: readonly string[]
allowUserCertificateOverride: false
}
示例表达的是安全不变量,不是平台参数。密钥、令牌和用户身份不应参与无业务请求的预建阶段;认证信息只在正式请求层按既有机制附加。
8. 连接复用需要上下文一致
预建结果只有在目标、协议配置、网络环境和有效期仍一致时才能复用。Wi-Fi 切换到蜂窝、代理变化或应用配置更新后,应把旧快照标记失效。
ts
export interface ConnectionSnapshot {
key: string
targetKey: string
networkEpoch: string
configVersion: string
state: 'preparing' | 'ready' | 'consumed' | 'invalid'
expiresAt: number
}
仓库记录的是复用决策元数据,不持久化底层连接对象。真实连接生命周期由平台与网络客户端管理。
9. 幂等防止重复建链
页面重建、多个组件同时请求首屏数据,可能重复触发同一目标。编排器以目标、网络代次和配置版本组成幂等键,复用进行中的 Promise 或已有就绪状态。
ts
async function prepareOnce(target: ConnectionTarget): Promise<PrepareResult> {
const key = buildKey(target, networkEpoch, configVersion)
const running = inFlight.get(key)
if (running) return running
const task = adapter.prepare(target, abortController.signal)
inFlight.set(key, task)
return task.finally(() => inFlight.delete(key))
}
幂等只合并相同上下文。网络变化后必须生成新键,避免复用错误环境中的结果。
10. 生命周期与取消策略
应用进入后台、用户切换入口、正式请求已经发出或预算耗尽时,未产生价值的预建应取消。取消属于正常控制流,不应作为网络故障上报。
ts
export class ConnectionOrchestrator {
onRouteChanged(next: StartupRoute): void {
this.abortIrrelevant(next)
this.prepareFor(next)
}
onBackground(): void {
this.abortController.abort()
}
}
协调器由应用级合适生命周期持有,页面销毁只取消订阅,不直接破坏可能被下一页面复用的有效连接。
11. 可观测性验证真实收益
每次会话记录候选数、实际执行数、准备结果、是否被正式请求复用以及失败原因。核心指标不是"预建成功率",而是"有用复用率"和首个请求关键分位的变化。
ts
export interface PreconnectTrace {
sessionId: string
targetKey: string
startedAt: number
endedAt: number
result: string
reusedByFirstRequest: boolean
}
日志不记录完整 URL、查询参数、认证头和响应内容。线上采样应符合隐私声明,分析时区分网络类型和启动路线。
12. 验收清单与总结
验收覆盖离线、弱网、网络切换、DNS 失败、连接超时、证书失败、应用前后台和重复触发。确认预建失败不影响正常请求,不安全连接不会被接受,非目标域名不会访问,超出预算能及时取消。再用发布构建在目标设备多轮对比首个可用数据的分位数。
冷启网络预建链不是多发一次网络调用,而是把高概率连接准备提前到合适窗口。通过白名单目标、路线筛选、严格预算、安全校验、幂等复用和可观测闭环,应用可以在能力可用时缩短首个请求等待,在异常时仍保持原有正确路径。