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.
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
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
