Android Network Optimization: Tutorial and Course

Android Network Optimization: Tutorial and Course - Android Network Optimization Tutorial and Android Network Optimization Course, The Ultimate Guide to Android Network Optimization. Learn Android Network Optimization Tutorial and Android Network Optimization Course at Android Network Optimization Tutorial and Course.

Android Network Optimization Tutorial and Android Network Optimization Course


Android Network Optimization: Overview


Android Network Optimization Tutorial and Course - Android Network Optimization tutorial and Android Network Optimization course, the ultimate guide to Android Network Optimization, including facts and information about Android Network Optimization. Android Network Optimization Tutorial and Course is one of the ultimate created by to help you learn and understand Android Network Optimization and the related SEO technologies, as well as facts and information about Android Network Optimization.



Android Network Optimization Tutorial, Android Network Optimization Course

Android Network Optimization: Tutorial and Course - Android Network Optimization Tutorial and Android Network Optimization Course by , The Ultimate Guide to Android Network Optimization.



Android Network Optimization: Tutorial and Course


What Is Android Network Optimization?


Android Network Optimization is the process of optimizating Android network performance by best practices for Android apps. The general trend for network performance is to download everything as quickly as possible. By getting out of the way of the radio, and letting the radio turn off, you save power. By getting the content to your customers as fast as possible, your customers are more engaged and less likely to become frustrated.



Android Network Optimization: Tutorial and Course


The web performance community has established a number of , and these also apply to mobile apps. We will also discuss several additional mobile-only best practices for your Android app (and they also apply to any iOS development you might do). The optimization best practices listed here are in no particular order of importance, as each of these will affect app performance differently (and some will likely not apply to your app at all). The general trend for network performance (whether on desktops or mobile) is to download everything as quickly as possible. By getting out of the way of the radio, and letting the radio turn off, you save power. By getting the content to your customers as fast as possible, your customers are more engaged and less likely to become frustrated.



The basic rules for mobile app performance are listed as the follows:





Now, several of these are website specific, but most of them still hold for Android native optimizations, and we will cover them in the following sections.



Android Network Optimization: File Optimization

There are two basic ways to download data faster: lower the number of requests, and/or reduce the size of those requests. This can be a hard pill to swallow, as our apps are getting more and more complex each day, but hopefully the pointers in this Android Network Optimization Tutorial and Course will help you come up with plans to reduce the amount and size of content in your app.



Text File Compression (Gzip Components) is one of the easiest fixes to make. When delivering text files (HTML, CSS, JavaScript, JSON, etc.) to your app, compressing them on the server can reduce the file size by 4-8x. This large reduction in file size from your server to your app means fewer roundtrips and faster delivery of the file. For example, in one app, we saw a 200 KB text file downloaded without Gzip compression. Placing this on a compression-enabled server reduced the size on the wire to 51 KB. Not only do you deliver the content to your customers faster, but you reduce the utilization and bandwidth of your servers too!



There are a number of Gzip algorithms available for use today. In general, the standard Gzip compression is good enough for most apps. If you are really trying to get the most out of compression, and you have files that do not change very often, you could try the Zopfli compression algorithm, as it squeaks out about 5% more compression than the default Gzip algorithms. On the downside, it takes about 100x longer to perform the file compression (hence the "only use it on precompressed files" warning).



Enabling Gzip compression is a simple server change - no code change in your app - you simply need to add the file extensions/MIME types and so on to your .htaccess file:




<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>



You'll immediately see your text files downloading more quickly. One additional addition to Gzip might be to exclude small files. Files under 850 bytes will fit into a single packet uncompressed anyway, so while the Gzip compression/decompression has very little overhead, you could still omit these steps for such small files.



Best Practice: Text File Compression



Android Network Optimization: Text File Minification (Minify JavaScript)

Another way to shrink the size of your text files is through the process of minification. Minification is a process that takes out all of the human-readable formatting to your text files (like whitespace, tabs, and comments) to make the files smaller.



