Merge branch 'fix/rax-render-perf' into 'release/1.0.26'

fix: rax perf



See merge request !1089190
This commit is contained in:
荣彬 2020-12-21 18:02:05 +08:00
commit 74de9e77ab
2 changed files with 208 additions and 167 deletions

View File

@ -0,0 +1,11 @@
import { createElement, PureComponent } from 'rax';
export default class DivView extends PureComponent {
static displayName = 'Div';
static version = '0.0.0';
render() {
return createElement('div', this.props);
}
}

View File

@ -23,6 +23,7 @@ import {
getFileCssName, getFileCssName,
} from '../utils'; } from '../utils';
import VisualDom from '../comp/visualDom'; import VisualDom from '../comp/visualDom';
import Div from '../comp/Div';
import AppContext from '../context/appContext'; import AppContext from '../context/appContext';
import compWrapper from '../hoc/compWrapper'; import compWrapper from '../hoc/compWrapper';
@ -248,32 +249,37 @@ export default class BaseEngine extends Component {
// parentInfo 父组件的信息包含schema和Comp // parentInfo 父组件的信息包含schema和Comp
// idx 若为循环渲染的循环Index // idx 若为循环渲染的循环Index
__createVirtualDom = (schema, self, parentInfo, idx) => { __createVirtualDom = (schema, self, parentInfo, idx) => {
const { engine } = this.context || {};
try {
if (!schema) return null; if (!schema) return null;
// rax text prop 兼容处理 if (schema.componentName === 'Text') { // 这个是不是不应该在这里处理
if (schema.componentName === 'Text') {
if (typeof schema.props.text === 'string') { if (typeof schema.props.text === 'string') {
schema = { ...schema }; schema = { ...schema };
schema.children = [schema.props.text]; schema.children = [schema.props.text];
} }
} }
const { __appHelper: appHelper, __components: components = {}, __componentsMap: componentsMap = {} } = this.props || {}; const { __appHelper: appHelper, __components: components = {} } = this.props || {};
const { engine } = this.context || {};
if (isJSExpression(schema)) { if (isJSExpression(schema)) {
return parseExpression(schema, self); return parseExpression(schema, self);
} }
if (isJSSlot(schema)) {
return this.__createVirtualDom(schema.value, self, parentInfo);
}
if (typeof schema === 'string') return schema; if (typeof schema === 'string') return schema;
if (typeof schema === 'number' || typeof schema === 'boolean') { if (typeof schema === 'number' || typeof schema === 'boolean') {
return schema.toString(); return schema.toString();
} }
if (Array.isArray(schema)) { if (Array.isArray(schema)) {
if (schema.length === 1) return this.__createVirtualDom(schema[0], self, parentInfo); if (schema.length === 1) return this.__createVirtualDom(schema[0], self, parentInfo);
return schema.map((item, idx) => this.__createVirtualDom(item, self, parentInfo, item && item.__ctx && item.__ctx.lunaKey ? '' : idx)); return schema.map((item, idy) => this.__createVirtualDom(item, self, parentInfo, item && item.__ctx && item.__ctx.lunaKey ? '' : idy));
} }
// FIXME
const _children = this.getSchemaChildren(schema);
// 解析占位组件 // 解析占位组件
if (schema.componentName === 'Flagment' && schema.children) { if (schema.componentName === 'Flagment' && _children) {
const tarChildren = isJSExpression(schema.children) ? parseExpression(schema.children, self) : schema.children; const tarChildren = isJSExpression(_children) ? parseExpression(_children, self) : _children;
return this.__createVirtualDom(tarChildren, self, parentInfo); return this.__createVirtualDom(tarChildren, self, parentInfo);
} }
@ -287,18 +293,21 @@ export default class BaseEngine extends Component {
return null; return null;
} }
if (schema.loop !== undefined) { if (schema.loop != null) {
const loop = parseData(schema.loop, self);
if ((Array.isArray(loop) && loop.length > 0) || isJSExpression(loop)) {
return this.__createLoopVirtualDom( return this.__createLoopVirtualDom(
{ {
...schema, ...schema,
loop: parseData(schema.loop, self), loop,
}, },
self, self,
parentInfo, parentInfo,
idx, idx,
); );
} }
const condition = schema.condition === undefined ? true : parseData(schema.condition, self); }
const condition = schema.condition == null ? true : parseData(schema.condition, self);
if (!condition) return null; if (!condition) return null;
let scopeKey = ''; let scopeKey = '';
@ -340,32 +349,36 @@ export default class BaseEngine extends Component {
if (engine && engine.props.designMode) { if (engine && engine.props.designMode) {
otherProps.__designMode = engine.props.designMode; otherProps.__designMode = engine.props.designMode;
} }
const componentInfo = componentsMap[schema.componentName] || {}; const componentInfo = {};
const props = this.__parseProps(schema.props, self, '', { const props =
this.__parseProps(schema.props, self, '', {
schema, schema,
Comp, Comp,
componentInfo: { componentInfo: {
...componentInfo, ...componentInfo,
props: transformArrayToMap(componentInfo.props, 'name'), props: transformArrayToMap(componentInfo.props, 'name'),
}, },
}); }) || {};
// 对于可以获取到ref的组件做特殊处理 // 对于可以获取到ref的组件做特殊处理
if (!acceptsRef(Comp)) { if (!acceptsRef(Comp)) {
Comp = compWrapper(Comp); Comp = compWrapper(Comp);
} }
// if (acceptsRef(Comp)) {
otherProps.ref = (ref) => { otherProps.ref = (ref) => {
this.$(props.fieldId, ref); // 收集ref this.$(props.fieldId, ref); // 收集ref
const refProps = props.ref; const refProps = props.ref;
if (refProps && typeof refProps === 'string') { if (refProps && typeof refProps === 'string') {
this[refProps] = ref; this[refProps] = ref;
} }
engine && engine.props.onCompGetRef(schema, ref); ref && engine && engine.props.onCompGetRef(schema, ref);
}; };
// }
// scope需要传入到组件上 // scope需要传入到组件上
if (scopeKey && this.__compScopes[scopeKey]) { if (scopeKey && this.__compScopes[scopeKey]) {
props.__scope = this.__compScopes[scopeKey]; props.__scope = this.__compScopes[scopeKey];
} }
// FIXME 这里清除 key 是为了避免循环渲染中更改 key 导致的渲染重复
props.key = '';
if (schema.__ctx && schema.__ctx.lunaKey) { if (schema.__ctx && schema.__ctx.lunaKey) {
if (!isFileSchema(schema)) { if (!isFileSchema(schema)) {
engine && engine.props.onCompGetCtx(schema, self); engine && engine.props.onCompGetCtx(schema, self);
@ -374,11 +387,16 @@ export default class BaseEngine extends Component {
} else if (typeof idx === 'number' && !props.key) { } else if (typeof idx === 'number' && !props.key) {
props.key = idx; props.key = idx;
} }
props.__id = schema.id;
if (!isFileSchema(schema) && schema.children) { props.__id = schema.id;
this.__createVirtualDom( if (!props.key) {
isJSExpression(schema.children) ? parseExpression(schema.children, self) : schema.children, props.key = props.__id;
}
let child = null;
if (/*!isFileSchema(schema) && */!!_children) {
child = this.__createVirtualDom(
isJSExpression(_children) ? parseExpression(_children, self) : _children,
self, self,
{ {
schema, schema,
@ -386,38 +404,26 @@ export default class BaseEngine extends Component {
}, },
); );
} }
const renderComp = (props) => engine.createElement(Comp, props, child);
const renderComp = (props) => engine.createElement(
Comp,
props,
(!isFileSchema(schema) &&
!!schema.children &&
this.__createVirtualDom(
isJSExpression(schema.children) ? parseExpression(schema.children, self) : schema.children,
self,
{
schema,
Comp,
},
))
|| null,
);
// 设计模式下的特殊处理 // 设计模式下的特殊处理
if (engine && [DESIGN_MODE.EXTEND, DESIGN_MODE.BORDER].includes(engine.props.designMode)) { if (engine && [DESIGN_MODE.EXTEND, DESIGN_MODE.BORDER].includes(engine.props.designMode)) {
// 对于overlay,dialog等组件为了使其在设计模式下显示外层需要增加一个div容器 // 对于overlay,dialog等组件为了使其在设计模式下显示外层需要增加一个div容器
if (OVERLAY_LIST.includes(schema.componentName)) { if (OVERLAY_LIST.includes(schema.componentName)) {
const { ref, ...overlayProps } = otherProps; const { ref, ...overlayProps } = otherProps;
return ( return (
<div ref={ref} __designMode={engine.props.designMode}> <Div ref={ref} __designMode={engine.props.designMode}>
{renderComp({ ...props, ...overlayProps })} {renderComp({ ...props, ...overlayProps })}
</div> </Div>
); );
} }
// 虚拟dom显示 // 虚拟dom显示
if (componentInfo && componentInfo.parentRule) { if (componentInfo && componentInfo.parentRule) {
const parentList = componentInfo.parentRule.split(','); const parentList = componentInfo.parentRule.split(',');
const { schema: parentSchema, Comp: parentComp } = parentInfo; const { schema: parentSchema, Comp: parentComp } = parentInfo;
if (!parentList.includes(parentSchema.componentName) || parentComp !== components[parentSchema.componentName]) { if (
!parentList.includes(parentSchema.componentName) ||
parentComp !== components[parentSchema.componentName]
) {
props.__componentName = schema.componentName; props.__componentName = schema.componentName;
Comp = VisualDom; Comp = VisualDom;
} else { } else {
@ -427,6 +433,30 @@ export default class BaseEngine extends Component {
} }
} }
return renderComp({ ...props, ...otherProps }); return renderComp({ ...props, ...otherProps });
} catch (e) {
return engine.createElement(engine.getFaultComponent(), {
error: e,
schema,
self,
parentInfo,
idx,
});
}
};
getSchemaChildren = (schema) => {
if (!schema || !schema.props) {
return schema?.children;
}
if (!schema.children) return schema.props.children;
if (!schema.props.children) return schema.children;
let _children = [].concat(schema.children);
if (Array.isArray(schema.props.children)) {
_children = _children.concat(schema.props.children);
} else {
_children.push(schema.props.children);
}
return _children;
}; };
__createLoopVirtualDom = (schema, self, parentInfo, idx) => { __createLoopVirtualDom = (schema, self, parentInfo, idx) => {