feat: improves performance of module

pull/1117/head
George Treviranus 8 months ago
parent 8767fa4e3e
commit be473e1ab0

@ -16,11 +16,11 @@ const ATTRS = "attrs";
const PROPS = "props"; const PROPS = "props";
const DATA = "data"; const DATA = "data";
const HYPHEN_CHAR = "-"; const HYPHEN_CHAR = "-";
const SHORTHAND_MODULE_PROPS = ["hook", "on", ATTRS, PROPS, DATASET]; const SHORTHAND_MODULE_PROPS = new Set(["hook", "on", ATTRS, PROPS, DATASET]);
export const DOM_PROPS = ["className", "tabIndex", "id"]; export const DOM_PROPS = new Set(["className", "tabIndex", "id"]);
// See: https://github.com/snabbdom/snabbdom/blob/master/src/vnode.ts#L21 // See: https://github.com/snabbdom/snabbdom/blob/master/src/vnode.ts#L21
const IGNORE_PROPS = [ const IGNORE_PROPS = new Set([
"key", "key",
"style", "style",
"class", "class",
@ -30,7 +30,16 @@ const IGNORE_PROPS = [
"args", "args",
"is", "is",
...SHORTHAND_MODULE_PROPS ...SHORTHAND_MODULE_PROPS
]; ]);
const prefixToModule: Record<string, string> = {
[DATA]: DATASET,
hook: "hook",
on: "on",
attrs: ATTRS,
props: PROPS,
dataset: DATASET
};
const forwardProp = ( const forwardProp = (
data: VNodeData, data: VNodeData,
@ -40,12 +49,10 @@ const forwardProp = (
prefixedKey?: string prefixedKey?: string
) => { ) => {
if (data[moduleName]) { if (data[moduleName]) {
data[moduleName]![key] = value; data[moduleName][key] = value;
} else { } else {
data[moduleName] = { [key]: value }; data[moduleName] = { [key]: value };
} }
// remove the old prop from vnode data
delete data[prefixedKey || key]; delete data[prefixedKey || key];
}; };
@ -55,55 +62,41 @@ const forwardJsxProps = (oldVNode: VNode, _vnode: VNode) => {
if (!vnode.data) return; if (!vnode.data) return;
for (const propKey in vnode.data) { for (const propKey in vnode.data) {
// ignore modules/props that don't need handling if (IGNORE_PROPS.has(propKey)) {
if (IGNORE_PROPS.includes(propKey)) {
continue; continue;
} }
// forward all other props into modules
else {
const propValue = vnode.data[propKey];
// forward DOM properties
const propertyIndex = DOM_PROPS.indexOf(propKey);
if (propertyIndex > -1) {
forwardProp(vnode.data, PROPS, DOM_PROPS[propertyIndex], propValue);
continue;
}
// check if prop instructs a module (using prefix) const propValue = vnode.data[propKey];
const hyphenIdx = propKey.indexOf(HYPHEN_CHAR);
if (hyphenIdx > 0) {
const prefix = propKey.slice(0, hyphenIdx);
const moduleTarget =
prefix === DATA
? DATA
: SHORTHAND_MODULE_PROPS.find(
(moduleName) => moduleName === prefix
);
if (moduleTarget) { // forward dom properties to props module
const propName = propKey.slice(hyphenIdx + 1); if (DOM_PROPS.has(propKey)) {
forwardProp(vnode.data, PROPS, propKey, propValue);
continue;
}
if (moduleTarget === DATA) { // forward module-prefixed props to the correct object
forwardProp( // e.g., `vnode.data['attrs-value']` --> `vnode.data.attrs.value`
vnode.data, const hyphenIdx = propKey.indexOf(HYPHEN_CHAR);
DATASET, if (hyphenIdx > 0) {
kebabToCamel(propName), const prefix = propKey.slice(0, hyphenIdx);
propValue, const moduleTarget = prefixToModule[prefix];
propKey
); if (moduleTarget) {
} else { const propName = propKey.slice(hyphenIdx + 1);
forwardProp(vnode.data, moduleTarget, propName, propValue, propKey); forwardProp(
} vnode.data,
moduleTarget,
moduleTarget === DATASET ? kebabToCamel(propName) : propName,
propValue,
propKey
);
continue; continue;
}
} }
// forward any other props into attributes
forwardProp(vnode.data, ATTRS, propKey, propValue);
} }
// everything else treated as an attribute
forwardProp(vnode.data, ATTRS, propKey, propValue);
} }
}; };

Loading…
Cancel
Save