Mozilla + Firefox über-release cycle = #FAIL! The long tail of costs and risks associated with fast release cycles.

Dear Mozilla Foundation, according to your web site you promote openness, innovation and participation. So, I feel strongly enough to write you about a problem. You are pushing for too many major releases in too short of time. If it wasn’t for firebug and httpfox developer tools, I’d dump Firefox as my browser of choice right now. In my humble opinion they are still the best web developer tools around…for now. But back to my point, and note that this isn’t a rash or knee jerk response: Firefox 7 appears to be the least stable browser I’ve used in a long time, Period. I’ve had a dozen lock-ups, problems on startup and various slow page load problems.  

I haven’t added any new plug-ins that might de-stabilize it. In fact, I’ve been using the same set of plug-ins since Firefox 3.x. And, I haven’t had any similar widespread problems with the latest versions of Internet Explorer or Chrome. You might ask “What if it’s just your machine?” To that I say I’ve experienced this on four different machines, and many of my colleagues share the same opinion. So Mozilla, I’m hanging on by my fingertips and you are stomping on them.

The Heart of the Problem

Maybe I’m the exception, but I believe that getting cool new browser features every few months at the expense of stability is the wrong choice. I’ve said this before in another post and I’ll say it again. I’ve read countless articles saying this is what Mozilla has to do to stay competitive. I say you couldn’t be more wrong and that there needs to be a more balanced approach to major releases. Now, I’m not implying that you, Mozilla, are intentionally leaving stability or scalability behind. I’m saying that the massive rush to stay abreast of new features being released by your competitors has to come at a cost, and I believe the cost for Firefox, at this point in time, is stability.

So, in response to an outcry over this and other related problems, and in order to counteract some of the side-effects of your über -release cycle, you will begin offering Extended Support Release, or ESR, sometime in the next year. I interpret this as an attempt to mitigate the über -release cycle’s short-term and long-term risks and costs on Enterprise customers by offering an extending support cycle for a limited number of releases and time. But…readers of this post must read the fine print under the Caveats and Risks sections; for example, ESR’s won’t apply to Firefox Mobile at a time when mobile usage is exploding. And, the ESR makes note of the security risks of staying on an “older” release. Fair enough. However one possible conclusion is, on the surface, ESRs seem like a mere concession to a looming problem, and perhaps it is a stop gap measure at best. Perhaps I’m wrong?

Driving Factors

I want to ask Mozilla the following questions:

  • What’s coming up in your next release?
  • Are the changes really so fundamental that the next release has to be a major numbered version?
  • What metrics are you using to make your decisions?
  • How fast are your users upgrading to new versions world-wide?
  • Is the new version adoption rate trending upward or downward?
  • Who are your largest supporters? Large organizations or the millions of individual users?
  • Have you taken a public survey from your largest supporters of what they would like to see?

Now, of course, this post is just my opinion, and I’m willing to admit that I may be seeing this problem in the wrong light or a different context. But, I and a lot of others want to know what you are thinking.

Hypothetical Scenario

Here’s a hypothetical scenario on how an organization might interpret the ESR, and I speak for myself on this one and am simply presenting one outcome of possibly many. Mozilla will continue to blast along having thirteen more major releases between now and March of 2013*. In response, CIO’s of major organizations will start to choose a pattern of leap frogging across swaths of major releases. In response, their development and IT teams will focus on building web apps, along with a full test suite and certification for Firefox 7. Then their next fully tested and certified release will be targeted at Firefox 9 sometime next year. These organizations may choose to not even support Firefox 8 because it’s between their development and certification cycles. There’s also a long-tail of cost associated with maintaining numerous previous releases across a multitude of browser versions from all the major vendors. In effect, these CIOs will weigh the security risks, costs and other issues over the costs of deploying an army of IT folks and developers to keep up with the über -release cycle.

Concluding Remarks

Mozilla I hope you are listening. You should take the following steps to reduce the possibility of failing as a leading browser vendor:

Focus on stability – IMHO, Firefox appears to be paying the price in the rush to add new and supposedly better features. I’m not even sure what those are because your release process isn’t transparent. As your consumer, first and foremost I would like my browser to be rock solid, followed by speed, followed by snazzy features. Rock solid to me also means that it’s as secure as possible. “Dot” releases are okay and in general they ease the support-related fears from both developers and IT teams.

Slow down the release cycles – Mozilla, you already acknowledged there’s a problem when you proposed the ESRs, but you need to go further than acknowledgement and a pat on the back which is what I consider ESRs to be. Seriously.

Now, I know I didn’t address these above, but I’m throwing these into the mix because I think they are strongly related:

