The POH Performance app is a series of aviation-related apps built around a common infrastructure. This is a brief history of the infrastructure.
The Gen 0 app was a spreadsheet for G36 Bonanza performance. It looked up performance data in the G36 tables entered in different worksheets and was ported to the spreadsheet app on Palm Pilot.
When the original iPhone came out, the only app development platform was building WebaApps. Mobile Safari had sufficient support of the Application Cache to enable running while disconnected, A key capability for an aircraft performance app.
The initial WebApp consisted of a lot of static HTML with Javascript to get results directly from the DOM nodes, do the computations, and insert the results directly into the DOM nodes.
The architecture had many deficiencies. It was difficult to support consistent mirroring and formatting of input and output values on multiple pages and the HTML and JavaScript were tightly tied together.
The Gen 2 app (major versions 2 through 4) was completely re-architected. Several public-domain frameworks were evaluated, but none seemed mature at the time, though Angular was very interesting. In the end, a custom Model, View, and Controller (MVC) framework inspired by Angular was designed.
innerHTML. The DOM tree was mostly static. Dynamism was accomplished through three mechanisms.This was a simple and flexible infrastructure. Its main problems were:
The next generation of infrastructure has several goals:
The Gen 2 app built a WebComponent-style tree that captures the view semantics with high-level components like Page or Group (a Card). This worked well, and a similar approach seemed desirable. React was the obvious choice. Potentially, React would allow the importation of third-party components. React did not have anything like State Variables, but that could be added. JSX seemed like a better, more familiar replacement for specifying the templates as objects. The following additional frameworks were briefly considered:
Taking advantage of the React ecosystem entails buying into the whole Babel and Webpack infrastructure. Using third-party components can cause an uncontrollable number of dependent libraries to load. Using Babel, Webpack, and JSX causes a divergence between the source seen by the programmer and the code executed by the browser. Sourcemaps make up this difference 90% of the time, but it breaks debugging 10% of the time, and you are left debugging with console logging.
The nature of POH Performance applications is such that the packing, tree shaking, and minifying that Webpack does is not as valuable as it might be with normal apps. On mobile devices where the bandwidth might be constrained, all the source files are kept locally in native apps by the Cordova infrastructure. On desktop computers that use the WebApp, the bandwidth is usually quite good and loading time is minimal, and once loaded, the source files are kept locally by the application cache or Service Workers. Lastly, the code for the application itself is usually dwarfed by the airport and runway database, so minifying and packing the application code has little advantage.
Using Babel would have been very useful when ES6 support was rare in browsers. However, it’s been well over five years since browsers started supporting ES6. The information sent to the app’s backend server indicates that 99% of active users are running a browser or WebView that supports ES6. In short, Babel is no longer a huge advantage.
As the React documentation notes, it’s possible to simply use the React library without Webpack or transpiling. When you do that, you need to decide on an alternative to JSX. The most JSX-like alternative is to use template strings to transform JSX-like syntax into a component tree for React. An existing library, htm, does just that. While there are advantages to compiling and optimizing JSX before runtime, htm does a very good job at caching, parsing data, and reusing it when able. In addition, once you take a template string approach, it is easy to extend JSX syntax where desired by simple modifications to the htm library. For example, adding Angular-like “{{stateVarName}}” to insert state variable data.
The state variable infrastructure in Gen 2 apps ensures that the state is formatted uniformly, values are verified properly, and numeric data can be manipulated or viewed in different units (e.g., English or metric). This infrastructure was so useful that eliminating it for more distributed state management or libraries like Redux was not seriously considered. In addition, state variables were used to trigger Model computation and declare dependencies, which was also very useful.
React is a very flexible and general-purpose system. However, it does have quirks:
useState(). This is un-DOM-like and a bit stilted. Similarly, you need to use useRef() to operate on individual DOM tree nodes where required.onchange). However, this may also have an advantage in unifying cross-browser behavior, though this is less of an issue nowadays and since the demise of IE.A huge advantage of using React would be to import third-party Components. However, as noted above, doing so would entail using Webpack and Babel since components rely on them to gather dependencies and smooth over syntax beyond ES2015. Given that, you're forced to debug with Sourcemaps. Also, since many components rely on other components, you quickly lose control of application dependencies.
Lastly, React is not the easiest paradigm for people to learn. The web is full of questions about "How do you do this in React?"
An experiment was done to use React under state variables and an early version of tml. The conclusion was that this is quite doable, but it avoids most of the React advantages, since third-party components would need to be translated to the non-JSX, non-Webpack environment.
In the end, a rewrite of the Gen 2 system that took a lot of inspiration from React was chosen, as it seemed better to use state variables to uniformly trigger change in the Model and View and not fight to match this to React semantics. See the MVCS overview for a description. In any case, a future version could substitute React to implement the View or perhaps some of the new WebComponent frameworks.