Got conversion rate optimization questions? Wanna ask Neil Patel for help? Then join us for our weekly Crazy Egg Conversion Talks. Anyone can attend and ask as many questions as they’d like! Our first talk will be on May 5th, 2017 at 10 AM Pacific. Here are a few more details about the talks: Frequency: Weekly Duration: 1 Hour No sign-up required Learn From Neil Patel – Ask Him Direct Questions! Neil has been continually optimizing websites for over a decade and is an industry leader when it comes to traffic generation, growth hacks and conversion funnel improvements. Plus, he’s…
We talk a lot about marketing strategy on this blog. But today, we are getting technical.
In this post, I team up with WiderFunnel front-end developer, Thomas Davis, to cover the basics of server-side testing from a web development perspective.
The alternative to server-side testing is client-side testing, which has arguably been the dominant testing method for many marketing teams, due to ease and speed.
But modern web applications are becoming more dynamic and technically complex. And testing within these applications is becoming more technically complex.
Server-side testing is a solution to this increased complexity. It also allows you to test much deeper. Rather than being limited to testing images or buttons on your website, you can test algorithms, architectures, and re-brands.
Simply put: If you want to test on an application, you should consider server-side testing.
Let’s dig in!
Note: Server-side testing is a tactic that is linked to single page applications (SPAs). Throughout this post, I will refer to web pages and web content within the context of a SPA. Applications such as Facebook, Airbnb, Slack, BBC, CodeAcademy, eBay, and Instagram are SPAs.
Defining server-side and client-side rendering
In web development terms, “server-side” refers to “occurring on the server side of a client-server system.”
The client refers to the browser, and client-side rendering occurs when:
A user requests a web page,
The server finds the page and sends it to the user’s browser,
The page is rendered on the user’s browser, and any scripts run during or after the page is displayed.
The server is where the web page and other content live. With server-side rendering, the requested web page is sent to the user’s browser in final form:
A user requests a web page,
The server interprets the script in the page, and creates or changes the page content to suit the situation
The page is sent to the user in final form and then cannot be changed using server-side scripting.
In laymen’s (ish) terms:
When you visit a SPA web application, the content you are seeing is either being rendered in your browser (client-side), or on the server (server-side).
Basically, the page is incomplete upon arrival, and is completed within the browser.
If the content is being rendered server-side, your browser receives the application HTML, pre-built by the server. It doesn’t have to fill in any blanks.
Why do SPAs use server-side rendering?
There are benefits to both client-side rendering and server-side rendering, but render performance and page load time are two huge pro’s for the server side.
(A 1 second delay in page load time can result in a 7% reduction in conversions, according to Kissmetrics.)
All of which to say, with a complex application, client-side rendering can lead to sloooow initial load times. And, because client-side rendering relies on each individual user’s browser, the developer only has so much control over load time.
Which explains why some developers are choosing to render their SPAs on the server side.
But, server-side rendering can disrupt your testing efforts, if you are using a framework like Angular or React.js. (And the majority of SPAs use these frameworks).
The disruption occurs because the version of your application that exists on the server becomes out of sync with the changes being made by your test scripts on the browser.
NOTE: If your web application uses Angular, React, or a similar framework, you may have already run into client-side testing obstacles. For more on how to overcome these obstacles, and successfully test on AngularJS apps, read this blog post.
Testing on the server side vs. the client side
The original page loads, the content is hidden, the necessary elements are changed in the background, and the ‘new’ version is shown to the user post-change. (Because the page is hidden while these changes are being made, the user is none-the-wiser.)
As I mentioned earlier, the advantages of client-side testing are ease and speed. With a client-side testing tool like VWO, a marketer can set up and execute a simple test using a WYSIWYG editor without involving a developer.
A Quick Hack
There is a workaround if you are determined to do client-side testing on a SPA application. Web developers can take advantage of features like Optimizely’s conditional activation mode to make sure that testing scripts are only executed when the application reaches a desired state.
However, this can be difficult as developers will have to take many variables into account, like location changes performed by the $routeProvider, or triggering interaction based goals.
To avoid flicker, you may need to hide content until the front-end application has initialized in the browser, voiding the performance benefits of using server-side rendering in the first place.
Here is an example where we are testing a pricing change:
“Ok, so, if I want to do server-side testing, do I have to involve my web development team?”
But, this means that testing gets folded into your development team’s work flow. And, it means that it will be easier to integrate winning variations into your code base in the end.
If yours is a SPA, server-side testing may be the better choice, despite the work involved. Not only does server-side testing embed testing into your development workflow, it also broadens the scope of what you can actually test.
Rather than being limited to testing page elements, you can begin testing core components of your application’s usability like search algorithms and pricing changes.
A server-side test example!
For web developers who want to do server-side testing on a SPA, Tom has put together a basic example using Optimizely SDK. This example is an illustration, and is not functional.
In it, we are running a simple experiment that changes the color of a button. The example is built using Angular Universal and express JS. A global service provider is being used to fetch the user variation from the Optimizely SDK.
Here, we have simply hard-coded the user ID. However, Optimizely requires that each user have a unique ID. Therefore, you may want to use the user ID that already exists in your database, or store a cookie through express’ Cookie middleware.
Are you currently doing server-side testing?
Or, are you client-side testing on a SPA application? What challenges (if any) have you faced? How have you handled them? Do you have any specific questions? Let us know in the comments!
I’ll explain how you can install this extension that supports the web extension model (i.e. Edge, Chrome, Firefox, Opera, Brave and Vivaldi), and provide some simple tips on how to get a unique code base for all of them, but also how to debug in each browser.
I’ve been thinking a lot about speech for the last few years. In fact, it’s been a major focus in several of my talks of late, including my well-received Smashing Conference talk “Designing the Conversation.” As such, I’ve been keenly interested in the development of the Web Speech API.
Most people now know that modern web browsers use the GPU to render parts of web pages, especially ones with animation. For example, a CSS animation using the transform property looks much smoother than one using the left and top properties. But if you ask, “How do I get smooth animation from the GPU?” in most cases, you’ll hear something like, “Use transform: translateZ(0) or will-change: transform.”
These properties have become something like how we used zoom: 1 for Internet Explorer 6 (if you catch my drift) in terms of preparing animation for the GPU — or compositing, as browser vendors like to call it. But sometimes animation that is nice and smooth in a simple demo runs very slowly on a real website, introduces visual artifacts or even crashes the browser. Why does this happen? How do we fix it? Let’s try to understand.
These words are superlatives — meaningless filler. The language is flowery (and not in a good way).
And while this is an extreme example, jargonistic, superlative-laden landing pages are everywhere.
They lack specificity and don’t drive home any message. They aren’t persuasive and their unique value proposition is a blur. They make people feel lost — like they just crawled out of a fallout shelter for the first time in 35 years.
Wait, where am I?
The worst part? You could have meaningless drivel on your landing page and not even know it.
In May of 2015, Facebook unveiled its new in-app publishing platform, Instant Articles. A month later, Apple declared that the old Newsstand experience (essentially a fancy folder full of news apps) would be replaced in iOS 9 with a brand-new news aggregation and discovery platform called Apple News.
Four months later, it was Google’s turn to announce its own, somewhat belated but no less ambitious, plan to revolutionize mobile news consumption with an open-source web-based solution called Accelerated Mobile Pages, or AMP. In just a few months, we’ve seen the relative tranquility of mobile digital publishing erupt into yet another full-scale platform war as Facebook, Apple and now Google compete for both the loyalty of publishers and the attention of readers.
There’s no shortage of boosterism or excitement about the fledgling service worker API, now shipping in some popular browsers. There are cookbooks and blog posts, code snippets and tools. But I find that when I want to learn a new web concept thoroughly, rolling up my proverbial sleeves, diving in and building something from scratch is often ideal.
The bumps and bruises, gotchas and bugs I ran into this time have benefits: Now I understand service workers a lot better, and with any luck I can help you avoid some of the headaches I encountered when working with the new API.
According to a recent report1, HTML is the most widely used language for mobile app developers. The main reasons among developers for selecting web technologies2 is cross-platform portability of code and the low cost of development. We’ve also heard that hybrid apps tend to be sluggish and poorly designed. Let’s prove whether it’s possible to deliver the native look and feel that we’re used to.
What Are Hybrid Mobile Apps?
Mobile apps can be generally broken down into native, hybrid and web apps. Going the native route allows you to use all of the capabilities of a device and operating system, with a minimum of performance overhead on a given platform. However, building a web app allows your code to be ported across platforms, which can dramatically reduce development time and cost. Hybrid apps combine the best of both worlds, using a common code base to deploy native-like apps to a wide range of platforms.
There are two approaches to building a hybrid app:
Compiled hybrid app
While both approaches are widely used and exist for good reasons, we’ll focus on WebView apps because they enable developers to leverage most of their existing web skills. Let’s look at all of the benefits and drawbacks of hybrid apps compared to both native and mobile web apps.
Developer can use existing web skills
One code base for multiple platforms
Reduced development time and cost
Easily design for various form factors (including tablets) using responsive web design
Access to some device and operating system features
Advanced offline capabilities
Increased visibility because the app can be distributed natively (via app stores) and to mobile browsers (via search engines)
Performance issues for certain types of apps (ones relying on complex native functionality or heavy transitions, such as 3D games)
Increased time and effort required to mimic a native UI and feel
Not all device and operating system features supported
Risk of being rejected by Apple if app does not feel native enough (for example, a simple website)
These drawbacks are significant and cannot be ignored, and they show that the hybrid approach does not suit all kinds of apps. You’ll need to carefully evaluate your target users, their platforms of choice and the app’s requirements. In the case of many apps, such as content-driven ones, the benefits outweigh the drawbacks. Such apps can typically be found in the “Business and Productivity,” “Enterprise” and “Media” categories in the app store.
Both Hojoki and CatchApp are very content-driven productivity apps, so we initially thought they would be a great match for hybrid development. The first three benefits mentioned above were especially helpful to us in building the mobile app for Hojoki in just four weeks8. Obviously, that first version lacked many important things. The following weeks and months were filled with work on optimizing performance, crafting a custom UI for each platform and exploiting the advanced capabilities of different devices. The learning in that time was crucial to making the app look and feel native. I’ll share as many lessons as possible below.
So, how do you achieve a native look and feel? To a mobile web developer, being able to use the features of a device and operating system and being able to package their app for an app store sounds just awesome. However, if users are to believe it is a native app, then it will have to behave and look like one. Accomplishing this remains one of the biggest challenges for hybrid mobile developers.
Make Your Users Feel at Home
A single code base doesn’t mean that the app should look and feel exactly the same on all platforms. Your users will not care at all about the underlying cross-platform technology. They just want the app to behave as expected; they want to feel “at home.” Your first stop should be each platform’s design guidelines:
While these guidelines might not perfectly suit all kinds of apps, they still provide a comprehensive and standard set of interfaces and experiences that users on each platform will know and expect.
DIY vs. UI Frameworks
Implementing all of these components, patterns and animations on your own can be quite a challenge. All kinds of frameworks exist to help you with that, ranging from commercial (Kendo UI12) to open-source ones (Ionic13) and from ones with a common UI (jQuery Mobile14 and Onsen UI15) to many platform-specific UIs (Sencha Touch7716 and ChocolateChip-UI17). Some are really good at providing a pixel-perfect layout, while others are rather sloppy, thus making it easy for the user to identify a web app. However, my impression is that their main drawbacks are performance-related, because most UI frameworks try to be as all-embracing as possible. Judge for yourself by taking a few minutes to try the demos on your own device.
Custom UI Components
Custom UI components also have many good use cases. Deciding between a platform’s UI and a custom UI will obviously depend on your target audience. If you want to do your own thing, you should have a deep understanding of UX design, because the guidelines linked to above were crafted by experts to meet the particular requirements of their platform’s users.
Whether you stick to a platform’s UI guidelines or do your own thing with custom components, know that there are certain design patterns that most people use every day and love. How are people usually introduced to a new app? Through a slideshow walkthrough or an instructional overlay. How do people navigate? With a tab bar or a sidebar drawer18. How do users quickly load or refresh data? By pulling to refresh. (Native-like scrolling will be covered extensively further below.)
One important part of a UI is the header bar, with its title and navigation elements, most notably the “up” and “back” buttons. To me, many popular frameworks fail to provide a HTML and CSS solution that compares to a native app. Mimicking this part of the UI with a minimal DOM and a few lines of CSS for each platform is actually fairly easy:
<!-- more actions (e.g. a search button on the right side) -->
Using the same DOM across all platforms is generally preferable because it results in cleaner code and, therefore, maximizes maintainability. I’ve found this to be easily possible for many UI components on iOS and Android (including the header bar, tab bar, custom navigation menu, settings page, popover and many more). However, this becomes much harder when adding support for Windows Phone, which comes with some very different design patterns.
Support High-Resolution Screens
Nowadays, smartphones and tablets with high-resolution screens make up the vast majority of mobile devices, making up more than 80% of iOS devices23 and over 70% on Android devices24. To make your images look crisp for everyone, you usually have to deliver twice the dimensions than what is actually shown in your app. Serving properly sized images for all different resolutions is one of the most discussed topics in responsive web design. There are various approaches, each with its benefits and drawbacks related to bandwidth, code maintainability and browser support. Let’s quickly review the most popular ones, in no particular order:
server-side resizing and delivering
HTML5 picture element
HTML5 srcset attribute
CSS media queries
Resolution-independent images (SVG)
As always, there is no silver bullet for responsive images. It pretty much depends on the type of images and how they are used in the app. For static images (such as the logo and tutorial images), I try to use SVG. They scale perfectly without any extra effort and have great browser support as long as you’re fine with Android 3+25.
When SVG is not an option, the HTML5 picture element and srcset attributes26 are definitely where front-end development is heading. Currently, their main drawback is the very limited browser support and, therefore, their need for polyfills.
/* Normal-resolution CSS */
background: url(logo.png) no-repeat 0 0;
/* HD and Retina CSS */
only screen and (-webkit-min-device-pixel-ratio: 1.25),
only screen and ( min--moz-device-pixel-ratio: 1.25),
only screen and ( -o-min-device-pixel-ratio: 1.25/1),
only screen and ( min-device-pixel-ratio: 1.25),
only screen and ( min-resolution: 200dpi),
only screen and ( min-resolution: 1.25dppx)
background: url(firstname.lastname@example.org) no-repeat 0 0;
background-size: 120px; /* Equal to normal logo width */
However, your app might already contain a lot of content (such as news articles), and adjusting all of the img tags or replacing them with CSS would be exhausting. A server-side solution is the best choice in this case.
Starting last year, more and more Android manufacturers have gone one step further with what is called XXHDPI (or very very high-resolution) screens. Whichever solution above fits your need, keep in mind that you’ll need images that are three times the original dimensions to support Android’s latest flagship devices.
Use System Fonts
A simple yet important way to make users feel at home is to use system fonts.
These are my recommended font stacks on the major platforms:
Furthermore, iOS 7 offers some interesting presets that automatically set the correct font family, font size and line height. It’s as easy as using font: -apple-system-body for normal text and font: -apple-system-headline for headings. This not only simplifies font declarations, but also improves accessibility through “dynamic type31,” Apple’s system-wide font-size setting. You can dig deeper into iOS 7 font presets in a post by Thomas Fuchs32.
An Icon Is Worth A Thousand Words
Iconography is an important part of the user experience on all major mobile platforms. As with fonts, you’re usually best off using icons that your target audience already knows. Recalling what I said about high-resolution screens earlier, make sure that your icons are scaleable. Implementing them as a font via CSS’ @font-face rule is a great way to achieve this, and it comes with wide browser support33. It even allows you to change an icon’s appearance (for example, its color, shadow and transparency) seamlessly via CSS. Here are my recommendations:
Get various platform icon fonts. Ionicons34 is our baseline set because it includes nearly everything we need. This includes specific icons for iOS and Android in addition to their general ones. The rest come from specific platform icon fonts for iOS35, Android set 136 and set 237 and Windows Phone38.
Combine them with a icon font generator.
Using multiple icon fonts is confusing and quickly adds up in size. That is why we use Fontello39 to combine the different sets, adjust key codes and export them for each platform. The result is <span class="icon">s</span>, which looks like a search icon on iOS, Android and Windows Phone, respectively. Also, check out the popular alternatives IcoMoon40 and Fontastic41.
Beyond that, mobile hardware and rendering engines are improving at a rapid pace, with new devices coming out every other day. Developers can make the performance of a hybrid WebView app difficult to distinguish from that of a fully native app on the iPhone 5 series and on Android phones comparable to Nexus 4 and 5.
Increase Perceived Speed
Building a performant app is one thing, but making it feel fast is a whole other. Whether your app needs some time for a certain task (such as some heavy calculation or client-server communication), presenting instant feedback is crucial to providing a fluid and responsive experience. A common technique is to delay tasks that the user doesn’t need yet, while predicting and preloading the steps the user might take next. A famous example is Instagram, which uploads photos in the background48 while the user is busy adding tags and sharing. Perceived speed can be very different from actual speed, so let’s use it in our favor. Here are some no-brainers.
Remove the Click Delay on Touch Devices
if ('ontouchstart' in window)
Internet Explorer 10+ is a bit easier. You just need some CSS:
Furthermore, remove the default tap highlight while adjusting your active states on mobile. I’d also recommend disabling user selections on actionable elements, because the selection menu would be quite disruptive if the user accidentally taps the button for too long.
Cross-platform tools like PhoneGap and Trigger.io also provide access to native loaders, which is great for showing a full-screen loading animation.
Get the Scrolling Right
Scrolling is one of the most important factors in the user experience of many apps. This is both a curse and a blessing because the success of its implementation will depend heavily on the scrolling niceties that your app relies on and on the mobile operating systems that need to be supported.
Scrollable content and a fixed header and/or footer bar are common to nearly all apps. There are two common approaches to achieving this with CSS:
Enabling scrolling on the body, and applying position: fixed to the header;
Disabling scrolling on the body, and applying overflow: scroll to the content;
Let’s look at some of the basic scrolling features.
The touch-friendly momentum effect enables users to quickly scroll through large content areas in an intuitive way. It can be easily activated with some simple CSS on iOS 5+ and in some versions of Chrome for Android. On iOS, this will also enable the content to bounce off the top and bottom edges.
Scroll to Top
Make It Easy To Hit Stuff
When performing a touch action, users will quite often miss their target by a few pixels, especially on small buttons (such as the ones in iOS’ top bar). Developers can assist users while keeping the design elegant by enabling an invisible touch area around small targets:
You’ll have to put the event handler on the button element, while restricting the styles to div.innerButton. Check out the full example, including CSS62, on JSFiddle.
Using Touch Gestures
Don’t Miss Out on Native Functionality
Building your app with web technology doesn’t necessarily mean that you can’t use native features. In fact, all major cross-platform development tools provide built-in access to the most important functionality. This includes APIs for device data, the file system, the network connection, geolocation, the accelerometer, notifications (including push) and much more.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6)
And here’s the code to copy a given string to the device’s clipboard on iOS:
Web developers often overlook how to handle bad situations in a hybrid app (for example, a connection timeout, a bad input, a timing issue, etc.). A hybrid app is fundamentally different from a website, mainly because there is no global refresh button, and an app can easily run in the background for weeks on some mobile operating systems. If the user runs into a dead end, their only option will be to restart the app, which entails force quitting and then restarting. Many people don’t even know how to do that, especially on Android 2.x (where it’s hidden deep in the app’s settings) and on iOS 6 and below (where you have to double-tap the home button, long-press the icon and kill it).
So, ignore the refresh button during development, and handle bad situations as they come up. For all other situations that would have unexpected outcomes, such as ones involving client-server communication, be prepared for things to go wrong, and provide a way out for users. This could be as easy as showing a full-screen error message — “Oops! Something bad happened. Please check your connection and try again” — with a big “Reload” button below.
How To Wrap It
A few cross-platform development tools provide that native bridge and simplify the whole process of wrapping it. Let’s dive into some options.
PhoneGap and Apache Cordova
PhoneGap68 is certainly one of the most popular tools for cross-platform development. The name itself is often used synonymously with hybrid mobile app development.
Both are open-source and free to use, with support for all major platforms and with an active community developing all kinds of plugins and extensions.
PhoneGap has shaped the hybrid lanscape significantly, and many new tools have emerged that offer additional services or that streamline the development process. They usually add a lot of convenience by enabling you to build an app in the cloud, thereby saving you the effort of locally installing all of the different platform SDKs and tools. Each tool has a different focus, level of platform support and price:
Sencha Touch7716 started out as a UI framework for the mobile web and has been around for years. Traditionally, developers have used Sencha to build an app while using another service, like PhoneGap, to deploy it as a hybrid app. Nowadays, Sencha offers this kind of functionality built in for free. Platform support includes iOS and Android (both via Sencha’s own native packager) BlackBerry, Windows 8 and more (via PhoneGap Build).
At Hojoki, we started using Trigger.io78 two and a half years ago because we were looking for a lightweight alternative to PhoneGap. Even though iOS and Android are its only supported platforms, it offers a good set of native APIs, custom plugins and third-party integration (including Parse push notifications, Flurry analytics and parts of Facebook’s SDK). Trigger.io’s command-line tools allowed us to integrate the app’s packaging into our Grunt79 build process, which is great if you love automation.
Once the 14-day trial is up, Trigger.io’s steep pricing82 is probably the biggest downside for many developers.
With MoSync83 having gone offline a couple of days ago, Trigger.io seems to be the only remaining tool that is not associated with PhoneGap.
Test on Real Devices
Building a mobile app with web technologies obviously tempts us to do most of our testing in a web browser. This might be fine when developing non-native features, but definitely avoid it when releasing. Test with as many manufacturers, platforms and form factors as possible before submitting the app. Android’s fragmentation brings endless possibilities of differences in browser rendering, unsupported features and manufacturer modifications. While iOS does much better with rendering differences, Apple has a growing number of devices with varying sizes, resolutions and pixel densities. Check out “Prioritizing Devices: Testing and Responsive Web Design84” to learn more.
When Facebook famously ditched most of its HTML5 and went native in 2012, it cited missing debugging tools and developer APIs85 as one of its main reasons. LinkedIn drew the same conclusions86 half a year later, stating that HTML5 itself is ready, but basic tools and the ecosystem don’t support it yet. From what I’m seeing, the situation is getting better, with remote debugging in WebView on Android 4.4+ and an increasing number of development tools on all platforms:
When building an app for web browsers, deploying a hot fix to users is a simple step, which means that testing can lose some of its importance. This obviously needs to be reconsidered when you’re releasing an app through an app store. Think of it like software development in the ’90s: You’re now living in the world of hard releases.
So, why is this bad? First, the submission process could easily take a week or two (Hello, Apple!). Secondly, even if your hot fix is released quickly, that doesn’t guarantee that users will update the app any time soon. Here are my suggestions:
Make testing a high priority.
Have some kind of “force update” logic to deprecate old client versions.
Use mechanisms like Trigger.io’s Reload9280 to fix code on the fly.
The tools mentioned above spit out a binary for each platform, which can then be submitted to the relevant store. From this point on, the process is exactly the same as publishing a “normal” native app. Some of the tools we’ve looked at might even have better documentation for this. Nevertheless, here are the official guides:
Now that our hybrid mobile apps have been in Apple’s App Store and in Google Play for two years, I’d like to recapitulate some of the benefits and drawbacks mentioned at the beginning of this article.
For us, a web startup company with very limited resources and no native iOS or Android experience, building an app for multiple platforms in just a few weeks would have been impossible. Choosing the hybrid path enabled us to reuse a lot of code from the web app and to iterate quickly based on user feedback. We’ve even managed to publish native apps for Windows 8 for the desktop and Microsoft Surface as well as Mac OS X with exactly the same code base. The effort of moving to another platform will depend largely on the capabilities of the given browser and device and on the level of your need for native functionality. We needed push notifications, in-app purchases and access to the user’s contacts, among other things. Depending on your needs, a lot of native functionality could make you heavily dependent on the native wrapping tool that you choose.
Finally, let’s see whether hybrid apps really can deliver a native look and feel. Below is a compilation of user reviews from the app stores. Both positive and negative comments are included, but many of the negative reviews are for early releases, which had the same UI for all platforms and was comparatively slow in performance.
★ Great idea, but not a good app. The app runs extremely slow on my Samsung Galaxy Ace and Tab. The app also looks and controls like an iPhone app. This is confusing when you have never had an iPhone.
★★ Another reason apps should not use WebViews for UI.
★★ Service great but WebView app sucks.
★★★ It’s the right app in concept, but it really is too laggy to be practically used. And I’m using Jellybean so there is no excuse.
★★★ It lags a lot and the UI is not beautiful.
★★★ Good but very very slow.
★★★★ This app is very handy, but is a little slow to boot up.
★★★★★ This is working really hard well since the update. It’s a great app to begin with and now it’s working smoother and faster than before.
★★★★★ Extremely smooth and effective.
★★★★★ The app work flawlessly…
★★★★★ Beautiful designed app! Love the interface and the great overview of all your tools! Good job! Keep shippin!
★★★★★ This is an absolutely beautiful aggregate that runs buttery smooth, even on a 3GS. Recommend to anyone doing any sort of project.
We’re definitely moving away from platform-specific app development and towards the many new technologies that are emerging. Larry Page said this98 when asked at Google I/O last year about the future of the web:
In the very long term, I don’t think you should have to think about, as a developer, am I developing for this platform or another, or something like that. I think you should be able to work at a much higher level, and software you write should run everywhere, easily.
The (mobile) web is a major success story in this regard. Being able to use this platform and still be able to distribute an app in all stores is a huge step forward. It will be interesting to see how this all plays out. Whatever happens, using a technology that over a third of the world’s population99 (over two thirds in Europe and the US) relies on probably won’t be a bad choice.