From 2caea68605deea51d61eec4a018b515bb0bd210b Mon Sep 17 00:00:00 2001
From: mantou132 <709922234@qq.com>
Date: Tue, 16 Jul 2024 00:55:04 +0800
Subject: [PATCH] [gem] Improve light dom apply style performance
---
packages/gem-examples/src/theme/index.ts | 35 ++++++++-------
packages/gem/src/helper/theme.ts | 6 +--
packages/gem/src/lib/decorators.ts | 2 +-
packages/gem/src/lib/element.ts | 54 +++++++++++++++++-------
packages/gem/src/lib/utils.ts | 11 -----
5 files changed, 63 insertions(+), 45 deletions(-)
diff --git a/packages/gem-examples/src/theme/index.ts b/packages/gem-examples/src/theme/index.ts
index 32f0e382..9f952763 100644
--- a/packages/gem-examples/src/theme/index.ts
+++ b/packages/gem-examples/src/theme/index.ts
@@ -1,4 +1,4 @@
-import { GemElement, html, render, customElement, connectStore } from '@mantou/gem';
+import { GemElement, html, render, customElement, connectStore, createCSSSheet, css, adoptedStyle } from '@mantou/gem';
import { createTheme, getThemeStore, updateTheme } from '@mantou/gem/helper/theme';
import { mediaQuery } from '@mantou/gem/helper/mediaquery';
@@ -25,24 +25,29 @@ document.onclick = () => {
});
};
+const style = createCSSSheet(css`
+ div {
+ color: rgba(${theme.color}, 0.5);
+ border: 2px solid ${theme.primaryColor};
+ }
+`);
+
+const style1 = createCSSSheet(
+ css`
+ div {
+ border: 2px solid ${printTheme.primaryColor};
+ }
+ `,
+ mediaQuery.PRINT,
+);
+
@customElement('app-root')
@connectStore(themeStore)
+@adoptedStyle(style1)
+@adoptedStyle(style)
export class App extends GemElement {
render() {
- return html`
-
-
color: ${themeStore.primaryColor}
- `;
+ return html`color: ${themeStore.primaryColor}
`;
}
}
diff --git a/packages/gem/src/helper/theme.ts b/packages/gem/src/helper/theme.ts
index 1fcd5ca1..2456d69f 100644
--- a/packages/gem/src/helper/theme.ts
+++ b/packages/gem/src/helper/theme.ts
@@ -32,7 +32,7 @@ const setThemeFnMap = new WeakMap();
*/
export function createTheme>(themeObj: T) {
const salt = randomStr();
- const style = document.createElement('style');
+ const style = new CSSStyleSheet();
const store = createStore(themeObj);
const theme: Record = {};
const props: Record = {};
@@ -48,10 +48,10 @@ export function createTheme>(themeObj: T) {
setTheme();
const getStyle = () =>
`:root, :host {${Object.keys(store).reduce((prev, key) => prev + `${props[key]}:${store[key]};`, '')}}`;
- const replace = () => (style.textContent = getStyle());
+ const replace = () => style.replaceSync(getStyle());
connect(store, replace);
replace();
- (document.head || document.documentElement).append(style);
+ document.adoptedStyleSheets.push(style);
return theme as SomeType;
}
diff --git a/packages/gem/src/lib/decorators.ts b/packages/gem/src/lib/decorators.ts
index 84f38ca3..1d6ae7c7 100644
--- a/packages/gem/src/lib/decorators.ts
+++ b/packages/gem/src/lib/decorators.ts
@@ -466,7 +466,7 @@ function defineEmitter(
}
/**
- * 分配一个构造的样式表,如果元素是 lightDOM,则将样式表挂载到 RootNode 上
+ * 分配一个构造的样式表,前面的优先级越高(因为装饰器是越近越早执行)
*
* For example
* ```ts
diff --git a/packages/gem/src/lib/element.ts b/packages/gem/src/lib/element.ts
index 926a4d21..cf4e4475 100644
--- a/packages/gem/src/lib/element.ts
+++ b/packages/gem/src/lib/element.ts
@@ -1,16 +1,7 @@
import { html, render, TemplateResult } from 'lit-html';
import { connect, Store } from './store';
-import {
- LinkedList,
- addMicrotask,
- Sheet,
- SheetToken,
- isArrayChange,
- GemError,
- removeItems,
- addListener,
-} from './utils';
+import { LinkedList, addMicrotask, Sheet, SheetToken, isArrayChange, GemError, addListener } from './utils';
export { html, svg, render, directive, TemplateResult, SVGTemplateResult } from 'lit-html';
@@ -47,6 +38,43 @@ const tick = (timeStamp = performance.now()) => {
};
noBlockingTaskList.addEventListener('start', () => addMicrotask(tick));
+const rootStyleSheetInfo = new WeakMap>();
+const rootUpdateFnMap = new WeakMap