---
title: Using setData Wisely
docType: default
---

# Using setData Wisely

## How It Works Under the Hood

Tuya miniapps use a dual-thread architecture. When the logic layer calls `setData`, the underlying flow is:

```
Logic layer calls setData
    ↓
Diff new and old data, generate delta
    ↓
Serialize delta and send to view layer via thread communication
    ↓
View layer updates DOM and re-renders
```

Every `setData` call involves cross-thread communication. The more frequent the calls and the larger the data, the higher the performance cost.

## Optimization Principles

### 1. Only Store Render-Related Data in data

Data unrelated to rendering should not be placed in `data`. Doing so triggers unnecessary renders and additional data transfer.

```javascript
// ❌ Avoid: non-render data in data
Page({
  data: {
    list: [],
    timer: null,       // non-render data
    cache: {},         // non-render data
    requestId: '',     // non-render data
  }
});

// ✅ Recommended: store non-render data on this
Page({
  data: {
    list: [],
  },
  onLoad() {
    this.timer = null;       // does not trigger render
    this.cache = {};         // does not trigger render
    this.requestId = '';     // does not trigger render
  }
});
```

### 2. Control setData Frequency

Every `setData` call triggers traversal and update of the virtual DOM tree in the logic layer, and may trigger a full page render. Use throttle for high-frequency scenarios such as scroll events.

```javascript
// ❌ Avoid: update data on every scroll event
Page({
  data: { scrollTop: 0 },
  onPageScroll(e) {
    this.setData({ scrollTop: e.scrollTop });
  }
});

// ✅ Recommended: throttle to control update frequency
Page({
  data: { scrollTop: 0 },
  onLoad() {
    this._throttleTimer = null;
  },
  onPageScroll(e) {
    if (this._throttleTimer) return;
    this._throttleTimer = setTimeout(() => {
      this.setData({ scrollTop: e.scrollTop });
      this._throttleTimer = null;
    }, 100);
  }
});
```

### 3. Only Pass Changed Data in setData

The amount of data in `setData` affects serialization and communication time. Only pass fields that actually changed, using path syntax for precise updates.

```javascript
// ❌ Avoid: pass the entire object
this.setData({ list: newList });

// ✅ Recommended: use path syntax to update a single item
this.setData({ 'list[0].name': 'New name' });
```

### 4. Batch Multiple setData Calls

Merge multiple related data updates into a single `setData` call to avoid triggering multiple renders:

```javascript
// ❌ Avoid: multiple separate setData calls
this.setData({ loading: true });
this.setData({ list: [] });
this.setData({ total: 0 });

// ✅ Recommended: merge into one call
this.setData({ loading: true, list: [], total: 0 });
```

### 5. Choose the Right setData Scope

A component's `setData` only updates that component and its children, reducing virtual DOM computation overhead. Push frequently updated data down to child components to avoid page-level full updates.

### 6. Stop setData in Background Pages

Since the miniapp logic layer runs on a single thread, background page `setData` calls compete with foreground page resources. Background page rendering is invisible to users, so these calls are wasteful.

```javascript
// ✅ Recommended: stop polling when page is hidden
Page({
  onShow() {
    this._isActive = true;
    this._startPolling();
  },
  onHide() {
    this._isActive = false;
    if (this._timer) {
      clearInterval(this._timer);
      this._timer = null;
    }
  },
  _startPolling() {
    this._timer = setInterval(() => {
      if (this._isActive) {
        fetchLatestData().then(res => {
          this.setData({ data: res });
        });
      }
    }, 3000);
  }
});
```

## Checklist

| Check Item | Symptom | Optimization |
| ---------- | ------- | ------------ |
| Non-render data in data | Unnecessary render overhead | Store on this |
| High-frequency setData calls | Laggy interactions | Apply throttle/debounce |
| Passing large amounts of data | Long communication time | Only pass changed fields; use path syntax |
| Multiple scattered setData calls | Multiple renders | Merge into one call |
| Background page setData | Wasted resources | Stop updates when page is hidden |
