What is Tech Debt and How Can You Solve for It?
Full-Stack WebTech debt (or technical debt) is a concept in software development where there is a build-up of refactoring work necessary in the future because...
React Native apps are native apps. It’s a heck of a coup they’ve pulled off, and while I have my concerns around adopting the technology, “Is it native?” isn’t one of them.
I suspect whether you agree with me hinges on what we each understand by “native”. Here’s what I have in mind:
Overall: Capable of achieving the same ends as any app developed using the platform’s preferred tooling by fundamentally the same mechanisms.
I claim React Native meets that bar.
I’ve spent most of my years as a professional programmer working on Mac & iOS apps. From my Apple-native point of view, React Native is a very elaborate way to marshal UIViews and other UIKit mechanisms towards the usual UIKit ends:
Well, about that one more language. Let’s talk about animation jank and asynchrony.
What is “jank”? It’s jargon for what happens when it’s time for something to show up on screen, but your app can’t render the needed pixels fast enough to show that something. As Shawn Maust put it back in 2015 in “What the Jank?”:
“Jank” is any stuttering or choppiness that a user experiences when there is
motion on the screen—like during scrolling, transitions, or animations.
The difference in language drives to something that may seem less than native at first glance. You see, there’s a context switch between UIKit-land and React Native JavaScript-action-handler-land, and at a high enough call rate – like, say, animation handlers that are supposed to run at the frame rate – the time taken in data marshaling and context switching can become noticeable.
Native apps aren’t immune from animation jank. It feels like there’s a WWDC session or three every year on how not to stutter when you scroll. But the overhead inherent in the technical mechanism eats some of your time budget, which means you get to sweep less inefficiency in your app code under Moore’s rug.
Native apps also aren’t immune from blocking rendering entirely. Do a bulk-import into Core Data on the main thread, parse a sufficiently large (or malicious) XML or JSON document on the main thread, or run a whole network request on the main thread, and the system watchdog will kill your app while leaving behind a death note of “8badf00d”. React Native’s context switch automatically enforces the best practice of doing work off the main thread: React Native developers naturally fall into the “pit of success” when it comes to aggressively pushing work off the main thread.
How do you deal with the time taken by a function call? You do less work, or you do work on the other side of the bridge.
Or you surface that gap, that asynchrony, in your programming model with:
Apple’s frameworks are rife with these mechanisms. Your standard IBAction-to-URLSession-to-spinner-to-view-update flow has a slow as a dog HTTP call in the middle. React Native’s IBAction-to-JSCore-to-view-update flow has a tiny little RPC bridge in the middle that often runs fast enough that you can pretend it’s synchronous. By the end of 2018, you may not even have to pretend – React Native will directly support synchronous cross-language calls where that’s advantageous.
React Native apps with their action handlers in JavaScript are no less native than an iOS app with their action handlers on a server on the other side of an HTTP API.
If you’ve worked on the common “all the brains are in our serverside API” flavor of iOS app, this should sound familiar. It should sound doubly familiar if that serverside API happens to be implemented in Node.js.
And, indeed, running the same language both serverside and clientside makes it a lot easier to change up which side of the pipe an operation happens on. (Such are the joys of isomorphic code, and it’s a small reason some are excited about Swift on the Server.)
React Native uses the same underlying mechanisms and benefits as much from Apple’s work on UIKit as does any other iOS app. React Native apps are native – perhaps even more native than many “iOS app as Web API frontend” apps!
Tech debt (or technical debt) is a concept in software development where there is a build-up of refactoring work necessary in the future because...
Rails 5.1 includes Webpacker, a build pipeline that allows using the latest and greatest JavaScript language features and frameworks, as well as system tests,...
Test automation and continous integration can streamline your workflow processes. Thankfully, cloud and SaaS solutions have turned a bare metal headache into a configuration...