---
title: 渲染性能优化
summary: "介绍小程序渲染性能优化方法，包括减少节点数、选择高性能动画方案和组件化拆分。"
questions:
  - 页面节点数和节点树深度的建议上限分别是多少？
  - ty:if 和 hidden 属性在条件渲染中有什么区别？
  - 为什么不建议声明空的 onPageScroll 函数？
  - 小程序中有哪些动画实现方案，各自适用什么场景？
  - 为什么应优先使用 transform 和 opacity 做动画？
  - 为什么不建议用 setData 驱动动画？
  - 组件化拆分如何提升渲染性能？
  - 减少页面节点数有哪些常用手段？
  - 滚动事件监听为什么会影响性能？
  - SJS 动画方案的优势和适用场景是什么？
docType: default
---

# 渲染性能优化

渲染性能影响页面的流畅度和响应速度。页面结构越复杂、更新越频繁，渲染压力越大。

## 减少页面节点数

页面中节点数过多会增加内存占用和布局计算耗时。建议一个页面节点数少于 1000 个，节点树深度少于 30 层。

常用手段：

- **移除冗余嵌套**：减少不必要的 `view` 包裹层，保持结构扁平
- **条件渲染**：暂时不需要展示的内容用 `ty:if` 移除节点；如果元素需要频繁切换，改用 `hidden` 属性避免反复创建销毁节点

```html
<!-- ✅ 用 ty:if 移除不需要的节点 -->
<view ty:if="{{showDetail}}" class="detail-content">...</view>

<!-- ✅ 频繁切换时用 hidden 避免反复创建 -->
<view hidden="{{!showPanel}}" class="panel">...</view>
```

## 合理监听滚动事件

`onPageScroll` 和 `scroll-view` 的 `bindscroll` 事件触发频率很高，每次触发都会有跨线程通信开销。

注意事项：

- 非必要不监听 scroll 事件
- 不需要时不要声明空的 `onPageScroll` 函数
- 避免在 scroll 回调中频繁调用 `setData` 或同步 API

## 选择高性能的动画实现方式

动画是提升小程序交互体验的重要手段。选择合适的动画实现方式可以在保证视觉效果的同时避免性能问题。

| 方案 | 适用场景 | 性能 | 复杂度 |
| ---- | -------- | ---- | ------ |
| CSS 动画 / Transition | 简单过渡效果（显隐、位移、缩放） | 高 | 低 |
| GIF / Lottie | 装饰性动画（加载动画、图标动效） | 高 | 低 |
| [SJS](/cn/miniapp/develop/miniapp/framework/sjs) | 高频交互动画（跟手拖拽、手势联动） | 高 | 高 |
| [createAnimation](/cn/miniapp/develop/miniapp/api/ui/animation/createAnimation#tycreateanimation) | 序列化动画 | 中 | 低 |
| setData 驱动 | - | 低 | 低 |

- 优先使用 `transform` 和 `opacity` 属性做动画，它们可以使用 GPU 加速
- 避免对 `width`、`height`、`margin`、`padding` 等属性做动画，它们会触发布局重排

```css
/* ✅ 推荐：使用 transform */
.slide-in {
  transform: translateX(-100%);
  transition: transform 0.3s ease;
}
.slide-in.active {
  transform: translateX(0);
}

/* ❌ 避免：使用 left/right */
.slide-in {
  left: -100%;
  transition: left 0.3s ease;
}
```

避免用 `setData` 每帧更新数据来驱动动画。在 60fps 的要求下每帧只有约 16ms，跨线程通信耗时会导致严重掉帧。高频交互动画（如拖拽跟手）使用 SJS 在视图层直接响应事件和修改样式。

## 组件化拆分

将页面拆分为独立的子组件，组件内的状态更新只会触发组件自身重新渲染，不会影响整个页面：

```
页面
├── Header 组件（独立更新）
├── ListItem 组件 × N（各自独立更新）
└── Footer 组件（独立更新）
```

## 检查清单

| 检查项 | 优化方法 |
| ------ | -------- |
| 页面节点数是否过多 | 移除冗余嵌套，简化结构 |
| 是否用 `display:none` 隐藏大量节点 | 改用 `ty:if` 条件渲染 |
| 是否监听了不必要的滚动事件 | 移除空回调 |
| 动画是否卡顿 | 改用 CSS 动画或 SJS |
| 页面是否进行了组件化拆分 | 将独立模块提取为子组件 |
