Skip to content

Commit 96d3177

Browse files
committedOct 8, 2019
perf(wx-react): 提供Sync版本的groupSetData,提升组件初始化性能
1 parent b5f8648 commit 96d3177

File tree

4 files changed

+182
-5
lines changed

4 files changed

+182
-5
lines changed
 

‎packages/wx-react/miniprogram_dist/AllComponent.js

+129-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
getRealOc,
2020
invokeWillUnmount,
2121
recursionFirstFlushWX,
22+
recursionFirstFlushWXSync,
2223
getShowUpdaterMap,
2324
HIDDEN_STYLE,
2425
recursionMountOrUpdate
@@ -111,6 +112,21 @@ import shallowEqual from './shallowEqual'
111112
*
112113
* 特别的,当Father是页面组件,且是第一次初始化的时候,每一层级的节点将依次产生,一共会发生n(组件树层级)次groupSetData
113114
*
115+
*
116+
* 另外微信小程序自定义组件的 setData行为是这样的(groupSetData同setData),当执行setData以后,新产生A组件的时候,调用如下:
117+
*
118+
* A created
119+
* A attached
120+
* setData 调用返回
121+
* A ready
122+
* setData callback 调用
123+
*
124+
* 所以这里的setData/groupSetData 调用结束之后,A组件attached的生命周期已经执行,这个时候InstanceManager已经管理A,可以不用等到
125+
* callback之后去执行下一次groupSetData
126+
*
127+
* 但是其他版本的小程序【百度,支付宝】是否如此,暂无测试,所以保留 sync /async 两个版本的 firstUpdateWX updateWX recursionFirstFlushWX
128+
*
129+
*
114130
*/
115131
export class BaseComponent {
116132

@@ -227,6 +243,57 @@ export class BaseComponent {
227243
}
228244
}
229245

246+
firstUpdateWXSync() {
247+
const deepComp = this.getDeepComp()
248+
if (!deepComp || Object.keys(deepComp._r).length === 0) {
249+
// 页面组件render null
250+
recursionMountOrUpdate(this)
251+
return
252+
}
253+
254+
255+
const pageWxInst = this.getWxInst()
256+
const comps = []
257+
// 收集下一次groupSetData的实例
258+
deepComp._c.forEach(child => {
259+
if (child._myOutStyle) {
260+
const childComp = child.getDeepComp()
261+
comps.push(childComp)
262+
}
263+
})
264+
265+
if (comps.length === 0) {
266+
pageWxInst.setData({
267+
_r: deepComp._r
268+
}, () => {
269+
recursionMountOrUpdate(this)
270+
})
271+
} else {
272+
const styleKey = deepComp.firstStyleKey
273+
const styleValue = deepComp._r[styleKey]
274+
const pageShowUpdater = {
275+
inst: pageWxInst,
276+
data: {
277+
[`_r.${styleKey}`]: styleValue
278+
}
279+
}
280+
281+
pageWxInst.groupSetData(() => {
282+
pageWxInst.setData({
283+
_r: {
284+
...deepComp._r,
285+
[deepComp.firstStyleKey]: `${styleValue}${HIDDEN_STYLE}`
286+
}
287+
})
288+
289+
//pageWxInst.setData 之后 已经可以获取子组件实例
290+
recursionFirstFlushWXSync(this, pageWxInst, comps, [pageShowUpdater], () => {
291+
recursionMountOrUpdate(this)
292+
})
293+
})
294+
}
295+
}
296+
230297
/**
231298
* 刷新数据到小程序
232299
* @param cb
@@ -276,6 +343,65 @@ export class BaseComponent {
276343
})
277344
}
278345

346+
/**
347+
* 刷新数据到小程序
348+
* @param cb
349+
* @param styleUpdater 上报样式的updater
350+
*/
351+
updateWXSync(cb, styleUpdater) {
352+
const flushList = []
353+
const firstFlushList = []
354+
355+
this.updateWXInner(flushList, firstFlushList)
356+
357+
if (styleUpdater) {
358+
flushList.push(styleUpdater)
359+
}
360+
361+
if (flushList.length === 0) {
362+
recursionMountOrUpdate(this)
363+
cb && cb()
364+
return
365+
}
366+
367+
const showUpdaterMap = getShowUpdaterMap(firstFlushList)
368+
const showUpdaterList = Array.from(showUpdaterMap.values())
369+
370+
/// groupSetData 来优化多次setData
371+
372+
const topWX = styleUpdater ? styleUpdater.inst : this.getWxInst()
373+
topWX.groupSetData(() => {
374+
for(let i = 0; i < flushList.length; i ++ ) {
375+
const {inst, data} = flushList[i]
376+
377+
const updater = showUpdaterMap.get(inst)
378+
if (updater) {
379+
Object.assign(data, updater.hiddenData)
380+
}
381+
382+
383+
if (showUpdaterList.length === 0) {
384+
if (i === 0) {
385+
inst.setData(data, () => {
386+
recursionMountOrUpdate(this)
387+
cb && cb()
388+
})
389+
} else {
390+
inst.setData(data)
391+
}
392+
} else {
393+
inst.setData(data)
394+
}
395+
}
396+
397+
if (showUpdaterList.length !== 0) {
398+
recursionFirstFlushWXSync(this, topWX, firstFlushList, showUpdaterList, () => {
399+
recursionMountOrUpdate(this)
400+
cb && cb()
401+
})
402+
}
403+
})
404+
}
279405