Provide guidance on browser certification and best practices – if documentation for this exists today I can’t find it. Building apps on browsers, today in the year 2012, is still like the Wild West in that everyone does what they think is right, but there’s really no word from the Vendor(s) themselves. Most people point to the W3C. But, everyone agrees that what’s agreed upon in the standard is not what’s officially interpreted and implemented by browser vendors in each and every release.

It’s been speculated by others that having browser vendors offer guidelines would crush innovation, and I strongly disagree. It’s your platform we are building on and you know how to do that in the best possible way. Believe it or not, you are also a key caretaker of the internet in that the web, in its current state, wouldn’t exist without the browser. And, I think it’s your responsibility to step up to the plate and help take leadership role, not just a feature-ship role and simply hope that everything turns out okay.

Provide official tools for browser certification – please don’t leave this entirely up to third parties with different goals and objectives. Based on your vast experience in this process, it would benefit everyone if you were to publicly share your tools, patterns, knowledge and guidance. Or, maybe you already do share this with key partners. Yes, you are open source, but not open process. Browsing through your partner sites doesn’t give any indication of publicly available tools.

I believe that the combination of these four goals would help propell Firefox on more successful trajectory than the one us users see today. Without the inclusion of my last two suggestions, as an application developer I’m hoping my code will work as best as possible, without truly knowing what that means. Is what we are doing simply good enough, or could we all do better? What are your recommendations on patterns for best performance or even unit testing for various languages? I can’t help but believe that you hold the key to that level of knowledge, as well as methodologies and tools that can help Firefox help us deliver on the next generation of web applications.

References

*Mozilla release schedule

Mozilla rapid-release schedule

Mozilla Defends Rapid Release of FireFox Versions (CIO Magazine, August 2011)

10 Essentials for developing commercial Flex 4.5.1 mobile applications

This post is for Adobe Flex/Actionscript/Flash developers who are looking to build commercial-grade mobile apps. I’ve tried to pull together a high-level check list of items you’ll need to build successful and stable apps based on Flex 4.5.1. I’ve also uploaded a fully-functional prototype that demonstrates these concepts in a real-time, GPS navigation app. You can download the app here. So, here goes.

1. Set your initial splashScreenImage and application icon. For your app to look professional you’ll want to display an image while it launches so there isn’t just a blank screen. Here’s a great blog post that goes into more detail and covers handling multiple screen resolutions. One caveat on the splashScreenMinimumDisplayTime property is use this with caution. If you delay the app start too much you run the risk of really annoying users.

<s:TabbedViewNavigatorApplication xmlns:fx="https://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
splashScreenImage="@Embed('assets/splashscreen.png')"
splashScreenMinimumDisplayTime="1500"
splashScreenScaleMode="letterbox">

And, be sure to set the application icon. When you install your app, this is the image that will be displayed in the phone’s UI. Configure this in the yourappname-app.xml file. Note if you image icon isn’t the absolute correct size you’ll get a compiler error:

<icon>
     <image16x16>assets/appicon16x16.png</image16x16>
     <image32x32>assets/appicon32x32.png</image32x32>
     <image36x36>assets/appicon36x36.png</image36x36>
     <image48x48>assets/appicon48x48.png</image48x48>
     <image72x72>assets/appicon72x72.png</image72x72>
     <image114x114>assets/appicon114x114.png</image114x114>
     <image128x128>assets/appicon128x128.png</image128x128>
</icon>

2. Manage your applications life-cycle. The best article to read is the old but still very useful Hero View and ViewNavigator  – Functional and Design Specification and this blog post on Understanding View and ViewNavigator. For some reason the ViewNavigatorEvent poperties listed below aren’t documented in the Adobe on-line help. I’ve complained and so should you!

  • viewActivate Event – called when the view is fully activated. It actually happens after the creationComplete event. If you want to know more about view states in general then read this Adobe article.
  • viewDeactivate Event – use this in a View if you want to handle certain things when the user changes to a different View and the current one has been deactivated.
  • removing Event – This is called right before the viewDeactivate Event. So if there is something you want to do right before the view is fully deactivated then use this event.
  • persistNavigatorState – This property works at the application level and allows you to save the navigator’s view stacks and navigation history to a local persistent object. This is a property that is set in the main application’s mxml file and by default it is set to false. The standard architecture of a mobile app is to destroy the view contents when a user switches views so that the application saves memory. But, if there is a significant cost to destroying and recreating a particular view then you should test setting this property to never. Cost in this case means the amount of time, memory and CPU it takes to destroy and recreate a view. Also, if your end user is repeating this over and over that will ultimately affect battery life. Once a view is destroyed my guess is that memory is set for garbage collection. For info see this very informative Adobe blog post.
    <s:TabbedViewNavigatorApplication xmlns:fx="https://ns.adobe.com/mxml/2009"
         xmlns:s="library://ns.adobe.com/flex/spark"
         persistNavigatorState="true">
    
  • destructionPolicy – This is a property that can be set on individual views and can prevent an individual view from having all its data destroyed when the view is deactivated. For example, you may allow some views to be destroyed where others are mission critical and shouldn’t be destroyed because it’s too expensive to recreate them. As I write this, I believe this only works if the persistNavigatorState property has been set but it’s been a while since I verified that.
    <s:View xmlns:fx="https://ns.adobe.com/mxml/2009"
    		xmlns:s="library://ns.adobe.com/flex/spark"
    		destructionPolicy="never"
    		viewActivate="settingsViewActivateHandler(event)"
    		viewDeactivate="settingsViewDeactivateHandler(event)">
    

3. Manually changing views. Use pushView(), popView(), popToFirstview(), popAll() and replaceView().

  • pushView() navigates the user to a new screen.
  • Use popView() to move back to the previous screen.
  • popToFirstView() changes to the screen to the very first view that was opened. This is programmatically referred to as the view at the bottom of the view stack and uses the FIFO principal.
  • popAll() returns a blank screen. I’ve never used this and I haven’t come across a use case (yet) that would require given the user a blank screen.
  • replaceView() removes the current view and replaces it in the view stack with the new view you that you assign.

4. Passing data between views. One of the requirements of commercial apps is sharing data between different views. There are a number of ways to do this including singletons, dependency injection and using the data property in the pushView() method. Here are some good articles on all three:

  • Using singletons or tightly coupling data. This is typical for prototyping where you don’t want or need the overhead of a full framework. The prototype app download (link at top of page) uses a singleton model for simplicity.
  • Using framework-based, dependency injection. Use this when you want to use a framework such as Swiz, Parsely or Robotlegs.
  • Using the pushView() data property. When you have fairly simple data needs use this via the pattern pushView(viewClass:Class, data:Object = null, context:Object = null, transition:spark.transitions:ViewTransitionBase = null) Note that this pattern is for basic usage and the data object only supports standard content within the object such as Strings, Array, ArrayCollection, etc. If you have a custom class be sure to register them with the registerClassAlias() method or you’ll get runtime errors when you go to switch views.

5. Set application permissions.These are root permissions that are set via manifestAdditions for Android and infoAdditions for iOS – and these are located in the yourappname-app.xml file in your application’s root directory. Here’s an Adobe article with additional details. When the application is installed the user will be alerted to what permissions you are asking for.

<android>
     <manifestAdditions><![CDATA[
          <manifest android:installLocation="auto">
	       <!--See the Adobe AIR documentation for more information about setting Google Android permissions-->
	       <uses-permission android:name="android.permission.INTERNET"/>
	       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	       <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
	       <uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
               <uses-permission android:name="android.permission.WAKE_LOCK"/>
               <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
               <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
	   </manifest>
	]]>
     </manifestAdditions>
</android>

6. Shutdown the app. This only works on Android. On iOS, the user has to do this manually.

NativeApplication.nativeApplication.exit(); 

7. Temporarily disable the screen saver. This is required in apps where you don’t want the screen to go to sleep such as navigation apps where it may be open for a long time without any user intervention. You also need to set the WAKE_LOCK permission in the manifest file.

<uses-permission android:name="android.permission.WAKE_LOCK"/>

 

//Make sure we are on a mobile device and then
//keep the application awake so it doesn't go to sleep and close the screen.                                                      
if(Capabilities.cpuArchitecture == "ARM")
{                                                                             
     NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;                                                                            
}

8. Detecting when phone rotates. If you need to know when the phone rotates use this listener:

stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE,stateChangeHandler);

9. Gracefully fail when network connection is lost. If your app needs network access then it’s a best practice to gracefully fail and let the user know when internet connection is lost and then again when it’s restored.

public function NetworkChangeController(autoStart:Boolean = false)
{             
    var req:URLRequest = new URLRequest(_MAP_URL);
    _urlMonitor = new URLMonitor(req);
    _urlMonitor.addEventListener(StatusEvent.STATUS,serviceMonitorStatusHandler);

    NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE,networkChangeHandler);
}

private function networkChangeHandler(event:Event):void
{
     if(!_urlMonitor.running)
     {
          _urlMonitor.start();
     }
}

private function serviceMonitorStatusHandler(event:StatusEvent):void
{
     trace("Network Status Event: " + event.code + ", " + _urlMonitor.available);
     _urlMonitor.stop();
     event.code == "Service.unavailable" ? _doSomething = false : _doSomething = true;
}

10. Multiple Device Support –sizing for different dpi’s. Last, but not least is using CSS and media queries to help with sizing and layout. Media queries are actually part of the W3C core CSS spec. The cool thing about them is they let you auto-majically detect the users screen dpi (dots-per-inch) and operating system and adjust your CSS accordingly. This saves a huge amount of work on your part:

@namespace s "library://ns.adobe.com/flex/spark";
/* DPI specific styles */
s|Button{
     color:#000000;
     fontWeight:bold;
}

@media (application-dpi:240)
{
     s|Button{
          color:#FF0000;
     }
}

@media (application-dpi:320)
{
     s|Button{
          color:#0000FF;
     }
}

/* Platform specific styles */
@media (os-platform:"IOS")
{
     s|Application{
          backgroundColor:#FFCCCC;
     }
     
     s|ActionBar{
          defaultButtonAppearance:beveled;
     }                      
}

@media (os-platform:"Android")
{
     s|Application{
          backgroundColor:#CCCCFF;
     }
}

A whole new world for app developers – it’s raining cats and browsers!

Holy smokes – how do we support all these different browser types and versions? I’ve been thinking about this for a while, but after attending the AdobeMAX conference this week I got to talk with other developers facing the same issues.  The web app world used to fairly simple: develop for the one or two major browsers running on desktop computers and you were done. We still grumbled a lot and had cross-browser problems that at the time were really annoying. And now we have to deal with not only desktop computers and laptops, but there are also dozens of different mobile browsers and hundreds of new tablet style devices. To make things even more interesting the pace at which new versions of browsers and mobile operating systems are being released is at an unprecedented (and perhaps unsustainable) rate.

What to do, what to do, what to do?  Well if we step back and look at this holistically, there are a few things to consider that can help lay the ground work for building apps in these crazy times. That will help you make better technical business decisions.

For web apps:

  1. What browsers and browser versions your customers are using? How often do you analyze this? If you don’t use a monitoring/analytics tool for this you can always download a free tool to analyze your web server logs. I’ve used Google Analytics in past, but there are plenty of other choices.
  2. What percentages of your visitors are using a particular browser version? Break down your stats again by the browser version. If you still have a large percentage of customers using IE 6 then you might want to consider continuing to support it.
  3. What percentage of your customers use mobile versus non-mobile?
  4. What percentage of customers are from your country? If most of your customers from outside your country then you’ll also have to include localization code.
  5. What type of device is each web site visitor using? Mobile devices can have vastly different screen resolutions and sizes.
  6. Which browsers represent visitors/customers that make you the most money? This is a very important number to know and getting this information can be a bit more involved than the other questions. If you mess up support for these group(s) you’ll really cause yourself business problems.

For native apps:

  1. Have you reviewed your marketplace stats page? One example is the Android Market offers application stats such as platform versions, devices, countries of origin, languages, etc.

What if you haven’t launched your app or website yet? If this is the case, then check out some of public tracking sites for hints. Some good places to start looking are: w3schools and Wikipedia which lets you drill down into different browser versions.  For mobile apps, most IDEs let you set up various layout scenarios that relate to rough categories of dpi (dots per inch). For example, here is an article from Adobe on Flex mobile development and handling different mobile device screen resolutions.

How do I interpret this information? In general, you want to have support for browsers and operating systems that the majority of your customers use. One example is in the retail/consumer industry you absolutely have to support what your customers use. If the vast majority of your customers use Internet Explorer then you will need to support IE or you will lose customers and money. If the vast majority of your visitors use Android, but your biggest spenders use iPhones then take that into your development considerations. If your website or application performs poorly for a small percentage of very high-spending customers then it could cost you your business. If you are lucky enough to have commercial customers consuming an internal-only application, or if you have an ultra-niche audience that only uses a single browser or smart phone operating system then you already have your answer. You build to suit their needs.

Any further advice? Test, test, test and then test some more on real devices and different versions of browsers. Emulators and simulators are not an adequate substitute for real-world checking. If you are a small shop, enlist family, friends and neighbors to test. Have them check out our app or website for a few minutes while they relax in the evening. You can also buy after market handsets on eBay and other places, just be careful that if a deal is too good to be true you probably shouldn’t purchase it. The reality is there are so many devices nowadays that you simply can’t test them all. So, pay special attention to feedback in your market place listing or on your forums.