Boosting Taro Mini‑Program Performance: Proven Best Practices and Real‑World Optimizations

This article details how the Taro team optimized the 京喜拼拼 mini‑program by identifying performance bottlenecks, applying best‑practice coding patterns, refining virtual list handling, reducing setData overhead, and integrating native components, ultimately achieving smoother scrolling and higher experience scores across devices.

Aotu Lab
Aotu Lab
Aotu Lab
Boosting Taro Mini‑Program Performance: Proven Best Practices and Real‑World Optimizations

Background

The JD community‑group‑buy platform 京喜拼拼 adopted Taro to satisfy multi‑platform requirements. The Taro team was asked to improve the mini‑program’s performance.

Performance‑Related Best Practices

Focus on setData payload size and call frequency. When debugging, print the data passed to setData by searching for .setData in dist/taro.js.

Node deletion – toggling a modal can cause sibling nodes to be updated, generating a large payload. Isolate the modal in its own <View> so that only the modal is removed.

<View>
  <!-- Slider -->
  <Slider />
  <!-- Goods -->
  <Goods />
  <!-- Modal -->
  <View>{isShowModal && <Modal />}</View>
</View>

Keep references for component props – avoid recreating non‑primitive objects on each render. Store them in state or a closure so that setData is not triggered unnecessarily.

<Map latitude={22.53332} longitude={113.93041} markers={this.state.markers} />

Avoid extra attributes on native components – attributes not defined by the component are still sent through setData, adding redundant data. Taro v3.1 will filter these automatically.

Experience‑Related Issues

Scroll penetration – overlay elements (modal, mask) may let scroll events bubble to the page. Solutions:

Disable scrolling with CSS (e.g., overflow:hidden; height:100vh;).

Add the catchMove attribute to the overlay component. <View catchMove /> Navigation preload – reduce latency between Taro.navigateTo and the target page’s onLoad by preloading data:

// pages/index.js
Taro.preload(fetchSomething())
Taro.navigateTo({ url: '/pages/detail' })

// pages/detail.js
console.log(getCurrentInstance().preloadData)

Cache Taro.getCurrentInstance() – store the result once in a component to avoid repeated calls:

class Index extends Component {
  inst = Taro.getCurrentInstance()
  componentDidMount() { console.log(this.inst) }
}

Cart Page Optimizations (Low‑End Devices)

1. Long‑List Optimization with Virtual List

Taro 3 provides a virtual‑list component that can handle unknown item heights when unlimitedSize is enabled.

import VirtualList from '@tarojs/components/virtual-list'
function buildData(offset = 0) { return Array(100).fill(0).map((_, i) => i + offset) }
const Row = React.memo(({ id, index, style }) => (
  <View id={id} className={index % 2 ? 'ListItemOdd' : 'ListItemEven'} style={style}>
    Row {index}
  </View>
))
export default class Index extends Component {
  state = { data: buildData(0) }
  render() {
    const { data } = this.state
    return (
      <VirtualList height={500} width='100%' itemData={data} itemCount={data.length}
        itemSize={100} unlimitedSize={true}>{Row}</VirtualList>
    )
  }
}

Developers can also render a bottom component with renderBottom and obtain detailed scroll events via the extended VirtualListEvent interface.

2. Rendering Performance via Native Custom Components

Deep page hierarchies generate massive setData payloads. Two approaches reduce the update scope:

Global baseLevel configuration – when the DOM depth exceeds baseLevel (default 16), Taro switches to native custom components. Lowering the threshold to 8 or 4 improves performance but may break flex layouts and requires selector adjustments (e.g., .ancestor >>> .descendant).

CustomWrapper component – wrap performance‑critical modules so that setData is delegated to a native component, achieving localized updates.

<CustomWrapper>
  <GoodsList>
    <Item />
    <Item />
    ...
  </GoodsList>
</CustomWrapper>

Experience Score Improvements

Removing unnecessary event bindings from small components and using static templates eliminated “click‑area too small” warnings, slightly reducing the generated base.wxml size and raising the average experience score above 95.

Multi‑Platform Adaptation & Native Mixing

HTML Parsing Enhancements

Taro 3 now supports <style> tags and aligns with wxparse capabilities, allowing developers to use dangerouslySetInnerHTML (React) or v-html (Vue) without third‑party parsers.

Native Project + Taro Mixing (v3.0.25+)

Use Taro pages inside a native project.

Run a full Taro app in a native sub‑package.

Embed Taro custom components in a native project (in progress).

Feedback is welcomed on the GitHub issue tracker.

References

Taro3 event mechanism: https://taro-docs.jd.com/taro/docs/react#%E9%98%BB%E6%AD%A2%E6%BB%9A%E5%8A%A8%E7%A9%BF%E9%80%8F

baseLevel configuration: https://taro-docs.jd.com/taro/docs/next/config-detail#minibaselevel

Cross‑custom‑component selector: https://developers.weixin.qq.com/miniprogram/dev/api/wxml/SelectorQuery.select.html

Taro3 default property/event binding: https://taro-docs.jd.com/taro/docs/next/platform-plugin#%E5%B1%9E%E6%80%A7%E7%B2%AE%E7%AE%80

Native project mixing solution: https://taro-docs.jd.com/taro/docs/next/taro-in-miniapp

GitHub issues: https://github.com/NervJS/taro/issues

frontendOptimizationmini-programTaro
Aotu Lab
Written by

Aotu Lab

Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.