Depending on the size and complexity of your page, minification can save up to 20%-50% of the file size. Many build tools (like grunt) include Minification libraries that can automatically minify your files whenever you make changes.



One might argue that using Gzip is enough to reduce the transmission costs of a text file. For example, minification might reduce the file size by 10%-15%, but the difference in Gzip savings for the minified versus not-minified file might only be 1%-2% (because whitespace compresses well).



However, you should always minify before Gzipping, not to save the 1%-2% of network transmission, but because it will offer storage savings on your customers' devices. In addition, reading a smaller file into memory is faster (and less likely to induce a crash on devices with limited memory).



While the Souders rule looks at only JavaScript for minification, this optimization can be run on any text file to reduce the file size. The ARO tool looks at all CSS, JavaScript, JSON, and HTML files for minification opportunities. It calculates the potential savings on each file, and provides a total savings for the files captured in the trace.



Android Network Optimization: Images

When it comes to apps, images are the most commonly downloaded file type. They are also among the largest files in size, and because images are everywhere, easily recycled from your web page or other digital service. Controlling image size is a fantastic way to reduce the data usage in your mobile app. There is a balance between image quality and image size that you must discover for your app (probably with the help of UX and editorial teams). Once you find that correct balance, you'll have a great-looking app with images that are optimized to download and render quickly.



If you create one version of every image in your app, and serve it to every mobile device (including the retina display tablets from that other mobile OS), you will likely want to use an image that looks great on all of those devices (meaning that the image downloaded will probably be pretty big). Now, imagine how long it will take to deliver an image sized for a Retina-enabled tablet to a small Android devices on a 2G network. This is probably not the user interaction you are looking for.



To account for all of the various screens sizes, you may want to create image buckets for your images, and whenever an image is needed, your app can provide the screen size to ensure that the correctly sized version of the image is delivered. Android has provided screen resolution buckets for app development, and these values are a good start for images on the network too.



If your app uses thumbnail images as well as full sized, you may want to consider delivering thumbnail sized images for images where the full-sized image might not be needed.



The actual sizes you may choose are very much app independent. You know from the layouts how large the images must be on the screen, so work out popular pixel sizes for the images based on small, medium phablet, and tablet screen sizes. From there, you can work out the correct image buckets for your app.



Metadata: When you take a photo with a digital camera, it is likely that there is metadata connected to the file (this can include information about the device, the settings on the device, and more recently, the location the photo was taken). Photo editing software may add additional metadata to the image. Unless your app is a photography app that discusses the way each photo was taken and how it was edited, you can strip out all of the image metadata to save anywhere from a few bytes to tens of kilobytes with no loss of image quality to your customers!



Compression: Just like with text files, you can compress images to make them smaller, take up less space on the device, and also take less time to download. Image compression is too large a subject to cover in detail here, but at a high level, when you compress images, you tend to lose image quality (lossy compression).



The amount of lossy compression applied to your images might depend on the use. For thumbnails, perhaps a higher compression is possible, as they tend to be small, and the "graininess" or pixelation is harder to see. For images inside an article, perhaps saving the JPEG at 70% compression will suffice. For apps focused on photography and graphics, you may decide to not do any lossy compression. The amount of compression is a delicate balance of optimizing the appearance of graphics versus size compression for speed. Google's PageSpeed server uses image compression of 85% by default, so this might be a good starting point for image comparisons.



Android Network Optimization: File Caching

If there are files that are used frequently in your app, you should download these files once and store the file locally for reuse. When it comes to performance, reading a file locally will always be faster than establishing a connection and downloading the file. For this performance reason alone, caching will speed up the rendering of your Android app. By avoiding network connections, you are saving capacity on your server, and you are reducing the battery drain of your customers.



Of course, the primary reason to invoke caching is that mobile data plans are constrained by data usage, and downloading excess content could end up costing your customers money if they exceed their monthly cap of data. There are two dimensions to caching: first, you must turn on caching in your app on the device, but then you must also properly set cache times on the server.



Interestingly, caching is off by default in Android, and you must turn it on, you enable the HTTP response cache by invoking in your onCreate:




