perf(门店选择): 门店明细移出页面 data,修复首屏卡顿
门店接口 /shop/merchant/groupByChain 一次返回 8105 家门店(约 1.1MB)。
此前把门店明细原样放进页面 data,data 树膨胀到 1118KB,导致此后每次
setData 都要重新 diff/序列化整棵树——即使载荷只有 1 个字段,耗时也从
约 490ms 涨到约 1000ms,首屏因此多花约 3.5s。
改为把明细挂在实例属性 merchantStore 上(不进页面 data),
merchantChainList 只保留 {id, text, merchantCount} 骨架,
新增 getMerchantsByChainId() / getVisibleMerchants() 按需取数。
涉及页面:
- packageUser/self-report/create.vue
- packageUser/chronic/index.vue
- pages/task/detail.vue
- pages/share/create.vue
- pages/share/index.vue
- pages/audit/components/AuditShareItem.vue
实测(微信开发者工具自动化):
- 页面 data 门店明细 1118KB -> 1KB
- 单字段 setData 998ms -> 10~53ms
- self-report/create 首屏 9055ms -> 5341ms
- 门店 picker 选项数不变(大参林 2700 项),搜索与选中回填均正常
This commit is contained in:
@@ -385,11 +385,14 @@ export default {
|
||||
},
|
||||
merchantChainOptions() {
|
||||
const list = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||
return list.length ? list : [{id: '', text: '暂无连锁', merchants: []}]
|
||||
return list.length ? list : [{id: '', text: '暂无连锁', merchantCount: 0}]
|
||||
},
|
||||
merchantStoreOptions() {
|
||||
const currentChain = this.merchantChainOptions.find(chain => String(chain.id) === String(this.form.chainId)) || {}
|
||||
const merchants = Array.isArray(currentChain.merchants) ? currentChain.merchants : []
|
||||
// 门店明细不放在页面 data 里(见 setMerchantChains),从实例上的 store 取。
|
||||
// 这里读 merchantChainList 是为了建立响应式依赖:门店数据到达后需要重算。
|
||||
const chainList = Array.isArray(this.merchantChainList) ? this.merchantChainList : []
|
||||
const hasChain = chainList.some(chain => String(chain.id) === String(this.form.chainId))
|
||||
const merchants = hasChain ? this.getMerchantsByChainId(this.form.chainId) : []
|
||||
const keyword = (this.merchantStoreSearchKeyword || '').trim()
|
||||
const filteredMerchants = this.filterMerchantStores(merchants)
|
||||
return filteredMerchants.length ? filteredMerchants : [{id: '', text: keyword ? '无匹配门店' : '无门店'}]
|
||||
@@ -442,6 +445,10 @@ export default {
|
||||
this.merchantPickerValue = [0]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 门店明细挂实例上而非 data:data 里的一切都会进页面 data 树并被 setData 序列化。
|
||||
this.merchantStore = []
|
||||
},
|
||||
async onShow() {
|
||||
this.isLoggedIn = !!getUserInfo().token
|
||||
if (!this.hasInitialized) {
|
||||
@@ -803,12 +810,13 @@ export default {
|
||||
const {data} = await merchantGroupByChainReq({})
|
||||
const list = this.unwrapList(data)
|
||||
const groupedList = this.groupMerchantListByChain(list)
|
||||
this.merchantChainList = (groupedList.length
|
||||
const chains = (groupedList.length
|
||||
? groupedList
|
||||
: list.map((item, index) => this.normalizeMerchantChain(item, index)))
|
||||
.filter(item => Array.isArray(item.merchants) && item.merchants.length > 0)
|
||||
this.setMerchantChains(chains)
|
||||
} catch (error) {
|
||||
this.merchantChainList = []
|
||||
this.setMerchantChains([])
|
||||
uni.showToast({
|
||||
title: '门店列表获取失败',
|
||||
icon: 'none'
|
||||
@@ -817,6 +825,27 @@ export default {
|
||||
this.merchantLoading = false
|
||||
}
|
||||
},
|
||||
// 门店明细(全量可达 8000+ 条)只放在实例上,不进页面 data。
|
||||
// 一旦放进 data,页面 data 树会膨胀到 1MB+,此后每次 setData 都要重新
|
||||
// diff/序列化整棵树,连只含一个字段的 setData 也会从 ~490ms 涨到 ~1000ms。
|
||||
setMerchantChains(chains) {
|
||||
const list = Array.isArray(chains) ? chains : []
|
||||
this.merchantStore = list.map(chain => ({
|
||||
id: chain.id,
|
||||
text: chain.text,
|
||||
merchants: Array.isArray(chain.merchants) ? chain.merchants : []
|
||||
}))
|
||||
this.merchantChainList = this.merchantStore.map(chain => ({
|
||||
id: chain.id,
|
||||
text: chain.text,
|
||||
merchantCount: chain.merchants.length
|
||||
}))
|
||||
},
|
||||
getMerchantsByChainId(chainId) {
|
||||
const store = Array.isArray(this.merchantStore) ? this.merchantStore : []
|
||||
const chain = store.find(item => String(item.id) === String(chainId))
|
||||
return chain && Array.isArray(chain.merchants) ? chain.merchants : []
|
||||
},
|
||||
openChainPicker() {
|
||||
if (!this.merchantChainList.length) return
|
||||
const chainIndex = this.merchantChainOptions.findIndex(item => String(item.id) === String(this.form.chainId))
|
||||
|
||||
Reference in New Issue
Block a user