11-03-2020, 04:02 AM
People hate when apps crash, or even when they slow down or freeze for a few seconds. According to a survey by Dimensional Research, 61 percent of users expect mobile apps to start within four seconds, while 49 percent want responses to inputs in two seconds. If an app crashes, freezes, or has errors, 53 percent of users will uninstall it.
Whether your target audience is consumers or the enterprise crowd, disappointing them is the quick road to being frozen out. I spoke to a number of mobile developers and asked about the most common problems they've come across. Here are six of the top ways your development can go astray and leave your app in danger of heading off a performance cliff.
1. Memory management
One of the biggest problem areas according to virtually everyone I spoke to is memory management. An app might be spinning too many threads and soaking up memory resources or running on a system that has too many apps open. People write code as though only their apps exist, says Sachin Agarwal, VP Marketing at OpsClarity. Your software needs to be a "good citizen in the app ecosystem," he says. "I look at some news apps and they're looking at almost a gig of data. They're archiving news from the last month. There's a level of corporate citizenship that needs to come up on mobile apps."
Not that the problem is the same for all developers. "In iOS there are more things you can do to leverage Objective-C to handle a lot of the memory issues," says Andrew Whiting, vice president of business development at Solstice Mobile. But there is a trade-off. "On Android, you have much deeper [memory] control and you can usually make it do exactly what you want it to do, which adds complexity."
"You get into things [with Android] like [running] out of memory in Java, which typically we find correlated with things like loading big images or processing bitmaps," says Jonathan Karon, senior software engineering manager at New Relic, which distributes a mobile SDK that reports on technical performance and has compiled common causes of problems. "There are actually a surprising number of what look like linker issues on Android, where a class can't be found, or there's an exception called unclassified link." On the other hand, iOS apps often suffer from the NSInternalInconsistency exception, which happens when a developer changes an array or data collection in one place "while something else is reading through the list of things that are there."
2. Software lifecycle
The iterative app development process, with its constant series of frequent releases, opens doors for getting to market with a minimum viable product and then improving it over time, building an audience. But the loss of the traditional software lifecycle introduces significant complications because of dependencies on the operating system and third-party APIs.
"If you look at the latest Android updates, the apps crash a lot," Agarwal says. "The OS is unstable itself. Or the OS gets updated and the app hasn't been updated." Or the user doesn't download the new version. "You have no control and it speaks to a core development process."
The growth of mobile and cloud computing has increased the use of third-party services, and their associated APIs, that save time and help get an app to market more quickly. But they have their own set of issues.
"A lot of the libraries are the lowest common denominators," Whiting says. "They're trying to solve everyone's problems and not making an optimal solution for anyone." For example, a given API might have a performance limitation for a particular app.
The API may also use techniques that can be tricky, like iOS method swizzling. A developer changes mappings from a method name to an implementation, which allows modification of the original method when the original code, like an API from Apple, is unavailable. "You could call it one of the 'dark arts' of iOS app development," says Raman Bhatia, director of mobile at online travel agency Fareportal. "[But] if your app code is written a certain way, it can cause a crash."
APIs also can introduce unexpected modifications. "API latencies, error rates, data bandwidth, version of API used, and the number of API requests can lead to small issues that become big problems," says Agarwal. Then there is the chain of dependencies for the APIs themselves, that creates a need for specialized tools to track everything.
An API can also cause other problems, like memory errors. "You're pointing to an object you had already removed from memory, and that's not usually a problem if you created all the objects yourself because you know whether or not you can refer to it," says Long Le, cofounder and developer of We Get Fit, an upcoming Apple Watch and iPhone fitness app. "The problem happens when you bring in third-party frameworks. You're never sure what they're cleaning up and what they're creating."
3. Inadequate testing
The need for testing is obvious, but getting adequate coverage, particularly with the plethora of Android versions and devices, can be challenging. There are simulators, but software running on a server might not show the same performance limitations.
For example, one thread of an app might try to read a database at the same time a second thread is trying to modify the same database. "It's a timing problem," says Wayne Carter, chief architect of mobile at Couchbase. "If they don't hit at the exact moment in time, the issue doesn't surface. It can be covered up with something as simple as a log statement." A simulator often won't exhibit the same foundational performance limitations of a mobile device, so the race condition isn't apparent.
There are services that run pairings of different devices and variations of operating systems and make them available, but that would likely be more expensive than a simulator. The choice becomes a trade-off between budgets and needs.
Testing should be combined with benchmarking against industry standards and user expectations to be sure that what seems acceptable to developers is also acceptable to users. Testing should also occur on a continuous basis. Monitor performance and look for user feedback suggesting problems, and then fix things as soon as possible.
4. Network management
As apps have increasingly come to depend on network access, either for data or for third-party services, network management has grown as a source of trouble.
"The most important reason [apps crash] is the responsiveness and your app hanging when you're trying to get some data, or you have submitted something and you're waiting for a response," says Pravin Vazirani, associate vice president of operations for Chetu, a software development consultancy. It could be that the developer had a good Wi-Fi connection, but the user is on a mobile network in an area with bad reception.
A change in networks, caused by going from 3G to 2G, going into and out of elevators, or losing reception is particularly tough and can result in lost or scrambled packets. Luckily, "a lot of these conditions can be [modeled] with a few scenarios," says Roi Carmel, senior vice president of products and strategy at mobile app testing company Perfecto Mobile.
One good way to handle a network problem is to inform the user of the connectivity break and to offer, when possible, the chance to do something else that might be of interest. If people understand the cause of what is a temporary condition beyond the control of the app, they're more likely to remain calm and not become annoyed at the software or the brand name associated with it.
5. Error condition and exception handling
Given the complications of mobile development, some errors are inevitable, whether it's an unexpected API change, a memory problem that avoided previous detection, or a network condition that ends connectivity or even just slows data speeds during the transmission of large files like images or video.
What stands between such a situation and a crash is good error and exception handling. This way, an app can't get thrown by an unexpected attempt to divide by zero, an incorrectly entered response from a user, an API that suddenly started providing text as a response instead of a numeric value, or the temporary loss of connectivity.
In any of these cases, a properly coded app will note the unexpected and have a graceful way to terminate a process or activity while informing the user of the error. It may not be ideal, but if you can keep the lines of communication open, there's a better chance you'll keep the user.
6. Too much code
But perhaps the best advice is to keep an app simple. Provide the single-purpose tool that people want and use the exercise to code only what is necessary. "The best and most bug-free code is the code that you don't write," says Felipe Laso-Marsetti, senior systems engineer with enterprise mobile development firm Lextech Global Services.
Can you realistically create a bug-free app, particularly on a first round? Probably not. However, you can focus on these trouble sources and do your best to create strong exception handling for the things that can and will go wrong. Murphy may wander the world of software development, but you can make sure he steps as lightly as possible.
Whether your target audience is consumers or the enterprise crowd, disappointing them is the quick road to being frozen out. I spoke to a number of mobile developers and asked about the most common problems they've come across. Here are six of the top ways your development can go astray and leave your app in danger of heading off a performance cliff.
1. Memory management
One of the biggest problem areas according to virtually everyone I spoke to is memory management. An app might be spinning too many threads and soaking up memory resources or running on a system that has too many apps open. People write code as though only their apps exist, says Sachin Agarwal, VP Marketing at OpsClarity. Your software needs to be a "good citizen in the app ecosystem," he says. "I look at some news apps and they're looking at almost a gig of data. They're archiving news from the last month. There's a level of corporate citizenship that needs to come up on mobile apps."
Not that the problem is the same for all developers. "In iOS there are more things you can do to leverage Objective-C to handle a lot of the memory issues," says Andrew Whiting, vice president of business development at Solstice Mobile. But there is a trade-off. "On Android, you have much deeper [memory] control and you can usually make it do exactly what you want it to do, which adds complexity."
"You get into things [with Android] like [running] out of memory in Java, which typically we find correlated with things like loading big images or processing bitmaps," says Jonathan Karon, senior software engineering manager at New Relic, which distributes a mobile SDK that reports on technical performance and has compiled common causes of problems. "There are actually a surprising number of what look like linker issues on Android, where a class can't be found, or there's an exception called unclassified link." On the other hand, iOS apps often suffer from the NSInternalInconsistency exception, which happens when a developer changes an array or data collection in one place "while something else is reading through the list of things that are there."
2. Software lifecycle
The iterative app development process, with its constant series of frequent releases, opens doors for getting to market with a minimum viable product and then improving it over time, building an audience. But the loss of the traditional software lifecycle introduces significant complications because of dependencies on the operating system and third-party APIs.
"If you look at the latest Android updates, the apps crash a lot," Agarwal says. "The OS is unstable itself. Or the OS gets updated and the app hasn't been updated." Or the user doesn't download the new version. "You have no control and it speaks to a core development process."
The growth of mobile and cloud computing has increased the use of third-party services, and their associated APIs, that save time and help get an app to market more quickly. But they have their own set of issues.
"A lot of the libraries are the lowest common denominators," Whiting says. "They're trying to solve everyone's problems and not making an optimal solution for anyone." For example, a given API might have a performance limitation for a particular app.
The API may also use techniques that can be tricky, like iOS method swizzling. A developer changes mappings from a method name to an implementation, which allows modification of the original method when the original code, like an API from Apple, is unavailable. "You could call it one of the 'dark arts' of iOS app development," says Raman Bhatia, director of mobile at online travel agency Fareportal. "[But] if your app code is written a certain way, it can cause a crash."
APIs also can introduce unexpected modifications. "API latencies, error rates, data bandwidth, version of API used, and the number of API requests can lead to small issues that become big problems," says Agarwal. Then there is the chain of dependencies for the APIs themselves, that creates a need for specialized tools to track everything.
An API can also cause other problems, like memory errors. "You're pointing to an object you had already removed from memory, and that's not usually a problem if you created all the objects yourself because you know whether or not you can refer to it," says Long Le, cofounder and developer of We Get Fit, an upcoming Apple Watch and iPhone fitness app. "The problem happens when you bring in third-party frameworks. You're never sure what they're cleaning up and what they're creating."
3. Inadequate testing
The need for testing is obvious, but getting adequate coverage, particularly with the plethora of Android versions and devices, can be challenging. There are simulators, but software running on a server might not show the same performance limitations.
For example, one thread of an app might try to read a database at the same time a second thread is trying to modify the same database. "It's a timing problem," says Wayne Carter, chief architect of mobile at Couchbase. "If they don't hit at the exact moment in time, the issue doesn't surface. It can be covered up with something as simple as a log statement." A simulator often won't exhibit the same foundational performance limitations of a mobile device, so the race condition isn't apparent.
There are services that run pairings of different devices and variations of operating systems and make them available, but that would likely be more expensive than a simulator. The choice becomes a trade-off between budgets and needs.
Testing should be combined with benchmarking against industry standards and user expectations to be sure that what seems acceptable to developers is also acceptable to users. Testing should also occur on a continuous basis. Monitor performance and look for user feedback suggesting problems, and then fix things as soon as possible.
4. Network management
As apps have increasingly come to depend on network access, either for data or for third-party services, network management has grown as a source of trouble.
"The most important reason [apps crash] is the responsiveness and your app hanging when you're trying to get some data, or you have submitted something and you're waiting for a response," says Pravin Vazirani, associate vice president of operations for Chetu, a software development consultancy. It could be that the developer had a good Wi-Fi connection, but the user is on a mobile network in an area with bad reception.
A change in networks, caused by going from 3G to 2G, going into and out of elevators, or losing reception is particularly tough and can result in lost or scrambled packets. Luckily, "a lot of these conditions can be [modeled] with a few scenarios," says Roi Carmel, senior vice president of products and strategy at mobile app testing company Perfecto Mobile.
One good way to handle a network problem is to inform the user of the connectivity break and to offer, when possible, the chance to do something else that might be of interest. If people understand the cause of what is a temporary condition beyond the control of the app, they're more likely to remain calm and not become annoyed at the software or the brand name associated with it.
5. Error condition and exception handling
Given the complications of mobile development, some errors are inevitable, whether it's an unexpected API change, a memory problem that avoided previous detection, or a network condition that ends connectivity or even just slows data speeds during the transmission of large files like images or video.
What stands between such a situation and a crash is good error and exception handling. This way, an app can't get thrown by an unexpected attempt to divide by zero, an incorrectly entered response from a user, an API that suddenly started providing text as a response instead of a numeric value, or the temporary loss of connectivity.
In any of these cases, a properly coded app will note the unexpected and have a graceful way to terminate a process or activity while informing the user of the error. It may not be ideal, but if you can keep the lines of communication open, there's a better chance you'll keep the user.
6. Too much code
But perhaps the best advice is to keep an app simple. Provide the single-purpose tool that people want and use the exercise to code only what is necessary. "The best and most bug-free code is the code that you don't write," says Felipe Laso-Marsetti, senior systems engineer with enterprise mobile development firm Lextech Global Services.
Can you realistically create a bug-free app, particularly on a first round? Probably not. However, you can focus on these trouble sources and do your best to create strong exception handling for the things that can and will go wrong. Murphy may wander the world of software development, but you can make sure he steps as lightly as possible.