Getting cozy with WebViews
The browser engines as well as the hardware components in smart phones have dramatically improved in the last decade. The web platform has also standardized many APIs required for mobile development. Network bandwidths have had a major uptick. Just like electron in the last 5 years has become the standard way for developing desktop apps, the time is ripe for web technologies to put the strong foot forward in mobile app development.
Web Views are out of fashion #
WebViews were vogue in the early days of mobile development. The original iPhone had support for pinning websites on the home page and that was the only way to add applications to the device. There was no App Store and no native development. By 2009, every one was building a mobile version of their website optimized for smaller screen sizes. PhoneGap was a new and promising technology that could easy mobile development by helping us write once and use multiple times - the same software could run on the iPhone, Android and the upcoming Windows phones. Even in the App Store, many apps were wrappers over the website placed to get an entry in the search results. All that ended once the music stopped. Most major applications moved off webviews during 2011-2012 because of a variety of reasons:
- The web platform was not mobile ready - Internet Explorer was the most used browser with over 70% market share in 2009. It was the peak era of JQuery where JavaScript was mostly used to patch up some animations on the rendered content. There were multiple issues with web development for mobile:
- Web was a document delivery platform and even things like vertical centering required extensive hacks.
- There was no web app and most websites were rendered on the server and the building blocks of web apps - JSON support, Flexbox, media queries were absent in the most browsers.
- There were too many mobile platforms Blackberry, Symbian and Windows Mobile still existed. While the native app developers were happy to optimize for the specific platform, web apps were sold to the executive team as the solution that was cross platform. Therefore, they had to support the most incapable platforms in the website and the quality suffered.
- Mobile was rapidly evolving There were significant changes taking place with every passing year. From the release of the iPad to Retina displays, while the native developers got tools for each and every change, web developers who needed to support older devices were stuck with the minimum common set and the platform itself took time to catch up.
- Web carried a lot of baggage Most apps were fresh code bases written from scratch to support a new platform. Many web apps were patches over existing 5 year old projects written for IE6 support. The re-engineering and removal of defunct use cases made native apps thinner and lighter.
- Tooling was not there Remember Firebug. That was a huge luxury to have. Without it, developers resorted to alert based debugging where a modal dialog was launched just to print a string, especially on the Android Browser(no chrome on Android back then). Many web developers used notepad and did not have a compiler, linter or a code formatter. Selenium was in its infancy and mostly a hack injecting scripts to provide a testing environment on the desktop.
- The big churn The web community was going through the biggest churn in code and practices. Flash -> JQuery -> Backbone -> Angular -> React all in a span of a few years. Browser wars 2.0 was in full rage and there were new features out every month that made old web development practices defunct.
- Web got bad press Mobile surprised a lot of giant technology companies and they were unprepared. Facebook put the blame on web technology. That too just before their hugely anticipated IPO. It became extremely difficult to defend web once one of the biggest technology companies publicly shames the platform in general media.
- Design practices were evolving Mobile was new and the best practices on mobile were still evolving. Here is an image of New York times from the blackberry days. 50% of the screen space was the header and the footer. That too on a smaller screen that we had back then. Shrinking the desktop design on mobile we know now was not the best solution. Even though web might have been easier to experiment with new designs, native apps mostly got the new designs first simply because web was the last resort for the extreme edge cases - no one wanted to risk the users who expected the desktop functionality on mobile.
You might have realized almost all of those concerns are not there any more. The core features required for mobile development have been stable in the web browsers for years and even the oldest browsers in use support most of the essentials. There are just two mobile platforms left and even they have been converging. People are holding onto their phones longer and most apps do not need to support all of the new features. Supporting the iPhone X notch is not the retina level effort. Most apps are more than 5 years old and carry similar baggage as the web. With ES6, many web apps are getting a reboot. Tooling on the web has left native far behind. The web platform has stabilized. Array.includes
is not a huge change in comparison to class
statement and we still get the same buzz because there is not much new to cheer about. Native has had its own share of churns - ObjC to Swift, the removal of 32 bit apps, of OpenGL and the migration from eclipse to android studio. There has been radical unification of design. Most apps look the same on Android and iOS. The differences like menu placement are minor. Many apps have started building their own conventions that are cross platform and many developers instead of building platform only features have been busy ensuring the design remains consistent.
Web has quietly surpassed mobile #
For building a regular application on mobile the web platform provides better features today than native code ever did:
- Live Reload Web stack is much easier to develop due to live reload. Change something and see it live. Add it the fact that you can debug mostly on the desktop browser and things work fine on mobile. Native never had the luxury in the past and may never have it in the future.
- Layouting CSS Grid and Flexbox are much more expressive and powerful than auto layouting ever was. As an added advantage there is no interface builder where you cannot do diff across checkins or merge changes across commits.
- Hot patches Web as a platform has been built online first and adding offline capabilities have been added later. Adding online capabilities and network conditions is many times more difficult than adding offline caching. Minor fixes do not need a huge cycle of submitting an app again for review and watching it slowly being adopted. If built right the web based app can be updated almost instantly for most users.
- Testing and CI/CD Testing web based code is many times easier than testing native apps. Tests can run extremely fast with the command line and on the automation machines. That makes them extremely easy to use. Setting up a build machine for automating native apps is so much effort that many teams decide to skip it altogether.
- Features With WebGL we can build apps with full cross platform GPU support in the web platform. With WebAssembly and WebWorkers, CPU intensive computations are all safe and simple. With IndexDB we have a fully managed database. Cryptographic methods are available natively in all browsers. Even more arcane APIs like orientation, camera, proximity, accelerometer, gyroscope, page visibility, and Bluetooth are either built in or getting ready. There are little reasons for a WebView based application to have a single call that requires special native code. Even if we need one, we now have mature APIs to expose native objects asynchronously in JavaScript without resorting to hacks like URL redirections.
- Code sharing This is deliberately been put as the last item. Web based apps can share some code between multiple platforms and even with the server and the website. This can turn into a huge limitation if we developers go overboard with supporting everything.
Ideal apps for WebViews #
Web Views are not perfect for all app types. If you are building the Facebook app with 18000 classes even native might not be good enough. But there is a huge class of applications where Web based views are the best choices. If your app fits in these categories definitely go for web views:
- The app needs a network Interactions over the internet are the biggest strength of the web. Nothing is more optimized, and can provide a more robust set of network communication tools and APIs than a web view.
- There is no extensive need for cutting edge native APIs If your app needs AR Kit or CoreML then a web view might not be the best choice. You might be able to place the general browsing and settings pages in the web view but if you have a native renderer, putting a webview may not be worth the effort. One or two views being native is all right as Web Views will save tremendous effort in debugging the interactions outside of those views.
- Everything can be built in the website If your website is fully featured, you can build a web based app with all the features and it can be much better than the website by fine tuning for the device the app targets.
- The app is UI/Data based rather than CPU based If your app is not the one that needs to convert an iPhone into a room heater, the performance overhead of an interpreted language might be worth it. It makes UI development and experimentation with interactions and user interface easier. Web provides the best interaction
Tuning WebViews for native like performance #
Most of the developer knowledge as well as the best advice is tuned to web development where downloading the resource from the internet is the biggest bottleneck and every other consideration for performance is second fiddle. This changes in the world of WebViews where most of the HTML is bundled and there are very different things we need to cater to. Here are some things to consider to get native like performance in WebViews:
- Target a single user WebView based apps unlike websites target the same user, who logs in for the lifetime of the application. The cookies are not deleted. The requests are not blocked and multi-user considerations are simply not present. There are no cross-site security issues. Therefore, the key to great performance is caching. There is simply no need to download anything again. Stashing everything in the indexDB is the right idea. Just like native apps the focus should be on offline user experience and the server updates should be done whenever network is available and in the background. Progressive Web Apps with a service workers can be used if you need remote update capabilities. But starting with that may not be a great idea. Start with some bundled HTML to figure out what needs to be done to get the app perfect. Service worker should come later. Most apps update through the app store.
- Take note of the parse times Web apps are optimized to minimize the package size. This is not the most important thing in a native app. The source code is on the disk. Therefore there is a no point in bundling JavaScript into a single file, especially if it forces the browser to parse code that does not need to execute. The JS bloat is the only reason WebView apps appear slow. But it does not have to be that way. Having 1000 files optimally split is not even a problem on web any more. Most users are on HTTP/2. But on native, bundling them in a huge JS file will ruin everything. In a native app written in a different language, no CPU cycles are wasted on views that need not be shown. Same should be the case with web. Handsomely use prefetch, preload and prerender tags in a WebView app. We are not wasting bandwidth just opportunistically parsing some image, CSS and JS files. The costs on battery are very low and the experience benefits immense.
- Identify the strengths There are no browser plugins in a web view. No Javascript disabled mode. No worries about the web font not loading. All the extra effort needed to support these use cases and testing scenarios is not required. Instead all focus should be on the performance. Cache the rendered HTML on disk to prevent having to generate it again. Have a good state management library.
- Use the right tools HTML rendering is highly optimized and the browser takes extreme care not to waste cycles rendering stuff that is not needed. But still the DOM is extremely expensive. To get native like performance, we need to take some cues from the native code. Picking an virtual scroll library is essential if we need a scroll list. Animations in JavaScript until Web Animations becomes available is not a great idea. Images should be optimized to the view they will show up in. The need for the browser to relayout should be prevented with things like size attributes in images and preloading of the content.
- Do not go overboard While many native app teams are happy going with a simpler design, as soon as the web technology is brought into the picture more customizations are needed. Not many apps ship with custom fonts but almost all webviews based ones are forced to adopt one. Similarly developers want to share code as much as possible. These goals deter the focus from quality. As long as web based apps target the lowest common denominator, they will remain far behind native code. The webview app should not be sharing code with the website to begin with. First get the best app out and then focus on sharing. The app can act as a forerunner to the website meant to replace it when the lowest browser supports everything it needs. There will still be avenues to share code. And even if there is none shared, there was nothing shared in the native world as well so we are not worse off.
- Realize the limitations Some screens are not ideal to be WebViews. For example, if your application’s core is something that depends on realtime updates from the Photo gallery, Phonebook or the camera, you can hook up Cordova or pass messages but it might be better to just use native code for those views. This does not mean the app cannot be a webview app. The photo view or the phonebook view can be a native view that calls back to the core webview when done. That way the core logic can still reside in the WebView and be cross platform while the platform specific performance sensitive pieces could reside in native code.
- Use the right defaults Almost all apps are on retina devices, wide gamut support is present by default almost everywhere. If building webview based apps start support the highest device feature set. Adding backwards compatibility is easy(especially with Babel and PostCSS) and we never know if we will support the older device by the time we get to a release. optimize for a feature that’s new in a new device. Users paid handsomely for the new handset and they expect the apps to appear much better on the new device. Developers need to respect those wishes with the web views just like they do with native code.
Just like native apps are engineered, web apps that are used natively need to be engineered. Web is extremely easy. Easy never means we don’t need to learn. If the best practices are not followed no platform or programming language can save someone from making a horrible and extremely slow app.
Raw WebViews vs Cordova vs React Native #
Raw WebViews are good for most of the workflows, especially if there is a team of native app developers who are building the hybrid part of the application. They allow native developers to feel at home while the web developers can fully implement most of the cross platform logic. The boilerplate has been reducing over time and with most requirements never requiring native code, the reasons not putting in a webview are diminishing at a great speed.
Cordova makes it faster but it comes with a lot of baggage of historical decisions that are not relevant in the modern world. Cordova is like JQuery, it makes job easier, works around platform specific bugs and significantly speeds up the process to get up and running. But in the modern OSes, it is not essential. If we are new to the platform we can use it to get started. But most of its functionality is natively available. At some point you can replace you entire framework dependency with a ployfill that is implemented over a web view. Cordova is perfect if you do not want to maintain a build system as Phonegap build can save you the cost of buying a Mac.
React Native is an interesting experiment. It started with the concept of using Native Controls directed by JavaScript but over time with things like React Navigation, the community has gravitated away from using true native controls to custom views. There are two big advantages of react native - out of box platform specific UI and the ability to write a custom native control surrounded by regular controls. Its API surface is very small in comparison to the web platform and new features like CSS Grids may not ever land up in the platform. WebViews also have native controls although things like switches have not yet been implemented. React native is a good idea if you are in terms with the limitations of the platform and need a custom control so tightly integrated with the JavaScript views that WebViews are prohibitive. Otherwise, WebViews with react would be easier to develop over and use with comparable performance for most use cases.
Conclusion #
There was an era when programmers using compiled languages over assembly were lesser beings. This was until the compiled languages took over the desktop. Then came a time when developers distinguished between compiled and interpreted languages. Interpreted and dynamic languages took over research and server side development. Then came an era when sand-boxed web development was marked as nothing in comparison to the real “native” stuff. Web applications are getting as powerful as native desktop applications and the difference will soon be indistinguishable. We still need to write assembly for really low level, extremely performance sensitive stuff but even those strong proponents of their real native skills never go down to assembly. We are entering the golden age of developing mobile apps using web technologies. Web Technologies are the present of application development. WebViews are a great way to make them go native.
Comments
Post a new comment
We get avatars from Gravatar. You can use emojis as per the Emoji cheat sheet.