性能优化
虚拟列表
在帖子列表组件(ThreadList
)中,我们直接渲染从远程得来的数据。这样做没有什么问题,但如果我们的数据非常庞大,或者列表渲染的 DOM 结构异常复杂,这就可能会产生性能问题。
为了解决这一问题,Taro 内置了虚拟列表(VirtualList
)功能,比起全量渲染所有列表数据,我们只需要渲染当前可视区域(visable viewport)的视图:
- React
- Vue
app.js
// 在入口文件新增使用插件
import VirtualList from '@tarojs/components/virtual-list'
Vue.use(VirtualList)
src/components/row.vue
<template>
<thread
:key="thread.id"
:node="thread.node"
:title="thread.title"
:last_modified="thread.last_modified"
:replies="thread.replies"
:tid="thread.id"
:member="thread.member"
/>
</template>
<script>
import Thread from './thread.vue'
export default {
components: {
thread: Thread,
},
props: ['index', 'data', 'css'],
computed: {
thread() {
return this.data[this.index]
},
},
}
</script>
src/components/thread_list.vue
<template>
<view className="thread-list">
<loading v-if="loading" />
<virtual-list
v-else
:height="500"
:item-data="threads"
:item-count="threads.length"
:item-size="100"
:item="Row"
width="100%"
/>
</view>
</template>
<script>
import Vue from 'vue'
import Loading from './loading.vue'
import Thread from './thread.vue'
import Row from './row.vue'
export default {
components: {
loading: Loading,
thread: Thread,
},
props: {
threads: {
type: Array,
default: [],
},
loading: {
type: Boolean,
default: true,
},
},
}
</script>
了解更多
在文档虚拟列表 你可以找到虚拟列表的一些高级用法,例如:无限滚动、滚动偏移、滚动事件等。
预渲染
现在我们来实现最后一个页面:节点列表页面。这个页面本质说就是渲染一个存在本地的巨大列表:
- React
- Vue
src/pages/nodes/nodes.vue
<template>
<view class="node-container">
<view v-for="item in allNodes" :key="item.title" class="container">
<view class="title">
<text style="margin-left: 5px">{{item.title}}</text>
</view>
<view class="nodes">
<navigator v-for="node in item.nodes" :key="node.full_name" class="tag" :url="node | url">
<text>{{node.full_name}}</text>
</navigator>
</view>
</view>
</view>
</template>
<script>
import Vue from 'vue'
import allNodes from './all_node'
import api from '../../utils/api'
import './nodes.css'
function getURL(node) {
return `/pages/node_detail/node_detail${api.queryString(node)}`
}
export default {
data() {
return {
allNodes,
}
},
filters: {
url(node) {
return getURL(node)
},
},
}
</script>
这个时候我们整个应用就完成了。但如果你把这个应用放在真机小程序中,尤其是一些性能不高的真机中,切换到此页面的时间可能会比较长,会有一段白屏时间。
这是由于 Taro 的渲染机制导致的:在页面初始化时,原生小程序可以从本地直接取数据渲染,但 Taro 会把初始数据通过 React/Vue 渲染成一颗 DOM 树,然后将这颗 DOM 树序列化之后交给小程序渲染。也就是说,比起原生小程序 Taro 会在页面初始化时多一次调用 setData
函数的支出——而大部分小程序的性能问题是 setData
数据过大导致的。
为了解决这个问题,Taro 引入了一种名为预渲染(Prerender)的技术,和服务端渲染一样,在 Taro CLI 直接将要渲染的页面转换为 wxml
字符串,这样就获得了与原生小程序一致甚至更快的速度。
使用预渲染也非常简单,我们只要进行简单的配置即可:
config/prod.js
const config = {
...
mini: {
prerender: {
include: ['pages/nodes/nodes'], // `pages/nodes/nodes` 也会参与 prerender
}
}
};
// 我们这里在编译生产模式时才开启预渲染
// 如果需要开发时也开启,那就把配置放在 `config/index` 或 `config/dev`
module.exports = config