private void enableHttpResponseCache() {
  try {
    long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
    File httpCacheDir = new File(getCacheDir(), "http");
    Class.forName("android.net.http.HttpResponseCache")
         .getMethod("install", File.class, long.class)
         .invoke(null, httpCacheDir, httpCacheSize);
  } catch (Exception httpResponseCacheNotAvailable) {
    Log.d(TAG, "HTTP response cache is unavailable.");
  }
}



And now your app will cache!



Caching on the Server: The cache time for each file saved on the device is set in the headers when delivered from the server. When setting up your caching parameters on the server, there are several important considerations that must be taken into account. Typically files are set to cache for a set amount of time, and if the file is requested again during that time period, it is served from the devices' cache. If the time has expired, a connection is made to the server to check if the file has changed. If the file has not changed, a HTTP 304 "not modified" response is sent to the device, and the cache timer reset. If the file is different, the new file is downloaded.



The length of the cache timer really depends on the content, and how often it changes (e.g., sports team logos that rarely change can be cached for a year, weather conditions for 5 minutes, and headline feeds might never cache). By modifying the cache time for your content, you ensure the data your customers see is always fresh, but also limit the number of files downloaded in a duplicate manner, saving battery and data. In general, there are three headers you can use to supply the expiration date of your content.



Cache Control (Add an Expires Header):



The header most frequently used for caching is the Cache-Control header, which has a few common values that you can assign:





ETags: The ETag is a response header with a unique string of random characters. Every time the file is to be used from the cache, the ETag must first be validated at the server. If the local string matches the server, the server replies with a "304 not modified," and the local file is used. If the ETags differ, the new file is downloaded and stored in the cache. Its behavior is the same as Cache-Control: no-cache, or max-age=0.



For files that regularly expire, ETags are a great way to validate that the locally cached file is still in sync with the server. For files that rarely change, ETags are an expensive (from a performance view) caching mechanism. While the file is not downloaded (thus saving bandwidth), a connection is still established, adding connection time to the file processing.



Expires: Less common than Cache-Control or ETag (but just as valid) is the Expires header. Rather than giving the time in seconds that the file expires, it gives an exact date in the future when the file will expire and should be revalidated. This was original cache header used in the web, and some ancient browsers may still use it. The Expires header should match the Cache-Control: max-age. In the preceding example, this is the case: the Expires header is exactly one day after the file is served.



Do you download content on the first startup of your app, and then cache them for a long time? Remember that your initial startup is almost your make or break point for customer satisfaction. If the first time your app starts up, it takes a long time to configure (as you are downloading images and files), your customers might stop using your app after one visit. Consider placing these images and icons into the resources file of your app. Sure, it makes the app download a bit larger, but this one time download cost will speed up that first startup. And, if you change the logos, icons, etc., all you need to do is issue an update to the app.



To discover if your app is correctly caching, you can use ARO. There are three best practices that help you determine any issues with caching files: duplicate content, cache control, and content expiration. The Cache Control and Content Expiration Best Practices in ARO serve as warnings for potential caching issues on the server or on the device (respectively).



The ARO Cache Control best practice is looking for the presence of a Cache-Control/ETag or Expires header. If no such header is inserted by the server, it throws a warning: "this is where your caching policy might be failing!" There are valid times for this to fail. Perhaps you have a file that you don't want to cache, so you leave out the headers. It is important to note that the HTTP cache spec says if the file says nothing, it can be cached for 24 hours. If you do not want the file cached, make sure you say so explicitly to avoid any future literal reading of the spec!



ARO's Content Expiration best practice is looking to make sure that your app's cache is working correctly. It counts the number of 304 not modified server checks, as well as the number of times the cache header is ignored, and the file is requested from the server (as the file should be in the cache). Typically this flashes a warning on apps whose cache is not configured (or configured correctly) on the device.



If your app is downloading content in a duplicate manner, take a close look to ensure that the headers are populated properly (server fix), and that your app is storing the files correctly in its cache (application fix).



