Skip to content

Instantly share code, notes, and snippets.

@arnoldc
Last active March 9, 2023 17:12
Show Gist options
  • Select an option

  • Save arnoldc/5f4532f6aa010878c0af8d8f19749de8 to your computer and use it in GitHub Desktop.

Select an option

Save arnoldc/5f4532f6aa010878c0af8d8f19749de8 to your computer and use it in GitHub Desktop.
[React Native] Optimizations Tips
// 1. Synchronization of input text when typing too fast
/*
One of the solutions for the synchronization problem is to remove the
value prop from TextInput entirely.
*/
const PizzaTranslator = () => {
const [value, setValue] = useState("");
const onChangeText = (text) => {
setValue(text);
};
return (
<View style={styles.container}>
<TextInput
accessibilityLabel="Text input field"
placeholder="Type here to translate!"
onChangeText={onChangeText}
defaultValue={value}
style={styles.textInput}
// we remove the value prop here
/>
<Text style={styles.label}>
{value
.split(" ")
.map((word) => word && "🍕")
.join(" ")}
</Text>
</View>
);
};
// 2. Always use a specialized component
// example 1: Using ScrollView + View instead of Flatlist
// note: FlatList uses ScrollView and View components
// example 2: Using Flashlist
// https://shopify.github.io/flash-list/
// 3. Choosing correct libraries
// example 1: Use a bundle size of the app
// https://github.com/IjzerenHein/react-native-bundle-visualizer
// can get the details of any added library in the bundle; hence deciding if it’s worth keeping or removing that library.
// Be more selective and use smaller specialized libraries.
// example 2: Using momentjs instead of day.js
// MomentJS 67.9 KB and DayJS 2.5 KB
// example 3: import smaller libray
// import { map } from 'lodash'; => instead of this
// import map from 'lodash/map'; => use this
// NOTE: use the import-cost in vscode extension to see realtime the size of the library
// 3. Use libraries that is optimized for mobile platform not web!
// example 1: Using react-native-webview instead of react-webview
// example 2: Using react-native-svg instead of react-svg
// example 3: Using '@react-native-firebase/database instead of '@firebase/database'
// 4. Use Stylesheet API to pass styles
/*
The easiest way to style a component is to pass it an object with styles.
While it works, you will not see it happening too much. It is generally
considered an anti-pattern, unless you’re dealing with dynamic values,
such as changing the style of the component based on the state.
*/
const App = () => {
return (
<View style={styles.container}>
<View style={styles.box} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
},
box: {
backgroundColor: "coral",
width: 200,
height: 200,
},
});
// 5. Validate and check the types ahead of time when building a native module
// example 1:
import { NativeModules } from "react-native";
const { ToastExample } = NativeModules;
export const show = (message, duration) => {
ToastExample.show(message, duration);
};
// to this
import { NativeModules } from "react-native";
const { ToastExample } = NativeModules;
export const show = (message, duration) => {
if (typeof message !== "string" || message.length > 100) {
throw new Error("Invalid Toast content");
}
if (!Number.isInteger(duration) || duration > 20000) {
throw new Error("Invalid Toast duration");
}
ToastExample.show(message, duration);
};
/*
Why:every time there’s a rendering happening – just like you execute
your native method with the JavaScript arguments.
*/
// 6. use the `useNativeDriver` for animations
// example 1
const fadeAnim = useRef(new Animated.Value(0)).current;
const fadeIn = () => {
Animated.timing(fadeAnim, {
toValue: 1,
duration: 1000,
useNativeDriver: true, // enables native driver
}).start();
};
// [...]
<Animated.View style={{ opacity: fadeAnim }} />;
// 7. Use great library for animations
// react-native-gesture-handler
// reanimated-bottom-sheet
// rive instead of lottie-react-native?? (debateable?)
// https://twitter.com/guidorosso/status/1579607142382055425
// 8. Enable Hermes
// example 1: Android
/*
project.ext.react = [
entryFile: "index.js",
enableHermes: true
]
*/
// example 2: iOS
/*
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and
then install pods
:hermes_enabled => true
)
*/
// 9 Use Proguard (Android)
// Why: https://segment.com/blog/mobile-app-size-effect-on-downloads/
// example 1:
// in android/app/build.gradle
// def enableProguardInReleaseBuilds = true
// 10. Test religiously
// Testing Pyramid
// 1. Web driver test (end-to-end)
// 2. Unit test (jest, mocaha, chai, enzyme)
// snapshot test
// react-native-testing-library
// 3. Static analysis (eslint, flow, typescript)
// 11. Use a profiler
// https://github.com/shopify/react-native-performance
// https://github.com/callstack/reassure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment