Why Native Is Winning

Posted by Ben

I keep reading blog posts and tweets that insist you can build web apps that look & feel as good as native apps, but I’m not convinced you can.

The debate on Native vs Web apps has raged for years, but came to the fore after the iPhone was released in 2007. There was no Native SDK, you couldn’t build apps for the iPhone! But wait, the iPhone shipped with a fully fledged Web browser.

You’ve got everything you need if you know how to write apps using the most modern web standards to write amazing apps for the iPhone today

Steve Jobs, iPhone announcement 2007.

You can take that with a pinch of salt, but I still believe Jobs thought apps based on web technologies was a viable option.

Zoom a year forward to 2008 and Apple released the iPhone SDK. Native apps start getting built, the App Store launches and the rest, as they say, is history.

Why didn’t Web apps take off?

Web based apps had an entire year’s head start on native, they had (have) no app store restrictions (submission times, rules, rejections, etc), but we didn't see any web apps really take off.

So why didn't that happen? The simple answer, in my opinion, is that the technologies were’t up to scratch. The JavaScript rendering engine was slow, CSS support was good but any animations were laggy and you didn't have access to important hardware features such as the camera or GPS signal.

Another reason was the development tools just weren’t (and arguably still aren’t) available.

I still believe some of these issues hold true today, and as I noted in my last post:

Facebook recently re-wrote their iPhone app to be native due to performance issues with the HTML version.

If a company the size of Facebook, with the resources they have and the enormous pool of talent they’ve hired/acquired, can’t build a web app that matches native performance then I’m not sure who can.

What actually got me thinking about all this was a post over on Forecast’s blog: It’s not a web app, it’s an app you install from the web

Native weather app compared to Forecast.io

Navtive vs Web weather app

Forecast is one of the best apps built using web technologies available today. It looks great, all the animations are smooth and everything is responsive. The Forecast team did a great job.

Their post is full of useful tips and helpful info on building web based apps, but one thing caught my attention:

If you can’t find a way to do something that doesn’t feel choppy or awkward, then just don’t do it. Design your interface around the technology you have, not the technology you wish you had.

I think this is where their argument that web apps are capable of being as good as native, trips up.

If you can’t find a way to do something using Web technologies, but you can do that thing using native, then “just don’t do it” doesn’t cut the mustard when your aim is to build true next generation apps.

The reason why every app that blows you away is native is because the development tools are available, the technologies are standardised across devices, and most important they work as expected. Today. Sadly, that’s just not the case with the web.

Another post, by Bruce Lawson, that I encourage you to read is What does the web platform need?

The advancement of what marketing and the press like to call “HTML5? (but mostly isn’t just HTML5) is closing the gap between the capabilities of native and web. But it isn’t there yet.

Bruce has created a gist asking developers why they choose native over web, some of the common reasons listed:

  • DRM
  • Geolocation in the browser stops tracking when screen goes blank
  • Hardware access (camera, GPS, NFC etc)
  • UI fluidity
  • Developer tools

The list goes on.

As a web developer it pains me to write posts like this — I really want to be able to develop world class apps using Web technologies — but we’re kidding ourselves if we think web technologies can create fully fledged, next generation apps today.

I believe in the web (I develop for it after all!) and the potential and real advantages it has over native, so my hope is that within the next months and years we’ll see better support and access to device hardware and system APIs, giving web developers the ability to write those next generation apps.

The only way to do that is to create apps with web technologies that push the boundaries of what's possible today. We should be reporting bugs, requesting features, getting involved in specification discussions and generally evangelise the web. That's what I plan to do.

Prototyping with Web Technologies

Posted by Ben

Over the years the steady progression of web technologies like HTML, CSS and JavaScript, has meant we’re now able to replicate many of the UI elements and interactions you see in native applications using web technologies.

With that in mind, I’d like to go over a couple of ways we use web technologies in our apps and workflow here at Realmac.

Before we go any further, let me say this: in my opinion, building an entire app using current web technologies just doesn’t cut the mustard. It’s clunky; interactions and animation are jerky or delayed by a split second. Things don’t quite work how you expect them to.

We may see this change in the future (with better JavaScript rending and new HTML and CSS features being developed), but today web-based apps aren’t on the same level as native apps.

Don’t believe me? Facebook recently re-wrote their iPhone app to be native due to performance issues with the HTML version.

Where I do think web technologies have an advantage over native is when prototyping features. It’s so quick and easy to put together a web page with an element(s) that you want to get a feel for. This is especially true when working within a team; there’s no provisioning profiles or app updates to install, just send out the URL and anyone can test and give feedback.

Analog filter Slider

Another benefit is happy coincidences. When we were building the Analog site, I was coding up the filter switching animation and it got us thinking about adding the animation to the app. If you’ve not seen the animation, go check it out on the site, but basically there’s a bar that swipes back and forth across a photo, removing the old filter and applying the new.

It was so quick to build (finished in literally a couple of hours) and gave us an instant feel for how it might work in the app. In the end we decided to not add it to Analog, but we saved several hours by prototyping it on the web rather than coding it in to the app. It’s situations like this where the web wins over native.

Embedded web views are really popular, you might not realise but I bet many of the apps you use on a daily basis have some form of an embedded web view. The Spotify Mac app, for example, has many web views; “What’s New” page, that’s also a web view and so is the activity sidebar.

We’ve embedded quite a few web views in to our apps over the years; the welcome screen for RapidWeaver used to be a web view which used JavaScript calls to talk to the native code.