Android Network Optimization: Beyond Files

Optimizing the files that you download is crucial. Smaller, leaner files will always lead to a faster download, and zippier performance. However, now you also know about how cellular latency and "RRC State Machine" can affect download speed and battery drain. Assuming all of your files are now optimized, let's make sure that the processes you use to connect your app and server to get these files are running as efficiently as possible, working with the state machine to maximize performance and customer satisfaction.



Android Network Optimization: Grouping Connections

Imagine an ad-supported image sharing app. Intuitively, we know that connections serving images will consume a lot of bandwidth, and connect to the network frequently. Do you know how the ad SDK will behave? Do the ads load with your images, or do these connections occur when the radio would be otherwise silent? How about your analytics data? Do these connections fire at the same time as your app? Or do they wake up the radio whenever they want to?



As you might imagine, many of these tools are built to just connect. If you use more than one analytics provider (or ad service) in addition to other libraries and connections, your app might never let the radio go to sleep, due to all of the services connecting whenever they want to. If you are looking to ensure that your app is as efficient as possible, it makes sense to organize your connections into as few large buckets as possible (versus many small buckets). Look into the documentation and code for these SDKs, and see if you might be able to sync them with other connections from your app. If you test, and see that your third-party SDKs are not behaving as nicely as they should be, reach out to the developers. Odds are they too are unaware of the way their libraries behave, and would be interested to improve their libraries' network behavior.



Regular Connections: Because every connection to your server keeps the radio on due to the RRC state machine, it is crucial to minimize the connections that occur in your app (especially those that occur in the background) to not only preserve the battery life, but also the data plan of your customers. In 2013, my team worked with a popular social media app to reduce the number of connections that the Android app made in the background. In this early version of the app, we saw three connections running in an uncoordinated way in the background. Every 30 minutes, these three connections turned on the radio seven times.



When the developers saw this, they realized that by simply coordinating these connections (and making sure to close them properly), they could greatly reduce the background battery drain of their app. The bottom trace shows the improvement. The "updated" version of the app pushed all three connections into one transaction time, and the developers doubled the refresh rate to every 15 minutes. Now, with two connections every 30 minutes, the data is being updated twice as often, but the battery drain actually decreased by >50%. Assuming that these connections occurred 24 hours a day, we estimate that this actually saved ~5% of battery usage for every customer with this app installed!



Not all developers have the time to build their own transaction managers, but the Android developers have been listening. In "JobScheduler", we looked at the JobScheduler API, which was introduced in Lollipop, and the examples showed how letting the OS handle periodic connections reduced what could have been 20 connections to a mere 9! By adding the flexibility of the JobScheduler API to download non-crucial elements in a more flexible manner, and by placing a fallback mechanism on background connections, your radio usage will decrease dramatically, improving the performance of your app while simultaneously using less battery (a win-win for you and your customers)!



Android Network Optimization: Detecting Radio Usage in Your App

To determine if your customer's device is connected to Wi-Fi or cellular, you can query the connectivity manager, as shown in:




public static String getNetworkClass(Context context) {
    ConnectivityManager cm = (ConnectivityManager)
                             context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = cm.getActiveNetworkInfo();
    if(info==null || !info.isConnected())
        return "-"; //not connected
    if(info.getType() == ConnectivityManager.TYPE_WIFI)
        return "wifi";
    if(info.getType() == ConnectivityManager.TYPE_MOBILE){
	 return "cellular";
         }
    }
    return "unknown";
}
    


With this snippet of data, you now know what sort of connection is in use, and you can customize the data stream for the two network types. If your users are on cellular, you might have non-urgent communications that you can delay transmission. Prior to the Job Scheduler in Android Lollipop, there was no way to tell if the network was being used. To force analytics and ads to only load when the cellular radio was already in use, the used the code shown in the follows:




