---
title: 启动流程介绍
summary: "详细介绍小程序从打开到首屏渲染完成的完整启动流程及各阶段耗时因素。"
docType: default
tags: [小程序启动流程介绍, 启动阶段详解, 代码加载到首屏渲染流程]
questions:
  - 小程序的启动流程包含哪些主要阶段？
  - 运行环境准备阶段需要准备哪些内容？
  - 小程序信息获取的同步和异步请求分别在什么场景下触发？
  - 代码包下载耗时与哪些因素相关？
  - 逻辑层代码注入阶段会触发哪些生命周期？
  - 逻辑层和视图层的代码注入是串行还是并行的？
  - Page.onReady 触发代表什么含义？
  - 小程序启动过程中的生命周期执行顺序是什么？
  - 为什么首次打开小程序比后续打开慢很多？
---

# 小程序启动流程介绍

在进行启动优化之前，需要先了解小程序的启动过程。理解各个阶段的作用和耗时因素，可以帮助开发者更有针对性地选择优化手段。

> 小程序启动的各流程不是完全串行的，部分流程会并行执行。总启动耗时不等于各阶段耗时的简单加和。

## 启动流程概览

小程序启动过程主要包含以下阶段：

```mermaid
sequenceDiagram
    autonumber
    participant User as 用户
    participant Runtime as 客户端
    participant Service as 逻辑层代码注入
    participant View as 视图层
    participant Net as 网络

    %% 启动
    User->>Runtime: 打开小程序

    par 资源准备
        Runtime->>Runtime: 运行环境初始化
    and
        Runtime->>Net: 获取小程序信息
    and
        Runtime->>Net: 下载代码包
    end

    %% 代码注入
    Runtime->>Service: 注入逻辑层代码
    Runtime->>View: 注入视图层代码

    %% 生命周期与首屏关键路径
    Service->>Service: 执行 App/Page 生命周期

    %% 首屏关键路径
    Service->>View: setData(初始数据)
    View-->>User: 首屏绘制完成

    %% 首屏后更新
    Service->>Net: 异步数据请求
    Net-->>Service: 返回数据
    Service->>View: setData(页面更新)
```

## 1. 资源准备

### 1.1 运行环境准备

小程序的运行环境包括：

- 小程序进程
- 客户端原生系统组件和 UI 元素（导航栏、tabBar 等）
- 渲染页面使用的 WebView 容器
- JavaScript 运行引擎
- 小程序基础库

部分环境（如 JavaScript 引擎、基础库）需要在执行小程序代码之前准备完成，其他部分会在启动过程中并行初始化。

> 为了降低运行环境准备对启动耗时的影响，客户端会根据用户的使用场景和设备资源状况，在小程序启动前对运行环境进行预加载。

### 1.2 小程序信息获取

客户端需要从后台获取小程序的基本信息（版本、配置、权限等）。这些信息会在本地缓存，并通过一定机制更新。

| 请求类型 | 触发场景 | 对启动的影响 |
| -------- | -------- | ------------ |
| 同步请求 | 首次访问、发现新版本 | 阻塞启动流程 |
| 异步请求 | 已使用过且无新版本 | 不影响启动流程 |

#### 对启动耗时的影响

- 首次访问或版本更新时，信息获取会增加启动耗时
- 耗时主要受网络环境影响
- 频繁发布版本会导致用户启动时同步请求比例上升，建议合理规划版本发布节奏

### 1.3 代码包下载

小程序启动时需要下载代码包。和信息获取类似，代码包也有缓存机制：

| 下载类型 | 触发场景 | 对启动的影响 |
| -------- | -------- | ------------ |
| 同步下载 | 首次下载、发现新版本需同步更新 | 阻塞启动流程 |
| 异步下载 | 已使用过，后台异步检测到新版本 | 不影响启动流程 |

#### 对启动耗时的影响

- 下载耗时是启动过程的重要瓶颈
- 耗时与网络环境和代码包压缩后大小直接相关
- 开发者应尽量控制代码包体积，参考 [代码包体积优化](/cn/miniapp/develop/ray/guide/optimization/startup/package-size)

## 2. 代码注入

### 2.1 逻辑层代码注入

小程序启动时需要读取代码包中的配置和代码，注入到 JavaScript 引擎中执行。在此过程中会触发：

- `App.onLaunch` 生命周期
- `App.onShow` 生命周期

#### 对启动耗时的影响

- **代码量和复杂度**：代码越多、逻辑越复杂，注入时间越长
- **同步接口调用**：启动时调用同步 API 会阻塞注入过程
- **复杂计算**：启动时执行大量计算会延长注入时间

### 2.2 视图层代码注入

开发者编写的样式和模板代码会编译为 JavaScript 注入到视图层，包含页面渲染所需的结构和样式信息。逻辑层和视图层的代码注入是并行进行的。

#### 对启动耗时的影响

注入耗时与**页面结构复杂度**和**使用的自定义组件数量**有关。

## 3. 首页渲染

逻辑层代码注入完成后，小程序框架会：

1. 根据用户访问的页面进行页面组件树初始化
2. 触发 `Page.onLoad`，开发者可在此设置初始数据
3. 生成初始渲染数据发送到视图层，触发 `Page.onShow`
4. 视图层收到数据后进行首屏绘制
5. 首屏绘制完成后触发 `Page.onReady`

`Page.onReady` 触发标志着小程序启动流程完成。

#### 对启动耗时的影响

- 首页渲染耗时是启动过程的最后一环
- 耗时与页面结构复杂度和参与渲染的组件数量相关
- 参考 [首屏渲染优化](/cn/miniapp/develop/ray/guide/optimization/startup/first-render)

## 4. 首屏内容展示

首页渲染完成后，小程序 Loading 消失。但如果首屏主体内容依赖异步网络请求，用户可能看到的仍是空白或骨架屏，需要等请求返回后通过 `setData` 更新页面才能呈现完整内容。

#### 对启动耗时的影响

异步数据请求不计入启动耗时统计，但会延迟用户看到完整内容的时间，影响实际体验。

## 生命周期时序总结

```
App.onLaunch → App.onShow → Page.onLoad → Page.onShow → Page.onReady
     ↑                            ↑                           ↑
  逻辑层注入完成               页面初始化完成              首屏渲染完成
```

## 常见问题

### 为什么首次打开比后续打开慢很多？

首次打开需要同步下载代码包和获取小程序信息，后续打开会使用本地缓存，省去了下载步骤。

### 为什么不同设备启动耗时差异很大？

- 设备性能不同（CPU、内存）
- 不同操作系统的进程管理机制不同
- 低端设备预加载的运行环境更容易被系统回收

## 相关文档

- [代码包体积优化](/cn/miniapp/develop/ray/guide/optimization/startup/package-size)
- [代码注入优化](/cn/miniapp/develop/ray/guide/optimization/startup/code-injection)
- [首屏渲染优化](/cn/miniapp/develop/ray/guide/optimization/startup/first-render)
