Skip to content

Commit

Permalink
[change] Use classic CSS in View, Text, etc., implementations
Browse files Browse the repository at this point in the history
The CSS base styles for certain primitives are implemented using classic CSS to
reduce browser layout times and better support 'null' values in
StyleSheet-defined styles. Combined with the previous patch this reduces the
benchmark layout times by about 30%.

Ref #1136
Fix #1044
Fix #1223
Fix #13
  • Loading branch information
necolas committed Mar 8, 2019
1 parent cea7ed0 commit 0e7c5bc
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,18 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
@media all {
[stylesheet-group=\\"0.1\\"]{}
:focus:not([data-focusvisible-polyfill]){outline: none;}
}
@media all {
[stylesheet-group=\\"1\\"]{}
.css-reset-4rbku5 { background-color: rgba(0,0,0,0.00); color: inherit; font: inherit; list-style: none; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: inherit; text-decoration: none; }
.css-cursor-18t94o4 { cursor: pointer; }
.css-view-1dbjc4n { -ms-flex-align: stretch; -ms-flex-direction: column; -ms-flex-negative: 0; -ms-flex-preferred-size: auto; -webkit-align-items: stretch; -webkit-box-align: stretch; -webkit-box-direction: normal; -webkit-box-orient: vertical; -webkit-flex-basis: auto; -webkit-flex-direction: column; -webkit-flex-shrink: 0; align-items: stretch; border: 0 solid black; box-sizing: border-box; display: -webkit-box;display: -moz-box;display: -ms-flexbox;display: -webkit-flex;display: flex; flex-basis: auto; flex-direction: column; flex-shrink: 0; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-height: 0px; min-width: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; position: relative; z-index: 0; }
.css-hitSlop-mjp8i1 { bottom: 0px; left: 0px; position: absolute; right: 0px; top: 0px; z-index: -1; }
.css-accessibilityImage-9pa8cd { bottom: 0px; height: 100%; left: 0px; opacity: 0; position: absolute; right: 0px; top: 0px; width: 100%; z-index: -1; }
.css-text-76zvg2 { border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; box-sizing: border-box; color: rgba(0,0,0,1.00); display: inline; font: 14px system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; white-space: pre-wrap; word-wrap: break-word; }
.css-textHasAncestor-16my406 { color: inherit; font: inherit; white-space: inherit; }
.css-textOneLine-bfa6kz { max-width: 100%; overflow-x: hidden; overflow-y: hidden; text-overflow: ellipsis; white-space: nowrap; }
.css-textMultiLine-cens5h { -webkit-box-orient: vertical; display: -webkit-box; max-width: 100%; overflow-x: hidden; overflow-y: hidden; text-overflow: ellipsis; }
.css-textinput-1cwyjr8 { -moz-appearance: textfield; -webkit-appearance: none; background-color: rgba(0,0,0,0.00); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; border-top-left-radius: 0px; border-top-right-radius: 0px; border: 0 solid black; box-sizing: border-box; font: 14px system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; resize: none; }
}</style>"
`;
15 changes: 13 additions & 2 deletions packages/react-native-web/src/exports/Image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import applyNativeMethods from '../../modules/applyNativeMethods';
import createElement from '../createElement';
import css from '../StyleSheet/css';
import { getAssetByID } from '../../modules/AssetRegistry';
import resolveShadowValue from '../StyleSheet/resolveShadowValue';
import ImageLoader from '../../modules/ImageLoader';
Expand Down Expand Up @@ -254,10 +255,10 @@ class Image extends Component<*, State> {
const hiddenImage = displayImageUri
? createElement('img', {
alt: accessibilityLabel || '',
className: classes.accessibilityImage,
draggable: draggable || false,
ref: this._setImageRef,
src: displayImageUri,
style: styles.accessibilityImage
src: displayImageUri
})
: null;

Expand Down Expand Up @@ -387,6 +388,16 @@ class Image extends Component<*, State> {
}
}

const classes = css.create({
accessibilityImage: {
...StyleSheet.absoluteFillObject,
height: '100%',
opacity: 0,
width: '100%',
zIndex: -1
}
});

const styles = StyleSheet.create({
root: {
flexBasis: 'auto',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,7 @@ StyleSheetValidation.addValidStylePropTypes({
objectFit: oneOf(['fill', 'contain', 'cover', 'none', 'scale-down']),
objectPosition: string,
pointerEvents: string,
tableLayout: string,
/* @private */
MozAppearance: string,
WebkitAppearance: string
tableLayout: string
});

export default StyleSheetValidation;
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`StyleSheet/createReactDOMStyle fontFamily "Noto, BlinkMacSystemFont" 1`] = `
Object {
"fontFamily": "Noto, BlinkMacSystemFont",
}
`;

exports[`StyleSheet/createReactDOMStyle fontFamily "Noto, System" 1`] = `
Object {
"fontFamily": "Noto, system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
}
`;

exports[`StyleSheet/createReactDOMStyle fontFamily "Noto, System" 2`] = `
Object {
"font": "14px Noto, system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
}
`;

exports[`StyleSheet/createReactDOMStyle fontFamily "System" 1`] = `
Object {
"fontFamily": "system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
}
`;

exports[`StyleSheet/createReactDOMStyle fontFamily "System" 2`] = `
Object {
"font": "14px system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
}
`;

exports[`StyleSheet/createReactDOMStyle fontFamily "monospace" 1`] = `
Object {
"fontFamily": "monospace, monospace",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,62 +39,33 @@ describe('StyleSheet/createReactDOMStyle', () => {
expect(createReactDOMStyle(style)).toMatchSnapshot();
});

describe('borderWidth styles', () => {
test('defaults to 0 when "null"', () => {
expect(createReactDOMStyle({ borderWidth: null })).toEqual({
borderTopWidth: '0px',
borderRightWidth: '0px',
borderBottomWidth: '0px',
borderLeftWidth: '0px'
});
expect(createReactDOMStyle({ borderWidth: 2, borderRightWidth: null })).toEqual({
borderTopWidth: '2px',
borderRightWidth: '0px',
borderBottomWidth: '2px',
borderLeftWidth: '2px'
});
});
});

describe('flexbox styles', () => {
test('flex defaults', () => {
expect(createReactDOMStyle({ display: 'flex' })).toEqual({
display: 'flex',
flexShrink: 0,
flexBasis: 'auto'
});
});

test('flex: -1', () => {
expect(createReactDOMStyle({ display: 'flex', flex: -1 })).toEqual({
display: 'flex',
expect(createReactDOMStyle({ flex: -1 })).toEqual({
flexBasis: 'auto',
flexGrow: 0,
flexShrink: 1,
flexBasis: 'auto'
flexShrink: 1
});
});

test('flex: 0', () => {
expect(createReactDOMStyle({ display: 'flex', flex: 0 })).toEqual({
display: 'flex',
expect(createReactDOMStyle({ flex: 0 })).toEqual({
flexGrow: 0,
flexShrink: 0,
flexBasis: '0%'
});
});

test('flex: 1', () => {
expect(createReactDOMStyle({ display: 'flex', flex: 1 })).toEqual({
display: 'flex',
expect(createReactDOMStyle({ flex: 1 })).toEqual({
flexGrow: 1,
flexShrink: 1,
flexBasis: '0%'
});
});

test('flex: 10', () => {
expect(createReactDOMStyle({ display: 'flex', flex: 10 })).toEqual({
display: 'flex',
expect(createReactDOMStyle({ flex: 10 })).toEqual({
flexGrow: 10,
flexShrink: 1,
flexBasis: '0%'
Expand All @@ -103,15 +74,12 @@ describe('StyleSheet/createReactDOMStyle', () => {

test('flexBasis overrides', () => {
// is flex-basis applied?
expect(createReactDOMStyle({ display: 'flex', flexBasis: '25%' })).toEqual({
display: 'flex',
flexShrink: 0,
expect(createReactDOMStyle({ flexBasis: '25%' })).toEqual({
flexBasis: '25%'
});

// can flex-basis override the 'flex' expansion?
expect(createReactDOMStyle({ display: 'flex', flex: 1, flexBasis: '25%' })).toEqual({
display: 'flex',
expect(createReactDOMStyle({ flex: 1, flexBasis: '25%' })).toEqual({
flexGrow: 1,
flexShrink: 1,
flexBasis: '25%'
Expand All @@ -120,15 +88,12 @@ describe('StyleSheet/createReactDOMStyle', () => {

test('flexShrink overrides', () => {
// is flex-shrink applied?
expect(createReactDOMStyle({ display: 'flex', flexShrink: 1 })).toEqual({
display: 'flex',
flexShrink: 1,
flexBasis: 'auto'
expect(createReactDOMStyle({ flexShrink: 1 })).toEqual({
flexShrink: 1
});

// can flex-shrink override the 'flex' expansion?
expect(createReactDOMStyle({ display: 'flex', flex: 1, flexShrink: 2 })).toEqual({
display: 'flex',
expect(createReactDOMStyle({ flex: 1, flexShrink: 2 })).toEqual({
flexGrow: 1,
flexShrink: 2,
flexBasis: '0%'
Expand All @@ -147,10 +112,16 @@ describe('StyleSheet/createReactDOMStyle', () => {

test('"System"', () => {
expect(createReactDOMStyle({ fontFamily: 'System' })).toMatchSnapshot();
expect(createReactDOMStyle({ font: '14px System' })).toMatchSnapshot();
});

test('"Noto, System"', () => {
expect(createReactDOMStyle({ fontFamily: 'Noto, System' })).toMatchSnapshot();
expect(createReactDOMStyle({ font: '14px Noto, System' })).toMatchSnapshot();
});

test('"Noto, BlinkMacSystemFont"', () => {
expect(createReactDOMStyle({ fontFamily: 'Noto, BlinkMacSystemFont' })).toMatchSnapshot();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,6 @@ const styleShortFormProperties = {
writingDirection: ['direction']
};

const borderWidthProps = {
borderWidth: true,
borderTopWidth: true,
borderRightWidth: true,
borderBottomWidth: true,
borderLeftWidth: true
};

const monospaceFontStack = 'monospace, monospace';
const systemFontStack =
'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif';
Expand Down Expand Up @@ -96,13 +88,7 @@ const createReactDOMStyle = style => {
Object.keys(style)
.sort()
.forEach(prop => {
let value = normalizeValueWithProperty(style[prop], prop);

// Make sure the default border width is explicitly set to '0' to avoid
// falling back to any unwanted user-agent styles.
if (borderWidthProps[prop]) {
value = value == null ? normalizeValueWithProperty(0) : value;
}
const value = normalizeValueWithProperty(style[prop], prop);

// Ignore everything else with a null value
if (value == null) {
Expand All @@ -129,21 +115,6 @@ const createReactDOMStyle = style => {
break;
}

case 'display': {
resolvedStyle.display = value;
// A flex container in React Native has these defaults which should be
// set only if there is no otherwise supplied flex style.
if (style.display === 'flex' && style.flex == null) {
if (style.flexShrink == null) {
resolvedStyle.flexShrink = 0;
}
if (style.flexBasis == null) {
resolvedStyle.flexBasis = 'auto';
}
}
break;
}

// The 'flex' property value in React Native must be a positive integer,
// 0, or -1.
case 'flex': {
Expand Down
51 changes: 51 additions & 0 deletions packages/react-native-web/src/exports/StyleSheet/css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2016-present, Nicolas Gallagher.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @noflow
*/

import { classic } from './compile';
import styleResolver from './styleResolver';
import { STYLE_GROUPS } from './constants';

/**
* A simple (and dangerous) CSS system.
* The order of CSS rule insertion is not guaranteed.
* Avoiding combining 2 or more classes that modify the same property.
*/
const css = {
/**
* const classes = css.create({ base: {}, extra: {} })
*/
create(rules) {
const result = {};
Object.keys(rules).forEach(name => {
const style = rules[name];
const compiled = classic(style, name);

Object.values(compiled).forEach(({ identifier, rules }) => {
rules.forEach(rule => {
styleResolver.sheet.insert(rule, STYLE_GROUPS.classic);
});
result[name] = identifier;
});
});
return result;
},
/**
* css.combine(classes.base, classes.extra)
*/
combine(...args) {
return args.reduce((className, value) => {
if (value) {
className += className.length > 0 ? ' ' + value : value;
}
return className;
}, '');
}
};

export default css;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`components/Text prop "onPress" 1`] = `
<div
className="rn-borderWidth-1yadl64 rn-boxSizing-deolkf rn-color-homxoj rn-cursor-1loqt21 rn-display-1471scf rn-fontFamily-1qd0xha rn-fontSize-1b43r93 rn-fontStyle-o11vmf rn-fontVariant-1kfwfc5 rn-fontWeight-gul640 rn-lineHeight-t9a87b rn-margin-crgep1 rn-padding-t60dpp rn-textDecorationLine-13wfysu rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
className="css-text-76zvg2 rn-cursor-1loqt21"
data-focusable={true}
dir="auto"
onClick={[Function]}
Expand All @@ -13,14 +13,14 @@ exports[`components/Text prop "onPress" 1`] = `

exports[`components/Text prop "selectable" 1`] = `
<div
className="rn-borderWidth-1yadl64 rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-fontFamily-1qd0xha rn-fontSize-1b43r93 rn-fontStyle-o11vmf rn-fontVariant-1kfwfc5 rn-fontWeight-gul640 rn-lineHeight-t9a87b rn-margin-crgep1 rn-padding-t60dpp rn-textDecorationLine-13wfysu rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
className="css-text-76zvg2"
dir="auto"
/>
`;

exports[`components/Text prop "selectable" 2`] = `
<div
className="rn-borderWidth-1yadl64 rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-fontFamily-1qd0xha rn-fontSize-1b43r93 rn-fontStyle-o11vmf rn-fontVariant-1kfwfc5 rn-fontWeight-gul640 rn-lineHeight-t9a87b rn-margin-crgep1 rn-padding-t60dpp rn-textDecorationLine-13wfysu rn-userSelect-lrvibr rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
className="css-text-76zvg2 rn-userSelect-lrvibr"
dir="auto"
/>
`;

0 comments on commit 0e7c5bc

Please sign in to comment.