Skip to content

Commit 77d3598

Browse files
committed
perf(wx-react): 1.分层setData的方式初始化组件 2. 使用opacity的方式防止页面抖动
1 parent f68c436 commit 77d3598

File tree

4 files changed

+172
-42
lines changed

4 files changed

+172
-42
lines changed

packages/wx-react/miniprogram_dist/AllComponent.js

+118-37
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
getRealOc,
2020
invokeWillUnmount,
2121
recursionFirstFlushWX,
22+
getShowUpdaterMap,
23+
HIDDEN_STYLE,
2224
recursionMountOrUpdate
2325
} from './util'
2426
import reactUpdate from './ReactUpdate'
@@ -142,6 +144,23 @@ export class BaseComponent {
142144
return inst.getDeepComp()
143145
}
144146

147+
/**
148+
* 如果是hocWrapped组件,一直往外追溯
149+
* @returns {*}
150+
*/
151+
getTopComp() {
152+
if (this.hocWrapped) {
153+
let p = this._p
154+
while (p.hocWrapped) {
155+
p = p._p
156+
}
157+
158+
return instanceManager.getCompInstByUUID(p.__diuu__)
159+
} else {
160+
return this
161+
}
162+
}
163+
145164
getWxInst() {
146165
let diuu = null
147166

@@ -164,11 +183,49 @@ export class BaseComponent {
164183
*/
165184
firstUpdateWX() {
166185
const deepComp = this.getDeepComp()
167-
168186
if (!deepComp || Object.keys(deepComp._r).length === 0) {
187+
// 页面组件render null
169188
recursionMountOrUpdate(this)
189+
return
190+
}
191+
192+
193+
const pageWxInst = this.getWxInst()
194+
const comps = []
195+
// 收集下一次groupSetData的实例
196+
deepComp._c.forEach(item => {
197+
const child = instanceManager.getCompInstByUUID(item)
198+
if (child._myOutStyle) {
199+
const childComp = child.getDeepComp()
200+
comps.push(childComp)
201+
}
202+
})
203+
204+
if (comps.length === 0) {
205+
pageWxInst.setData({
206+
_r: deepComp._r
207+
}, () => {
208+
recursionMountOrUpdate(this)
209+
})
170210
} else {
171-
recursionFirstFlushWX(this, this.getWxInst(), [deepComp])
211+
const styleKey = deepComp.firstStyleKey
212+
const styleValue = deepComp._r[styleKey]
213+
const pageShowUpdater = {
214+
inst: pageWxInst,
215+
data: {
216+
[`_r.${styleKey}`]: styleValue
217+
}
218+
}
219+
pageWxInst.setData({
220+
_r: {
221+
...deepComp._r,
222+
[deepComp.firstStyleKey]: `${styleValue}${HIDDEN_STYLE}`
223+
}
224+
}, () => {
225+
recursionFirstFlushWX(this, pageWxInst, comps, [pageShowUpdater], () => {
226+
recursionMountOrUpdate(this)
227+
})
228+
})
172229
}
173230
}
174231

@@ -178,30 +235,10 @@ export class BaseComponent {
178235
* @param styleUpdater 上报样式的updater
179236
*/
180237
updateWX(cb, styleUpdater) {
181-
182-
// 页面组件特殊处理
183-
let topComp = null
184-
if (this.isPageComp) {
185-
const dc = this.getDeepComp()
186-
if (!dc || Object.keys(dc._r).length === 0) {
187-
this.getWxInst().setData({
188-
_r: {}
189-
}, () => {
190-
recursionMountOrUpdate(this)
191-
cb && cb()
192-
})
193-
return
194-
} else {
195-
topComp = dc
196-
}
197-
} else {
198-
topComp = this
199-
}
200-
201238
const flushList = []
202239
const firstFlushList = []
203240

204-
topComp.updateWXInner(flushList, firstFlushList)
241+
this.updateWXInner(flushList, firstFlushList)
205242

206243
if (styleUpdater) {
207244
flushList.push(styleUpdater)
@@ -213,17 +250,26 @@ export class BaseComponent {
213250
return
214251
}
215252

253+
const showUpdaterMap = getShowUpdaterMap(firstFlushList)
254+
216255
/// groupSetData 来优化多次setData
217256

218257
const topWX = styleUpdater ? styleUpdater.inst : this.getWxInst()
219258
topWX.groupSetData(() => {
220-
console.log('update wow:', flushList)
221259
for(let i = 0; i < flushList.length; i ++ ) {
222260
const {inst, data} = flushList[i]
223261

262+
const updater = showUpdaterMap.get(inst)
263+
if (updater) {
264+
Object.assign(data, updater.hiddenData)
265+
}
266+
224267
if (i === 0) {
225268
inst.setData(data, () => {
226-
recursionFirstFlushWX(this, topWX, firstFlushList, cb)
269+
recursionFirstFlushWX(this, topWX, firstFlushList, Array.from(showUpdaterMap.values()), () => {
270+
recursionMountOrUpdate(this)
271+
cb && cb()
272+
})
227273
})
228274
} else {
229275
inst.setData(data)
@@ -241,7 +287,44 @@ export class BaseComponent {
241287
* @param firstFlushList
242288
*/
243289
updateWXInner(flushList, firstFlushList) {
244-
if (this.firstRender !== FR_DONE) {
290+
let shouldTraversalChild = false
291+
if (this.isPageComp) {
292+
const dc = this.getDeepComp()
293+
if (!dc || Object.keys(dc._r).length === 0) {
294+
// 页面组件 render null
295+
flushList.push({
296+
inst: this.getWxInst(),
297+
data: {
298+
_r: {}
299+
}
300+
})
301+
return
302+
}
303+
304+
305+
if (this.firstRender === FR_DONE && !this.shouldUpdate) {
306+
return
307+
}
308+
309+
if (this instanceof HocComponent) {
310+
shouldTraversalChild = true
311+
} else {
312+
const cp = getChangePath(this._r, this._or)
313+
// _or 不在有用
314+
this._or = {}
315+
316+
if (Object.keys(cp).length === 0) {
317+
shouldTraversalChild = true
318+
} else {
319+
const wxInst = this.getWxInst()
320+
flushList.push({
321+
inst: wxInst,
322+
data: cp
323+
})
324+
shouldTraversalChild = true
325+
}
326+
}
327+
} else if (this.firstRender !== FR_DONE) {
245328
if (this._myOutStyle === false) {
246329
return
247330
}
@@ -253,8 +336,6 @@ export class BaseComponent {
253336
return
254337
}
255338

256-
let shouldTraversalChild = false
257-
258339
if (this instanceof HocComponent) {
259340
shouldTraversalChild = true
260341
} else {
@@ -273,22 +354,21 @@ export class BaseComponent {
273354
})
274355
shouldTraversalChild = true
275356
} else {
276-
const top = this.topExistWx()//this.getDeepComp()
357+
const top = this.topExistWx()
277358
firstFlushList.push(top)
278359
}
279360
}
280361
}
362+
}
281363

282-
if (shouldTraversalChild) {
283-
const children = this._c
284-
for (let i = 0; i < children.length; i++) {
285-
const childUuid = children[i]
286-
const child = instanceManager.getCompInstByUUID(childUuid)
364+
if (shouldTraversalChild) {
365+
const children = this._c
366+
for (let i = 0; i < children.length; i++) {
367+
const childUuid = children[i]
368+
const child = instanceManager.getCompInstByUUID(childUuid)
287369

288-
child.updateWXInner(flushList, firstFlushList)
289-
}
370+
child.updateWXInner(flushList, firstFlushList)
290371
}
291-
292372
}
293373
}
294374
}
@@ -440,6 +520,7 @@ export class Component extends BaseComponent {
440520
/* eslint-disable-next-line */
441521
while (true) {
442522
const pp = p._p
523+
p._myOutStyle = newOutStyle
443524
if (pp.isPageComp || !p._isFirstEle || p._TWFBStylePath) {
444525
const stylePath = p._TWFBStylePath || `${p._keyPath}style`
445526
setDeepData(pp, newOutStyle, stylePath)

packages/wx-react/miniprogram_dist/render.js

+5
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,11 @@ export default function render(vnode, parentInst, parentContext, data, oldData,
600600
const subVnode = inst.render()
601601
if (subVnode && subVnode.isReactElement) {
602602
subVnode.isFirstEle = true
603+
604+
if (inst.isPageComp) {
605+
// 首屏渲染的时候 需要先设置这个style opacity为0。
606+
inst.firstStyleKey = subVnode.diuu + 'style'
607+
}
603608
}
604609

605610
inst._parentContext = parentContext

packages/wx-react/miniprogram_dist/util.js

+48-4
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,8 @@ export function recursionMountOrUpdate(comp) {
184184
}
185185
}
186186

187-
export function recursionFirstFlushWX(top, topWx, comps, cb) {
188-
console.log('recursionFirstFlushWX:', comps)
187+
export function recursionFirstFlushWX(top, topWx, comps, showUpdaterList, cb) {
189188
if (comps.length === 0) {
190-
recursionMountOrUpdate(top)
191189
cb && cb()
192190
return
193191
}
@@ -211,10 +209,16 @@ export function recursionFirstFlushWX(top, topWx, comps, cb) {
211209
})
212210

213211
if (i === comps.length - 1) {
212+
if (newComps.length === 0) {
213+
showUpdaterList.forEach(({inst, data}) => {
214+
inst.setData(data)
215+
})
216+
}
217+
214218
wxItem.setData({
215219
_r: item._r
216220
}, () => {
217-
recursionFirstFlushWX(top, topWx, newComps, cb)
221+
recursionFirstFlushWX(top, topWx, newComps, showUpdaterList, cb)
218222
})
219223
} else {
220224
wxItem.setData({
@@ -224,3 +228,43 @@ export function recursionFirstFlushWX(top, topWx, comps, cb) {
224228
}
225229
})
226230
}
231+
232+
/**
233+
* 分层groupSetData的方式,存在一个问题:当父元素的大小,由子元素决定的时候,由于父元素先渲染会导致抖动。
234+
* 解决这个问题的方式是: 先把顶层父元素设置为: opacity: 0; 当所有子孙元素都渲染完成之后统一在恢复样式
235+
* @type {string}
236+
*/
237+
export const HIDDEN_STYLE = " opacity: 0;"
238+
239+
240+
export function getShowUpdaterMap(firstFlushList) {
241+
const showUpdaterMap = new Map()
242+
firstFlushList.forEach(comp => {
243+
const topComp = comp.getTopComp()
244+
const p = topComp._p.getWxInst()
245+
246+
const key = topComp._keyPath
247+
const value = topComp._myOutStyle
248+
249+
const updater = showUpdaterMap.get(p)
250+
if (updater) {
251+
Object.assign(updater.hiddenData, {
252+
[`${key}style`]: `${value}${HIDDEN_STYLE}`
253+
})
254+
Object.assign(updater.data, {
255+
[`${key}style`]: value
256+
})
257+
} else {
258+
showUpdaterMap.set(p, {
259+
inst: p,
260+
hiddenData: {
261+
[`${key}style`]: `${value}${HIDDEN_STYLE}`
262+
},
263+
data: {
264+
[`${key}style`]: value
265+
}
266+
})
267+
}
268+
})
269+
return showUpdaterMap
270+
}

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.25-beta.2",
3+
"version": "1.0.25-beta.3",
44
"description": "微信版本的React",
55
"main": "index.js",
66
"scripts": {

0 commit comments

Comments
 (0)