if (Tel.getDataActivity() >0){

           if (Tel.getDataActivity() <4){

           //1, 2, 3 response means that the cellular radio is transmitting!
           //download the image here using image getter
            imagegetter(counter, numberofimages);

            //and show the ad
            AdRequest adRequest = new AdRequest();
            adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
            adView.loadAd(adRequest);
            // Initiate a generic request to load it with an ad
            adView.loadAd(new AdRequest());
}}



This code snippet uses the TelephonyManager (Tel) data activity APIs to determine if the radio is on, and if it is on, piggybacks on the connection to download more content. This will only indicate if data transmission is occurring on the cellular network (not on Wi-Fi). In Lollipop, new APIs were added to ConnectivityManager abstracts this method from just cellular to all radio connections with ConnectivityManager.OnNetworkActiveListener to find out when the radio is in a high-powered state (and ready to transmit data). To see if a network is already active, you can use ConnectivityManager.isDefaultNetworkActive(). Using a radio connection that is already established is a great way to share the resources, and save customer battery.



GCM Network Manager: Google and Android made scheduling battery efficient network connections even easier. As a part of Google Play Services, they added GCM Network Manager APIs that mimic the JobSchedule API for connectivity. However, JobScheduler only runs on devices using Lollipop and newer, while the GCM Network Manager runs on all Google Android devices back to Gingerbread! Now, just like in JobScheduler, you can easily set your connections to only run when on Wi-Fi, or when the device is plugged in. You can set tasks to run periodically in the background, or to automatically back off. By utilizing this API for your non-urgent updates and connections, you will directly save a large amount of device battery for your customers.



Android Network Optimization: All Good Things Must Come to An End: Closing Connections

With the latency to establish radio and TCP connections on cellular, you might think it sensible to just keep a TCP connections to your server open. That way, if more packets need to be sent to the device, you can reduce some of the latency on connection setup. This is the case for files sent in relatively rapid succession. But if the files are separated by 15 s or more, the radio will likely still have to be turned on, and you'll save very little time on the connection setup.



If connections are left open with no data traffic for a period of time, either the device or the server closes the connection as a cleanup process. This is also not a bad thing (as you'll see in the next section). However, what is negative about this is that the side closing the connection will tell the other party "Hey, I am closing this connection now" and this can lead to the radio turning on, and running through the 10-15 s RRC state machine on the device, causing extra battery drain for your customers.



For connections where you know that you will not be needing the connection any longer, you can specify that the connection should be closed when you are completed with the download.



When this code is implemented, the image is downloaded, and the server and the device immediately closes the connection.



Android Network Optimization: Regular Repeated Pings

For apps that require data updates at regular intervals, tools like Google Cloud Messenger should be used to push this information down to the app. Building your own service often results in polling in the background by setting an alarm for every x minutes, then waking up the radio and downloading your data. This does not seem like a big deal, but imagine an app that pings the server for updates every 3 minutes. Extrapolate this out—your app will make 480 connections every 24 hours. Throw in a 10 second state machine timer, and now these "harmless" connections are using 80 minutes of radio time per day. If you must have a regular wakeup for data, make sure that you have a fallback procedure, or disable the alarm after a certain amount of time to keep your app (and the device) asleep.



There are cases (think real-time games) where the app may need to keep packets going back and forth on a connection. Make sure you are minimizing the data being sent, but also know that keeping the radio connection on while your app is running can cause major battery drain.



Android Network Optimization: Security in Networking (HTTP versus HTTPS)

When transporting data over the network, it is imperative that you keep your customers' private data secure. It seems that not a week goes by without a serious breach of private information from a mobile app. Properly storing the files locally on the device and on your servers is crucial, but so is transporting those files back and forth across the network. Your customers may connect to any sort of network, including compromised Wi-Fi hotspots in cafes. If the data you transmit is sent via HTTP, the snooper can get that data with no effort at all—you sent it in cleartext! By using HTTPS, you encrypt the data using an encrypted key. Sharing this key can result in an additional roundtrip when the connection is initialized, but assuming that you have correctly configured your HTTPS connection, it is considered secure.



Android Network Optimization: Further Reading



Big Discounts for Domains, Hosting, SSL and more