There are a number of articles and discussion on the React Native vs Ionic debate. Sonny Lazuardi has a thoughtful post here that covers the pros/cons and has a visually informative Youtube video that shows the performance difference between React Native and Ionic. At Gorilla, we’re increasingly working with clients who want to build feature rich and technically challenging apps using these frameworks. As part of those engagements we’ve taken a deep dive into React Native and Ionic and thought we’d share what we’ve learned in a series of articles. In this series, we will cover the technical challenges of accessing streaming video, location services/iBeacon and compare the UI components offered by each framework. The first post in this series, Senior Gorilla Caro Aguilar talks Video Playback: Ionic vs React Native.
There are multiple approaches for video playback on iOS including AVPlayerViewController, AVPlayers with custom views, or even lower level implementations using AVAssetReader, AVSampleBufferDisplayLayer and AudioToolKit. For native apps, these options allow for easy out of the box implementations or completely custom players optimized for speed, but what about an app you would like to run on iOS and Android? Are there any cross-platform frameworks that allow for similar user experiences? I took a look at Ionic Framework and React Native as possible solutions.
The idea of writing code once to run on both iOS and Android is appealing, but my initial concern with frameworks like Ionic is the impact on user experience. Setting up the project was straightforward and implementation included the use of the video tag in html with the webkit-playsinline attribute to create a more native experience on iPhones (not the default fullscreen behavior).
User experience was decent under ideal network conditions, but the biggest limitation I encountered was around preloading videos. Setting the preload attribute to “auto” and adding <preference name=”AllowInlineMediaPlayback” value=”true” /> to the projects config.xml did not have any effect on preloading. This caused some very noticeable delays (anywhere from 3 – 15 seconds) when setting the device Network Link Conditioner to a slower network. Playing video and maintaining a good user experience is always tricky in low network conditions, but the ability of the native player to preload videos gives the player a better chance of being ready for playback. There was also about a 1 second delay between tapping the play button and the video playback beginning. This delay also blocks the main thread, so if a user tries to interact with the app during that time, interaction is blocked as well. Preloading issues aside, I was also interested to see how well Ionic handled multiple videos on a single page. The answer: not well. Consistently after playing 16 videos every subsequent video failed with error code MEDIA_ERR_DECODE.
This is not surprising considering there are AVPlayer limits when implemented natively, but the biggest limitation I found was the ability to remove players dynamically or recover from one of these failures.
Unlike Ionic, react native is not a write once and run anywhere framework, but is instead touted as a “learn once, write anywhere” framework. Another key difference is that is creates native counterparts to the components written in js (rather than web components running inside a web view). The video component is not included with the default set of React Native components, but I found one here https://github.com/brentvatne/react-native-video. Getting started with the Video component is easy and there is a nice sample project included with react-native-video. It didn’t take long to make it look like the app created using Ionic.
Looking closer at the react-native-video implementation, it uses the Video js component to create an AVPlayer on the iOS side and a MediaPlayer on Android. Pretty neat! Better yet, if the implementation of react-native-video does not suit your needs, you can create your own component for video playback and use lower level API’s to optimize performance even further. Since it is a native player, the limitations discovered in Ionic around preloading do not exist in this case. The player behaves exactly as if it were created in Swift or Objective-C, so in the case where I might need to instantiate many players I am able to manage them directly and remove old players that are no longer needed. Furthermore, playback was very smooth and there was no noticeable delay when switching between videos during playback.