280406
/**
281407
* 递归程序。 主要做两个事情
@@ -491,7 +617,7 @@ export class Component extends BaseComponent {
491617
const oldOutStyle = this._myOutStyle
492618

493619
if (this.isPageComp) {
494-
this.updateWX(finalCb)
620+
this.updateWXSync(finalCb)
495621
return
496622
}
497623

@@ -523,7 +649,7 @@ export class Component extends BaseComponent {
523649

524650
const wxInst = pp.getWxInst()
525651

526-
this.updateWX(finalCb, {
652+
this.updateWXSync(finalCb, {
527653
inst: wxInst,
528654
data: {
529655
[stylePath]: newOutStyle
@@ -535,7 +661,7 @@ export class Component extends BaseComponent {
535661
p = p._p
536662
}
537663
} else {
538-
this.updateWX(finalCb)
664+
this.updateWXSync(finalCb)
539665
}
540666
}
541667
}

‎packages/wx-react/miniprogram_dist/WxNormalComp.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export default function (CompMySelf, RNApp) {
8080

8181
const compInst = instanceManager.getCompInstByUUID(this.data.diuu)
8282
// 在firstUpdate 接受到小程序的回调之前,如果组件调用setState 可能会丢失!
83-
compInst.firstUpdateWX()
83+
compInst.firstUpdateWXSync()
8484
}
8585

8686
o.methods.onShow = function () {

‎packages/wx-react/miniprogram_dist/util.js

+51
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,57 @@ export function recursionFirstFlushWX(top, topWx, comps, showUpdaterList, cb) {
231231
})
232232
}
233233

234+
export function recursionFirstFlushWXSync(top, topWx, comps, showUpdaterList, cb) {
235+
const newComps = []
236+
topWx.groupSetData(() => {
237+
for(let i = 0; i < comps.length; i ++) {
238+
const item = comps[i]
239+
const wxItem = item.getWxInst()
240+
241+
item._c.forEach(childComp => {
242+
// 组件render null
243+
if (childComp._myOutStyle === false) {
244+
return
245+
}
246+
247+
// 跳过hoc包裹的组件
248+
childComp = childComp.getDeepComp()
249+
newComps.push(childComp)
250+
})
251+
252+
253+
if (i === comps.length - 1) {
254+
if (newComps.length === 0) {
255+
// 最后一次groupSetData
256+
showUpdaterList.forEach(({inst, data}) => {
257+
inst.setData(data)
258+
})
259+
260+
wxItem.setData({
261+
_r: item._r
262+
}, () => {
263+
cb && cb()
264+
})
265+
} else {
266+
wxItem.setData({
267+
_r: item._r
268+
})
269+
}
270+
} else {
271+
wxItem.setData({
272+
_r: item._r
273+
})
274+
}
275+
}
276+
277+
278+
if (newComps.length !== 0) {
279+
recursionFirstFlushWXSync(top, topWx, newComps, showUpdaterList, cb)
280+
}
281+
})
282+
}
283+
284+
234285
/**
235286
* 分层groupSetData的方式,存在一个问题:当父元素的大小,由子元素决定的时候,由于父元素先渲染会导致抖动。
236287
* 解决这个问题的方式是: 先把顶层父元素设置为: opacity: 0; 当所有子孙元素都渲染完成之后统一在恢复样式

‎packages/wx-react/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@areslabs/wx-react",
3-
"version": "1.0.26",
3+
"version": "1.0.27-beta.0",
44
"description": "微信版本的React",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)