refactor(perf): 不再为无样式的节点创建 style 标签, 修改节点样式后改为更新 style 节点

This commit is contained in:
lihao.ylh 2021-06-28 13:55:23 +08:00
parent d7f13e430d
commit e02d7fe16e

View File

@ -1,25 +1,27 @@
import { project } from '@ali/lowcode-engine'; import { project } from '@ali/lowcode-engine';
import { isPlainObject } from '@ali/lowcode-utils';
import { toCss } from '@ali/vu-css-style'; import { toCss } from '@ali/vu-css-style';
export function stylePropsReducer(props: any, node: any) { export function stylePropsReducer(props: any, node: any) {
let cssId; let cssId;
let cssClass; let cssClass;
let styleProp; let styleProp;
if (props && typeof props === 'object' && props.__style__) { if (!props || typeof props !== 'object') return props;
cssId = `_style_pesudo_${node.id.replace(/\$/g, '_')}`; if (props.__style__) {
cssClass = `_css_pesudo_${node.id.replace(/\$/g, '_')}`; cssId = `_style_pseudo_${node.id.replace(/\$/g, '_')}`;
cssClass = `_css_pseudo_${node.id.replace(/\$/g, '_')}`;
styleProp = props.__style__; styleProp = props.__style__;
appendStyleNode(props, styleProp, cssClass, cssId); appendStyleNode(props, styleProp, cssClass, cssId);
} }
if (props && typeof props === 'object' && props.pageStyle) { if (props.pageStyle) {
cssId = '_style_pesudo_engine-document'; cssId = '_style_pseudo_engine-document';
cssClass = 'engine-document'; cssClass = 'engine-document';
styleProp = props.pageStyle; styleProp = props.pageStyle;
appendStyleNode(props, styleProp, cssClass, cssId); appendStyleNode(props, styleProp, cssClass, cssId);
} }
if (props && typeof props === 'object' && props.containerStyle) { if (props.containerStyle) {
cssId = `_style_pesudo_${node.id}`; cssId = `_style_pseudo_${node.id}`;
cssClass = `_css_pesudo_${node.id.replace(/\$/g, '_')}`; cssClass = `_css_pseudo_${node.id.replace(/\$/g, '_')}`;
styleProp = props.containerStyle; styleProp = props.containerStyle;
appendStyleNode(props, styleProp, cssClass, cssId); appendStyleNode(props, styleProp, cssClass, cssId);
} }
@ -33,24 +35,33 @@ function appendStyleNode(props: any, styleProp: any, cssClass: string, cssId: st
if (!doc) { if (!doc) {
return; return;
} }
if (isPlainObject(styleProp)) {
styleProp = isEmptyObject(styleProp) ? '' : toCss(styleProp);
}
if (typeof styleProp === 'string' && styleProp) {
const dom = doc.getElementById(cssId) as HTMLStyleElement; const dom = doc.getElementById(cssId) as HTMLStyleElement;
if (typeof styleProp === 'object') {
styleProp = toCss(styleProp);
}
if (typeof styleProp === 'string') {
const newStyleStr = transformStyleStr(styleProp, cssClass); const newStyleStr = transformStyleStr(styleProp, cssClass);
if (dom && stringEquals(dom.textContent!, newStyleStr)) { if (!dom) {
return;
}
if (dom) {
dom.parentNode?.removeChild(dom);
}
const s = doc.createElement('style'); const s = doc.createElement('style');
s.setAttribute('type', 'text/css'); s.setAttribute('type', 'text/css');
s.setAttribute('id', cssId); s.setAttribute('id', cssId);
doc.getElementsByTagName('head')[0].appendChild(s); doc.getElementsByTagName('head')[0].appendChild(s);
s.appendChild(doc.createTextNode(newStyleStr)); s.appendChild(doc.createTextNode(newStyleStr));
return;
} }
if (!stringEquals(dom.innerHTML!, newStyleStr)) {
dom.innerHTML = newStyleStr;
}
}
}
function isEmptyObject(obj: any) {
if (!isPlainObject(obj)) return false;
let empty = true;
for (let k in obj) {
empty = false;
}
return empty;
} }
function stringEquals(str: string, targetStr: string): boolean { function stringEquals(str: string, targetStr: string): boolean {