Skip to content

Commit

Permalink
perf(wx-react): 提供Sync版本的groupSetData,提升组件初始化性能
Browse files Browse the repository at this point in the history
  • Loading branch information
ykforerlang committed Oct 8, 2019
1 parent b5f8648 commit 96d3177
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 5 deletions.
132 changes: 129 additions & 3 deletions packages/wx-react/miniprogram_dist/AllComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
getRealOc,
invokeWillUnmount,
recursionFirstFlushWX,
recursionFirstFlushWXSync,
getShowUpdaterMap,
HIDDEN_STYLE,
recursionMountOrUpdate
Expand Down Expand Up @@ -111,6 +112,21 @@ import shallowEqual from './shallowEqual'
*
* 特别的,当Father是页面组件,且是第一次初始化的时候,每一层级的节点将依次产生,一共会发生n(组件树层级)次groupSetData
*
*
* 另外微信小程序自定义组件的 setData行为是这样的(groupSetData同setData),当执行setData以后,新产生A组件的时候,调用如下:
*
* A created
* A attached
* setData 调用返回
* A ready
* setData callback 调用
*
* 所以这里的setData/groupSetData 调用结束之后,A组件attached的生命周期已经执行,这个时候InstanceManager已经管理A,可以不用等到
* callback之后去执行下一次groupSetData
*
* 但是其他版本的小程序【百度,支付宝】是否如此,暂无测试,所以保留 sync /async 两个版本的 firstUpdateWX updateWX recursionFirstFlushWX
*
*
*/
export class BaseComponent {

Expand Down Expand Up @@ -227,6 +243,57 @@ export class BaseComponent {
}
}

firstUpdateWXSync() {
const deepComp = this.getDeepComp()
if (!deepComp || Object.keys(deepComp._r).length === 0) {
// 页面组件render null
recursionMountOrUpdate(this)
return
}


const pageWxInst = this.getWxInst()
const comps = []
// 收集下一次groupSetData的实例
deepComp._c.forEach(child => {
if (child._myOutStyle) {
const childComp = child.getDeepComp()
comps.push(childComp)
}
})

if (comps.length === 0) {
pageWxInst.setData({
_r: deepComp._r
}, () => {
recursionMountOrUpdate(this)
})
} else {
const styleKey = deepComp.firstStyleKey
const styleValue = deepComp._r[styleKey]
const pageShowUpdater = {
inst: pageWxInst,
data: {
[`_r.${styleKey}`]: styleValue
}
}

pageWxInst.groupSetData(() => {
pageWxInst.setData({
_r: {
...deepComp._r,
[deepComp.firstStyleKey]: `${styleValue}${HIDDEN_STYLE}`
}
})

//pageWxInst.setData 之后 已经可以获取子组件实例
recursionFirstFlushWXSync(this, pageWxInst, comps, [pageShowUpdater], () => {
recursionMountOrUpdate(this)
})
})
}
}

/**
* 刷新数据到小程序
* @param cb
Expand Down Expand Up @@ -276,6 +343,65 @@ export class BaseComponent {
})
}

/**
* 刷新数据到小程序
* @param cb
* @param styleUpdater 上报样式的updater
*/
updateWXSync(cb, styleUpdater) {
const flushList = []
const firstFlushList = []

this.updateWXInner(flushList, firstFlushList)

if (styleUpdater) {
flushList.push(styleUpdater)
}

if (flushList.length === 0) {
recursionMountOrUpdate(this)
cb && cb()
return
}

const showUpdaterMap = getShowUpdaterMap(firstFlushList)
const showUpdaterList = Array.from(showUpdaterMap.values())

/// groupSetData 来优化多次setData

const topWX = styleUpdater ? styleUpdater.inst : this.getWxInst()
topWX.groupSetData(() => {
for(let i = 0; i < flushList.length; i ++ ) {
const {inst, data} = flushList[i]

const updater = showUpdaterMap.get(inst)
if (updater) {
Object.assign(data, updater.hiddenData)
}


if (showUpdaterList.length === 0) {
if (i === 0) {
inst.setData(data, () => {
recursionMountOrUpdate(this)
cb && cb()
})
} else {
inst.setData(data)
}
} else {
inst.setData(data)
}
}

if (showUpdaterList.length !== 0) {
recursionFirstFlushWXSync(this, topWX, firstFlushList, showUpdaterList, () => {
recursionMountOrUpdate(this)
cb && cb()
})
}
})
}

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

if (this.isPageComp) {
this.updateWX(finalCb)
this.updateWXSync(finalCb)
return
}

Expand Down Expand Up @@ -523,7 +649,7 @@ export class Component extends BaseComponent {

const wxInst = pp.getWxInst()

this.updateWX(finalCb, {
this.updateWXSync(finalCb, {
inst: wxInst,
data: {
[stylePath]: newOutStyle
Expand All @@ -535,7 +661,7 @@ export class Component extends BaseComponent {
p = p._p
}
} else {
this.updateWX(finalCb)
this.updateWXSync(finalCb)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/wx-react/miniprogram_dist/WxNormalComp.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export default function (CompMySelf, RNApp) {

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

o.methods.onShow = function () {
Expand Down
51 changes: 51 additions & 0 deletions packages/wx-react/miniprogram_dist/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,57 @@ export function recursionFirstFlushWX(top, topWx, comps, showUpdaterList, cb) {
})
}

export function recursionFirstFlushWXSync(top, topWx, comps, showUpdaterList, cb) {
const newComps = []
topWx.groupSetData(() => {
for(let i = 0; i < comps.length; i ++) {
const item = comps[i]
const wxItem = item.getWxInst()

item._c.forEach(childComp => {
// 组件render null
if (childComp._myOutStyle === false) {
return
}

// 跳过hoc包裹的组件
childComp = childComp.getDeepComp()
newComps.push(childComp)
})


if (i === comps.length - 1) {
if (newComps.length === 0) {
// 最后一次groupSetData
showUpdaterList.forEach(({inst, data}) => {
inst.setData(data)
})

wxItem.setData({
_r: item._r
}, () => {
cb && cb()
})
} else {
wxItem.setData({
_r: item._r
})
}
} else {
wxItem.setData({
_r: item._r
})
}
}


if (newComps.length !== 0) {
recursionFirstFlushWXSync(top, topWx, newComps, showUpdaterList, cb)
}
})
}


/**
* 分层groupSetData的方式,存在一个问题:当父元素的大小,由子元素决定的时候,由于父元素先渲染会导致抖动。
* 解决这个问题的方式是: 先把顶层父元素设置为: opacity: 0; 当所有子孙元素都渲染完成之后统一在恢复样式
Expand Down
2 changes: 1 addition & 1 deletion packages/wx-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@areslabs/wx-react",
"version": "1.0.26",
"version": "1.0.27-beta.0",
"description": "微信版本的React",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 96d3177

Please sign in to comment.