mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-06-06 03:45:18 +00:00
[fix] StyleSheet registry key check
This commit is contained in:
@@ -82,6 +82,7 @@ Exported modules:
|
|||||||
* [`Vibration`](docs/apis/Vibration.md)
|
* [`Vibration`](docs/apis/Vibration.md)
|
||||||
|
|
||||||
<span id="#why"></span>
|
<span id="#why"></span>
|
||||||
|
|
||||||
## Why?
|
## Why?
|
||||||
|
|
||||||
There are many different teams at Twitter building web applications with React.
|
There are many different teams at Twitter building web applications with React.
|
||||||
|
|||||||
@@ -65,6 +65,10 @@ AppRegistry.runApplication('App', {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Setting `process.env.__REACT_NATIVE_DEBUG_ENABLED__` to `true` will expose some
|
||||||
|
debugging logs. This can help track down when you're rendering without the
|
||||||
|
performance benefit of cached styles.
|
||||||
|
|
||||||
## Server-side rendering
|
## Server-side rendering
|
||||||
|
|
||||||
Rendering using the `AppRegistry`:
|
Rendering using the `AppRegistry`:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ const registerStyle = (id, flatStyle) => {
|
|||||||
}
|
}
|
||||||
}).join(' ').trim();
|
}).join(' ').trim();
|
||||||
|
|
||||||
const key = `${prefix}${id}`;
|
const key = `${prefix}-${id}`;
|
||||||
resolvedPropsCache[key] = { className };
|
resolvedPropsCache[key] = { className };
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
@@ -76,6 +76,7 @@ const resolveProps = (reactNativeStyle) => {
|
|||||||
if (injectedClassNames[singleClassName]) {
|
if (injectedClassNames[singleClassName]) {
|
||||||
return singleClassName;
|
return singleClassName;
|
||||||
} else {
|
} else {
|
||||||
|
// 4x slower render
|
||||||
style[prop] = value;
|
style[prop] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,11 +111,14 @@ const resolveProps = (reactNativeStyle) => {
|
|||||||
* Caching layer over 'resolveProps'
|
* Caching layer over 'resolveProps'
|
||||||
*/
|
*/
|
||||||
const resolvePropsIfNeeded = (key, style) => {
|
const resolvePropsIfNeeded = (key, style) => {
|
||||||
if (!key || !resolvedPropsCache[key]) {
|
if (key) {
|
||||||
|
if (!resolvedPropsCache[key]) {
|
||||||
// slow: convert style object to props and cache
|
// slow: convert style object to props and cache
|
||||||
resolvedPropsCache[key] = resolveProps(style);
|
resolvedPropsCache[key] = resolveProps(style);
|
||||||
}
|
}
|
||||||
return resolvedPropsCache[key];
|
return resolvedPropsCache[key];
|
||||||
|
}
|
||||||
|
return resolveProps(style);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,6 +127,18 @@ const resolvePropsIfNeeded = (key, style) => {
|
|||||||
const StyleRegistry = {
|
const StyleRegistry = {
|
||||||
initialize(classNames) {
|
initialize(classNames) {
|
||||||
injectedClassNames = classNames;
|
injectedClassNames = classNames;
|
||||||
|
|
||||||
|
if (process.env.__REACT_NATIVE_DEBUG_ENABLED__) {
|
||||||
|
if (global.__REACT_NATIVE_DEBUG_ENABLED__styleRegistryTimer) {
|
||||||
|
clearInterval(global.__REACT_NATIVE_DEBUG_ENABLED__styleRegistryTimer);
|
||||||
|
}
|
||||||
|
global.__REACT_NATIVE_DEBUG_ENABLED__styleRegistryTimer = setInterval(() => {
|
||||||
|
const entryCount = Object.keys(resolvedPropsCache).length;
|
||||||
|
console.groupCollapsed('[StyleSheet] resolved props cache snapshot:', entryCount, 'entries');
|
||||||
|
console.log(resolvedPropsCache);
|
||||||
|
console.groupEnd();
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
@@ -155,6 +171,7 @@ const StyleRegistry = {
|
|||||||
// flatten the array
|
// flatten the array
|
||||||
// [ 1, [ 2, 3 ], { prop: value }, 4, 5 ] => [ 1, 2, 3, { prop: value }, 4, 5 ];
|
// [ 1, [ 2, 3 ], { prop: value }, 4, 5 ] => [ 1, 2, 3, { prop: value }, 4, 5 ];
|
||||||
const flatArray = flattenArray(reactNativeStyle);
|
const flatArray = flattenArray(reactNativeStyle);
|
||||||
|
|
||||||
let isArrayOfNumbers = true;
|
let isArrayOfNumbers = true;
|
||||||
for (let i = 0; i < flatArray.length; i++) {
|
for (let i = 0; i < flatArray.length; i++) {
|
||||||
if (typeof flatArray[i] !== 'number') {
|
if (typeof flatArray[i] !== 'number') {
|
||||||
@@ -163,14 +180,32 @@ const StyleRegistry = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isArrayOfNumbers) {
|
// TODO: determine when/if to cache unregistered styles. This produces 2x
|
||||||
// cache resolved props
|
// faster benchmark results for unregistered styles. However, the cache
|
||||||
const key = `${prefix}${flatArray.join('-')}`;
|
// could be filled with props that are never used again.
|
||||||
|
//
|
||||||
|
// let hasValidKey = true;
|
||||||
|
// let key = flatArray.reduce((keyParts, element) => {
|
||||||
|
// if (typeof element === 'number') {
|
||||||
|
// keyParts.push(element);
|
||||||
|
// } else {
|
||||||
|
// if (element.transform) {
|
||||||
|
// hasValidKey = false;
|
||||||
|
// } else {
|
||||||
|
// const objectAsKey = Object.keys(element).map((prop) => `${prop}:${element[prop]}`).join(';');
|
||||||
|
// if (objectAsKey !== '') {
|
||||||
|
// keyParts.push(objectAsKey);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return keyParts;
|
||||||
|
// }, [ prefix ]).join('-');
|
||||||
|
// if (!hasValidKey) { key = null; }
|
||||||
|
|
||||||
|
// cache resolved props when all styles are registered
|
||||||
|
const key = isArrayOfNumbers ? `${prefix}${flatArray.join('-')}` : null;
|
||||||
|
|
||||||
return resolvePropsIfNeeded(key, flatArray);
|
return resolvePropsIfNeeded(key, flatArray);
|
||||||
} else {
|
|
||||||
// resolve
|
|
||||||
return resolveProps(flatArray);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,25 @@
|
|||||||
exports[`components/Text prop "children" 1`] = `
|
exports[`components/Text prop "children" 1`] = `
|
||||||
<span
|
<span
|
||||||
className="rn-borderTopWidth:0px rn-borderRightWidth:0px rn-borderBottomWidth:0px rn-borderLeftWidth:0px rn-color:inherit rn-display:inline rn-font:inherit rn-marginTop:0px rn-marginRight:0px rn-marginBottom:0px rn-marginLeft:0px rn-paddingTop:0px rn-paddingRight:0px rn-paddingBottom:0px rn-paddingLeft:0px rn-textDecoration:none rn-whiteSpace:pre-wrap rn-wordWrap:break-word"
|
className="
|
||||||
style={
|
rn-borderTopWidth:0px
|
||||||
Array [
|
rn-borderRightWidth:0px
|
||||||
3,
|
rn-borderBottomWidth:0px
|
||||||
undefined,
|
rn-borderLeftWidth:0px
|
||||||
false,
|
rn-color:inherit
|
||||||
false,
|
rn-display:inline
|
||||||
undefined,
|
rn-font:inherit
|
||||||
]
|
rn-marginTop:0px
|
||||||
}>
|
rn-marginRight:0px
|
||||||
|
rn-marginBottom:0px
|
||||||
|
rn-marginLeft:0px
|
||||||
|
rn-paddingTop:0px
|
||||||
|
rn-paddingRight:0px
|
||||||
|
rn-paddingBottom:0px
|
||||||
|
rn-paddingLeft:0px
|
||||||
|
rn-textDecoration:none
|
||||||
|
rn-whiteSpace:pre-wrap
|
||||||
|
rn-wordWrap:break-word"
|
||||||
|
style={Object {}}>
|
||||||
children
|
children
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
@@ -44,16 +54,26 @@ rn-wordWrap:break-word"
|
|||||||
|
|
||||||
exports[`components/Text prop "selectable" 1`] = `
|
exports[`components/Text prop "selectable" 1`] = `
|
||||||
<span
|
<span
|
||||||
className="rn-borderTopWidth:0px rn-borderRightWidth:0px rn-borderBottomWidth:0px rn-borderLeftWidth:0px rn-color:inherit rn-display:inline rn-font:inherit rn-marginTop:0px rn-marginRight:0px rn-marginBottom:0px rn-marginLeft:0px rn-paddingTop:0px rn-paddingRight:0px rn-paddingBottom:0px rn-paddingLeft:0px rn-textDecoration:none rn-whiteSpace:pre-wrap rn-wordWrap:break-word"
|
className="
|
||||||
style={
|
rn-borderTopWidth:0px
|
||||||
Array [
|
rn-borderRightWidth:0px
|
||||||
3,
|
rn-borderBottomWidth:0px
|
||||||
undefined,
|
rn-borderLeftWidth:0px
|
||||||
false,
|
rn-color:inherit
|
||||||
false,
|
rn-display:inline
|
||||||
undefined,
|
rn-font:inherit
|
||||||
]
|
rn-marginTop:0px
|
||||||
} />
|
rn-marginRight:0px
|
||||||
|
rn-marginBottom:0px
|
||||||
|
rn-marginLeft:0px
|
||||||
|
rn-paddingTop:0px
|
||||||
|
rn-paddingRight:0px
|
||||||
|
rn-paddingBottom:0px
|
||||||
|
rn-paddingLeft:0px
|
||||||
|
rn-textDecoration:none
|
||||||
|
rn-whiteSpace:pre-wrap
|
||||||
|
rn-wordWrap:break-word"
|
||||||
|
style={Object {}} />
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`components/Text prop "selectable" 2`] = `
|
exports[`components/Text prop "selectable" 2`] = `
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ const objects = {};
|
|||||||
const prefix = 'r';
|
const prefix = 'r';
|
||||||
let uniqueID = 1;
|
let uniqueID = 1;
|
||||||
|
|
||||||
const createKey = (id) => `${prefix}${id}`;
|
const createKey = (id) => `${prefix}-${id}`;
|
||||||
|
|
||||||
class ReactNativePropRegistry {
|
class ReactNativePropRegistry {
|
||||||
static register(object: Object): number {
|
static register(object: Object): number {
|
||||||
let id = ++uniqueID;
|
let id = uniqueID++;
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
Object.freeze(object);
|
Object.freeze(object);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user