So there’s certainly an argument for using web technologies in native apps, I just think you have to pick and choose very carefully so as not diminish the experience of your app.

Future wise I can see prototyping using web technologies becoming a bigger part of our work flow. I can also see, within the next couple of years, more apps adding features programmed using web technologies, especially with all the new shiny features currently being worked on like CSS Filters, HTML5 Fullscreen API and the FileSystem API amongst others. You can also get a glimpse of the future with the amazing HTML demos on the Form Follows Function site. It’s certainly an exciting time to be a web developer!

I’d love to hear how you prototype features in your apps or if you’ve written a web based native app, and how it went. Leave a comment below or tweet me @bencounsell.

Coding for Retina on the web

Posted by Ben

A couple of weeks ago Chris wrote about Designing for Retina, which covered Mac App design. The same principles apply to designing images for the web. So if you haven’t yet, go and read Chris’ post as it’ll give you a good idea of what you need to consider when designing retina images. In this post we’ll look at how you can implement retina images on your website.

Principles

When you're writing CSS, you need to be careful to only download retina graphics when they're really needed. This is done by detecting what’s known as the “pixel ratio”. Very simply, this is the number of physical pixels vertically and horizontally that render each virtual pixel (more commonly known as “points”). Non-retina devices (such as the iPhone 3GS or current MacBook Air) will have a pixel ratio of 1, whilst newer retina devices (iPhone 4 onwards) have a pixel ratio of 2. If you’re wanting to learn more about pixel ratios, I suggest watching Session 602 - Delivering Web Content on High Resolution Displays on Apple’s Developer site.

There are currently three ways to implement retina images; via the CSS background-image property, with Javascript or using the new Image Set CSS function. We’ll cover all three below.

Oh, just a quick note: I append the Apple standard “@2x” to the retina image name. So “cats.png” becomes “cats@2x.png” on a retina device.

CSS Images

This option works for any HTML element you want to set a CSS background image on.

To do this, set your element styles as you would normally including the background-image property. Then add a media query that checks the min-device-pixel-ratio is 2 and set the background-image to use the retina image.

It’s important to remember that you must include the background-size property in the base styles for the element, as the browser needs to know the original size so it can scale the retina image appropriately.

Note: I’ve removed browser specific prefixes on all code examples for simplicity.

/* Standard styles for your element
    Be sure to include the background-size property
*/
.cats {
    …
    background-size: 400px 200px;
    background-image: url(cats.png);
}

@media screen and (min-device-pixel-ratio: 2) {
    /* Set the retina background */
    .cats {
        background-image: url(cats@2x.png);
    }
}

This is nice and easy and it’s great for performance as the browser only downloads the image needed for the device, rather than both. The browser will also automatically update the images when dragging the browser window between a non-retina and retina display (say a Retina MBP and the current Cinema Displays). The downside is that it’s not great for accessibility to serve all your images (in a sprite or individually) this way, but you need to make that decision based on your project.

Inline Images with Javascript

Inline images are tricker to deal with. Currently there’s no way to tell the browser which image you want it to display for the device. What you could do is check the pixel ratio on page load and create all the inline images you need based on that, then insert them in to the DOM. I don’t like this solution as I feel it’s a bad user experience: the images flash in to view after the rest of the content had loaded so I’m not going to cover this technique here.

Instead, what I did on the Analog page was add a matchMedia listener to the window and update all the images on the page as if it was a retina device.

Note: In this example I loop through all <img> elements on the page, but you'll probably want to selectively replace images which you could do via a class or data- attribute selector.

function retinaise() {
    // Check if it's a retina device or not
    var retina = (window.devicePixelRatio > 1) ? true : false;

    // Loop through all the images you want to update
    $("img").each(function(i,image) {
        var source = image.getAttribute('src');

        // Append "@2x" to the image src if it's a retina device
        // else remove the appended "@2x" if it's a non-retina device
        if (retina == true) {
            source = source.replace(/\.\w+$/, function(match) { return "@2x" + match; });
        } else {
            source = source.replace(/(@2x)/, '');
        }

        // Set the image src
        image.setAttribute('src', source);
    }); 

}

// Add a listener for the device pixel ratio
window.matchMedia("(device-pixel-ratio: 1)").addListener(retinaise);

This is great for accessibility; all your images are image elements on the page. It’s also great as the images will update in the same way as the CSS background images technique when dragging the browser window between displays. This technique isn’t so hot when it comes to performance as you’ll be loading both the standard and retina versions of every image. Again, this is something you need to decide on based on your project spec and target audience.

Something you should consider using is retina.js, it’s an open source project that “makes it easy to serve high-resolution images to devices with retina displays”.

CSS Imageset

Finally there is a new CSS function, created by Apple, called Image Set.

Image Set allows you to specify a set of images for the CSS element in question, and tell the browser the pixel ratio you want to target, like this:

.cats {
    background-image: -webkit-image-set(
        url(cats.png) 1x,
        url(cats@2x.png) 2x
    );
    background-size: 400px 200px;
}

This is lovely as you can list multiple images in one place and the browser applies the most relevant image for the device. What isn’t so lovely is that it’s currently only available in Safari 6, Safari on iOS 6 & Chrome 21. It’s also not great for accessibility as mentioned in the CSS images section above.

So that wraps up what I believe are the most relevant techniques for retinaising your images on the web. You’ll need to choose between them depending on the needs of your project.

If you found this post helpful, think I’ve missed something or have other ideas on implementing retina images, please let me know on Twitter or leave a comment below.