Category Archives: Performance

Tips And Tools For Optimizing Android Apps


Android devices have a lot of cores, so writing smooth apps is a simple task for anyone, right? Wrong. As everything on Android can be done in a lot of different ways, picking the best option can be tough. If you want to choose the most efficient method, you have to know what’s happening under the hood. Luckily, you don’t have to rely on your feelings or sense of smell, since there’s a lot of tools out there that can help you find bottlenecks by measuring and describing what’s going on. Properly optimized and smooth apps greatly improve the user experience, and also drain less battery.

Let’s see some numbers first to consider how important optimization really is. According to a Nimbledroid post, 86% of users (including me) have uninstalled apps after using them only once due to poor performance. If you’re loading some content, you have less than 11 seconds to show it to the user. Only every third user will give you more time. You might also get a lot of bad reviews on Google Play because of it.

Build Better Apps: Android Performance Patterns

Testing your users’ patience is a shortcut to uninstallation.

The first thing every user notices over and over is the app’s startup time. According to another Nimbledroid post, out of the 100 top apps, 40 start in under 2 seconds, and 70 start in under 3 seconds. So if possible, you should generally display some content as soon as possible and delay the background checks and updates a bit.

Always remember, premature optimization is the root of all evil. You should also not waste too much time with micro optimization. You will see the most benefit of optimizing code that runs often. For example, this includes the onDraw() function, which runs every frame, ideally 60 times per second. Drawing is the slowest operation out there, so try redrawing only what you have to. More about this will come later.

Performance Tips

Enough theory, here is a list of some of the things you should consider if performance matters to you.

1. String vs StringBuilder

Let’s say that you have a String, and for some reason you want to append more Strings to it 10 thousand times. The code could look something like this.

String string = "hello";
for (int i = 0; i < 10000; i++) {
    string += " world";
}

You can see on the Android Studio Monitors how inefficient some String concatenation can be. There’s tons of Garbage Collections (GC) going on.

String vs StringBuilder

This operation takes around 8 seconds on my fairly good device, which has Android 5.1.1. The more efficient way of achieving the same goal is using a StringBuilder, like this.

StringBuilder sb = new StringBuilder("hello");
for (int i = 0; i < 10000; i++) {
    sb.append(" world");
}
String string = sb.toString();

On the same device this happens almost instantly, in less than 5ms. The CPU and Memory visualizations are almost totally flat, so you can imagine how big this improvement is. Notice though, that for achieving this difference, we had to append 10 thousand Strings, which you probably don’t do often. So in case you are adding just a couple Strings once, you will not see any improvement. By the way, if you do:

String string = "hello" + " world";

It gets internally converted to a StringBuilder, so it will work just fine.

You might be wondering, why is concatenating Strings the first way so slow? It is caused by the fact that Strings are immutable, so once they are created, they cannot be changed. Even if you think you are changing the value of a String, you are actually creating a new String with the new value. In an example like:

String myString = "hello";
myString += " world";

What you will get in memory is not 1 String “hello world”, but actually 2 Strings. The String myString will contain “hello world”, as you would expect. However, the original String with the value “hello” is still alive, without any reference to it, waiting to be garbage collected. This is also the reason why you should store passwords in a char array instead of a String. If you store a password as a String, it will stay in the memory in human-readable format until the next GC for an unpredictable length of time. Back to the immutability described above, the String will stay in the memory even if you assign it another value after using it. If you, however, empty the char array after using the password, it will disappear from everywhere.

2. Picking the Correct Data Type

Before you start writing code, you should decide what data types you will use for your collection. For example, should you use a Vector or an ArrayList? Well, it depends on your usecase. If you need a thread-safe collection, which will allow only one thread at once to work with it, you should pick a Vector, as it is synchronized. In other cases you should probably stick to an ArrayList, unless you really have a specific reason to use vectors.

How about the case when you want a collection with unique objects? Well, you should probably pick a Set. They cannot contain duplicates by design, so you will not have to take care of it yourself. There are multiple types of sets, so pick one that fits your use case. For a simple group of unique items, you can use a HashSet. If you want to preserve the order of items in which they were inserted, pick a LinkedHashSet. A TreeSet sorts items automatically, so you will not have to call any sorting methods on it. It should also sort the items efficiently, without you having to think of sorting algorithms.

Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
— Rob Pike’s 5 Rules of Programming

Sorting integers or strings is pretty straightforward. However, what if you want to sort a class by some property? Let’s say you are writing a list of meals you eat, and store their names and timestamps. How would you sort the meals by timestamp from the lowest to highest? Luckily, it’s pretty simple. It’s enough to implement the Comparable interface in the Meal class and override the compareTo() function. To sort the meals by lowest timestamp to highest, we could write something like this.

@Override
public int compareTo(Object object) {
    Meal meal = (Meal) object;
    if (this.timestamp < meal.getTimestamp()) {
        return -1;
    } else if (this.timestamp > meal.getTimestamp()) {
        return 1;
    }
    return 0;
}

3. Location Updates

There are a lot of apps out there which collect the user’s location. You should use the Google Location Services API for that purpose, which contains a lot of useful functions. There is a separate article about using it, so I will not repeat it.

I’d just like to stress some important points from a performance perspective.

First of all, use only the most precise location as you need. For example, if you are doing some weather forecasting, you don’t need the most accurate location. Getting just a very rough area based on the network is faster, and more battery efficient. You can achieve it by setting the priority to LocationRequest.PRIORITY_LOW_POWER.

You can also use a function of LocationRequest called setSmallestDisplacement(). Setting this in meters will cause your app to not be notified about location change if it was smaller than the given value. For example, if you have a map with nearby restaurants around you, and you set the smallest displacement to 20 meters, the app will not be making requests for checking restaurants if the user is just walking around in a room. The requests would be useless, as there wouldn’t be any new nearby restaurant anyway.

The second rule is requesting location updates only as often as you need them. This is quite self explanatory. If you are really building that weather forecast app, you do not need to request the location every few seconds, as you probably don’t have such precise forecasts (contact me if you do). You can use the setInterval() function for setting the required interval in which the device will be updating your app about the location. If multiple apps keep requesting the user’s location, every app will be notified at every new location update, even if you have a higher setInterval() set. To prevent your app from being notified too often, make sure to always set a fastest update interval with setFastestInterval().

And finally, the third rule is requesting location updates only if you need them. If you are displaying some nearby objects on the map every x seconds and the app goes in background, you do not need to know the new location. There is no reason to update the map if the user cannot see it anyway. Make sure to stop listening for location updates when appropriate, preferably in onPause(). You can then resume the updates in onResume().

4. Network Requests

There is a high chance that your app is using the internet for downloading or uploading data. If it is, you have several reasons to pay attention to handling network requests. One of them is mobile data, which is very limited to a lot of people and you shouldn’t waste it.

The second one is battery. Both WiFi and mobile networks can consume quite a lot of it if they are used too much. Let’s say that you want to download 1 kb. To make a network request, you have to wake up the cellular or WiFi radio, then you can download your data. However, the radio will not fall asleep immediately after the operation. It will stay in a fairly active state for about 20-40 more seconds, depending on your device and carrier.

Network Requests

So, what can you do about it? Batch. To avoid waking up the radio every couple seconds, prefetch things that the user might need in the upcoming minutes. The proper way of batching is highly dynamic depending on your app, but if it is possible, you should download the data the user might need in the next 3-4 minutes. One could also edit the batch parameters based on the user’s internet type, or charging state. For example, if the user is on WiFi while charging, you can prefetch a lot more data than if the user is on mobile internet with low battery. Taking all these variables into account can be a tough thing, which only few people would do. Luckily though, there is GCM Network Manager to the rescue!

GCM Network Manager is a really helpful class with a lot of customizable attributes. You can easily schedule both repeating and one-off tasks. At repeating tasks you can set the lowest, as well as the highest repeat interval. This will allow batching not only your requests, but also requests from other apps. The radio has to be woken up only once per some period, and while it’s up, all apps in the queue download and upload what they are supposed to. This Manager is also aware of the device’s network type and charging state, so you can adjust accordingly. You can find more details and samples in this article, I urge you to check it out. An example task looks like this:

Task task = new OneoffTask.Builder()
    .setService(CustomService.class)
    .setExecutionWindow(0, 30)
    .setTag(LogService.TAG_TASK_ONEOFF_LOG)
    .setUpdateCurrent(false)
    .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
    .setRequiresCharging(false)
    .build();

By the way, since Android 3.0, if you do a network request on the main thread, you will get a NetworkOnMainThreadException. That will definitely warn you not to do that again.

5. Reflection

Reflection is the ability of classes and objects to examine their own constructors, fields, methods, and so on. It is used usually for backward compatibility, to check if a given method is available for a particular OS version. If you have to use reflection for that purpose, make sure to cache the response, as using reflection is pretty slow. Some widely used libraries use Reflection too, like Roboguice for dependency injection. That’s the reason why you should prefer Dagger 2. For more details about reflection, you can check a separate post.

6. Autoboxing

Autoboxing and unboxing are processes of converting a primitive type to an Object type, or vice versa. In practice it means converting an int to an Integer. For achieving that, the compiler uses the Integer.valueOf()function internally. Converting is not just slow, Objects also take a lot more memory than their primitive equivalents. Let’s look at some code.

Integer total = 0;
for (int i = 0; i < 1000000; i++) {
    total += i;
}

While this takes 500ms on average, rewriting it to avoid autoboxing will speed it up drastically.

int total = 0;
for (int i = 0; i < 1000000; i++) {
    total += i;
}

This solution runs at around 2ms, which is 25 times faster. If you don’t believe me, test it out. The numbers will be obviously different per device, but it should still be a lot faster. And it’s also a really simple step to optimize.

Okay, you probably don’t create a variable of type Integer like this often. But what about the cases when it is more difficult to avoid? Like in a map, where you have to use Objects, like Map<Integer, Integer>? Look at the solution many people use.

Map<Integer, Integer> myMap = new HashMap<>();
for (int i = 0; i < 100000; i++) {
    myMap.put(i, random.nextInt());
}

Inserting 100k random ints in the map takes around 250ms to run. Now look at the solution with SparseIntArray.

SparseIntArray myArray = new SparseIntArray();
for (int i = 0; i < 100000; i++) {
    myArray.put(i, random.nextInt());
}

This takes a lot less, roughly 50ms. It’s also one of the easier methods for improving performance, as nothing complicated has to be done, and the code also stays readable. While running a clear app with the first solution took 13MB of my memory, using primitive ints took something under 7MB, so just the half of it.

SparseIntArray is just one of the cool collections that can help you avoid autoboxing. A map like Map<Integer, Long> could be replaced by SparseLongArray, as the value of the map is of type Long. If you look at the source code of SparseLongArray, you will see something pretty interesting. Under the hood, it is basically just a pair of arrays. You can also use a SparseBooleanArray similarly.

If you read the source code, you might have noticed a note saying that SparseIntArray can be slower than HashMap. I’ve been experimenting a lot, but for me SparseIntArray was always better both memory and performance wise. I guess it’s still up to you which you choose, experiment with your use cases and see which fits you the most. Definitely have the SparseArrays in your head when using maps.

7. OnDraw

As I’ve said above, when you are optimizing performance, you will probably see the most benefit in optimizing code which runs often. One of the functions running a lot is onDraw(). It may not surprise you that it’s responsible for drawing views on the screen. As the devices usually run at 60 fps, the function is run 60 times per second. Every frame has 16 ms to be fully handled, including its preparation and drawing, so you should really avoid slow functions. Only the main thread can draw on the screen, so you should avoid doing expensive operations on it. If you freeze the main thread for several seconds, you might get the infamous Application Not Responding (ANR) dialog. For resizing images, database work, etc., use a background thread.

If you think your users won’t notice that drop in frame rate, you are wrong!

I’ve seen some people trying to shorten their code, thinking that it will be more efficient that way. That definitely isn’t the way to go, as shorter code totally doesn’t mean faster code. Under no circumstances should you measure the quality of code by the number of lines.

One of the things you should avoid in onDraw() is allocating objects like Paint. Prepare everything in the constructor, so it’s ready when drawing. Even if you have onDraw() optimized, you should call it only as often as you have to. What is better than calling an optimized function? Well, not calling any function at all. In case you want to draw text, there is a pretty neat helper function called drawText(), where you can specify things like the text, coordinates, and the text color.

8. ViewHolders

You probably know this one, but I cannot skip it. The Viewholder design pattern is a way of making scrolling lists smoother. It is a kind of view caching, which can seriously reduce the calls to findViewById() and inflating views by storing them. It can look something like this.

static class ViewHolder {
    TextView title;
    TextView text;

    public ViewHolder(View view) {
        title = (TextView) view.findViewById(R.id.title);
        text = (TextView) view.findViewById(R.id.text);
    }
}

Then, inside the getView() function of your adapter, you can check if you have a useable view. If not, you create one.

ViewHolder viewHolder;
if (convertView == null) {
    convertView = inflater.inflate(R.layout.list_item, viewGroup, false);
    viewHolder = new ViewHolder(convertView);
    convertView.setTag(viewHolder);
} else {
    viewHolder = (ViewHolder) convertView.getTag();
}

viewHolder.title.setText("Hello World");

You can find a lot of useable info about this pattern around the internet. It can also be used in cases when your list view has multiple different types of elements in it, like some section headers.

9. Resizing Images

Chances are, your app will contain some images. In case you are downloading some JPGs from the web, they can have really huge resolutions. However, the devices they will be displayed on will be a lot smaller. Even if you take a photo with the camera of your device, it needs to be downsized before displaying as the photo resolution is a lot bigger than the resolution of the display. Resizing images before displaying them is a crucial thing. If you’d try displaying them in full resolutions, you’d run out of memory pretty quickly. There is a whole lot written about displaying bitmaps efficiently in the Android docs, I will try summing it up.

So you have a bitmap, but you don’t know anything about it. There’s a useful flag of Bitmaps called inJustDecodeBounds at your service, which allows you to find out the bitmap’s resolution. Let’s assume that your bitmap is 1024×768, and the ImageView used for displaying it is just 400×300. You should keep dividing the bitmap’s resolution by 2 until it’s still bigger than the given ImageView. If you do, it will downsample the bitmap by a factor of 2, giving you a bitmap of 512×384. The downsampled bitmap uses 4x less memory, which will help you a lot with avoiding the famous OutOfMemory error.

Now that you know how to do it, you should not do it. … At least, not if your app relies on images heavily, and it’s not just 1-2 images. Definitely avoid stuff like resizing and recycling images manually, use some third party libraries for that. The most popular ones are Picasso by Square, Universal Image Loader, Fresco by Facebook, or my favourite, Glide. There is a huge active community of developers around it, so you can find a lot of helpful people at the issues section on GitHub as well.

10. Strict Mode

Strict Mode is a quite useful developer tool that many people don’t know about. It’s usually used for detecting network requests or disk accesses from the main thread. You can set what issues Strict Mode should look for and what penalty it should trigger. A google sample looks like this:

public void onCreate() {
    if (DEVELOPER_MODE) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectDiskWrites()
                .detectNetwork()
                .penaltyLog()
                .build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                .detectLeakedSqlLiteObjects()
                .detectLeakedClosableObjects()
                .penaltyLog()
                .penaltyDeath()
                .build());
    }
    super.onCreate();
}

If you want to detect every issue Strict Mode can find, you can also use detectAll(). As with many performance tips, you should not blindly try fixing everything Strict Mode reports. Just investigate it, and if you are sure it’s not an issue, leave it alone. Also make sure to use Strict Mode only for debugging, and always have it disabled on production builds.

Debugging Performance: The Pro Way

Let’s now see some tools that can help you find bottlenecks, or at least show that something is wrong.

1. Android Monitor

This is a tool built into Android Studio. By default, you can find the Android Monitor at the bottom left corner, and you can switch between 2 tabs there. Logcat and Monitors. The Monitors section contains 4 different graphs. Network, CPU, GPU, and Memory. They are pretty self explanatory, so I will just quickly go through them. Here is a screenshot of the graphs taken while parsing some JSON as it is downloaded.

Android Monitor

The Network part shows the incoming and outgoing traffic in KB/s. The CPU part displays the CPU usage in percent. The GPU monitor displays how much time it takes to render the frames of a UI window. This is the most detailed monitor out of these 4, so if you want more details about it, read this.

Lastly we have the Memory monitor, which you will probably use the most. By default it shows the current amount of Free and Allocated memory. You can force a Garbage Collection with it too, to test if the amount of used memory drops down. It has a useful feature called Dump Java Heap, which will create a HPROF file which can be opened with the HPROF Viewer and Analyzer. That will enable you to see how many objects you have allocated, how much memory is taken by what, and maybe which objects are causing memory leaks. Learning how to use this analyzer is not the simplest task out there, but it is worth it. The next thing you can do with the Memory Monitor is do some timed Allocation Tracking, which you can start and stop as you wish. It could be useful at many cases, for example when scrolling or rotating the device.

2. GPU Overdraw

This is a simple helper tool, which you can activate in Developer Options once you have enabled developer mode. Select Debug GPU overdraw, “Show overdraw areas”, and your screen will get some weird colors. It’s ok, that’s what is supposed to happen. The colors mean how many times a particular area was overdrawn. True color means that there was no overdraw, this is what you should aim for. Blue means one overdraw, green means two, pink three, red four.

GPU Overdraw

While seeing true color is the best, you will always see some overdraws, especially around texts, navigation drawers, dialogs and more. So don’t try getting rid of it fully. If your app is blueish or greenish, that’s probably fine. However, if you see too much red on some simple screens, you should investigate what’s going on. It might be too many fragments stacked onto each other, if you keep adding them instead of replacing. As I’ve mentioned above, drawing is the slowest part of apps, so there is no sense drawing something if there will be more than 3 layers drawn onto it. Feel free to check out your favourite apps with it. You will see that even apps with over a billion downloads have red areas, so just take it easy when you are trying to optimize.

3. GPU Rendering

This is another tool from the Developer options, called Profile GPU rendering. Upon selecting it, pick “On screen as bars”. You will notice some colored bars appearing on your screen. Since every application has separate bars, weirdly the status bar has its own ones, and in case you have software navigation buttons, they have their own bars too. Anyway, the bars get updated as you interact with the screen.

GPU Rendering

The bars consist of 3-4 colors, and according to the Android docs, their size indeed matters. The smaller, the better. At the bottom you have blue, which represents the time used to create and update the View’s display lists. If this part is too tall, it means that there is a lot of custom view drawing, or a lot of work done in the onDraw() functions. If you have Android 4.0+, you will see a purple bar above the blue one. This represents the time spent transferring resources to the render thread. Then comes the red part, which represents the time spent by Android’s 2D renderer issuing commands to OpenGL to draw and redraw display lists. At the top is the orange bar, which represents the time the CPU is waiting for the GPU to finish its work. If it’s too tall, the app is doing too much work on the GPU.

If you are good enough, there is one more color above the orange. It is a green line representing the 16 ms threshold. As your goal should be running your app at 60 fps, you have 16 ms to draw every frame. If you don’t make it, some frames might be skipped, the app could become jerky, and the user would definitely notice. Pay special attention to animations and scrolling, that’s where the smoothness matters the most. Even though you can detect some skipped frames with this tool, it won’t really help you figuring out where exactly the problem is.

4. Hierarchy Viewer

This is one of my favourite tools out there, as it’s really powerful. You can start it from Android Studio through Tools -> Android -> Android Device Monitor, or it is also in your sdk/tools folder as “monitor”. You can also find a standalone hierarachyviewer executable there, but as it’s deprecated you should open the monitor. However you open the Android Device Monitor, switch to the Hierarchy Viewer perspective. If you don’t see any running apps assigned to your device, there are a couple things you can do to fix it. Also try checking outthis issue thread, there are people with all kinds of issues and all kinds of solutions. Something should work for you too.

With Hierarchy Viewer, you can get a really neat overview of your view hierarchies (obviously). If you see every layout in a separate XML, you might easily spot useless views. However, if you keep combining the layouts, it can easily get confusing. A tool like this makes it simple to spot, for example, some RelativeLayout, which has just 1 child, another RelativeLayout. That makes one of them removable.

Avoid calling requestLayout(), as it causes traversing of the entire view hierarchy, to find out how big each view should be. If there is some conflict with the measurements, the hierarchy might be traversed multiple times, which if happens during some animation, it will definitely make some frames be skipped. If you want to find out more about how Android draws its views, you can read this. Let’s look at one view as seen in Hierarchy Viewer.

The top right corner contains a button for maximizing the preview of the particular view in a standalone window. Under it you can also see the actual preview of the view in the app. The next item is a number, which represents how many children the given view has, including the view itself. If you select a node (preferably the root one) and press “Obtain layout times” (3 colored circles), you will have 3 more values filled, together with colored circles appearing labelled measure, layout, and draw. It might not be shocking that the measure phase represents the time it took to measure the given view. The layout phase is about the rendering time, while the drawing is the actual drawing operation. These values and colors are relative to each other. Green one means that the view renders in the top 50% of all views in the tree. Yellow means rendering in the slower 50% of all views in the tree, red means that the given view is one of the slowest. As these values are relative, there will always be red ones. You simply cannot avoid them.

Under the values you have the class name, such as “TextView”, an internal view ID of the object, and the android:id of the view, which you set in the XML files. I urge you to build a habit of adding IDs to all views, even if you don’t reference them in the code. It will make identifying the views in Hierarchy Viewer really simple, and in case you have automated tests in your project, it will also make targeting the elements a lot faster. That will save some time for you and your colleagues writing them. Adding IDs to elements added in XML files is pretty straightforward. But what about the dynamically added elements? Well, it turns out to be really simple too. Just create an ids.xml file inside your values folder and type in the required fields. It can look like this:

<resources>
    <item name="item_title" type="id"/>
    <item name="item_body" type="id"/>
</resources>

Then in the code, you can use setId(R.id.item_title). It couldn’t be simpler.

There are a couple more things to pay attention to when optimizing UI. You should generally avoid deep hierarchies while preferring shallow, maybe wide ones. Do not use layouts you don’t need. For example, you can probably replace a group of nested LinearLayouts with either a RelativeLayout, or a TableLayout. Feel free to experiment with different layouts, don’t just always use LinearLayout and RelativeLayout. Also try creating some custom views when needed, it can improve the performance significantly if done well. For instance, did you know that Instagram doesn’t use TextViews for displaying comments?

You can find some more info about Hierarchy Viewer on the Android Developers site with descriptions of different panes, using the Pixel Perfect tool, etc. One more thing I would point out is capturing the views in a .psd file, which can be done by the “Capture the window layers” button. Every view will be in a separate layer, so it’s really simple to hide or change it in Photoshop or GIMP. Oh, that’s another reason to add an ID to every view you can. It will make the layers have names that actually make sense.

You will find a lot more debugging tools in Developer options, so I advise you to activate them and see what are they doing. What could possibly go wrong?

The Android developers site contains a set of best practices for performance. They cover a lot of different areas, including memory management, which I haven’t really talked about. I silently ignored it, because handling memory and tracking memory leaks is a whole separate story. Using a third party library for efficiently displaying images will help a lot, but if you still have memory issues, check out Leak canary made by Square, or read this.

Wrapping Up

So, this was the good news. The bad new is, optimizing Android apps is a lot more complicated. There are a lot of ways of doing everything, so you should be familiar with the pros and cons of them. There usually isn’t any silver bullet solution which has only benefits. Only by understanding what’s happening behind the scenes will you be able to pick the solution which is best for you. Just because your favorite developer says that something is good, it doesn’t necessarily mean that it’s the best solution for you. There are a lot more areas to discuss and more profiling tools which are more advanced, so we might get to them next time.

Make sure you learn from the top developers and top companies. You can find a couple hundred engineering blogs at this link. It’s obviously not just Android related stuff, so if you are interested only in Android, you have to filter the particular blog. I would highly recommend the blogs of Facebook and Instagram. Even though the Instagram UI on Android is questionable, their engineering blog has some really cool articles. For me it’s awesome that it’s so easy to see how things are done in companies which are handling hundreds of millions of users daily, so not reading their blogs seems crazy. The world is changing really fast, so if you aren’t constantly trying to improve, learn from others and use new tools, you will be left behind. As Mark Twain said, a person who doesn’t read has no advantage over one who can’t read.

This article was written by Tibor Kaputa, a Toptal Java developer.

Who Knew Adobe CC Could Wireframe?


Wireframing is a major step in designing any user interface whether a website, application or software product. Without distraction in the form of visuals, colours, typography, styles and effects you can be more focused on defining content hierarchy and user experience.

Doing low fidelity wireframes and prototypes will help you test and iterate more often and in earlier phases, work faster and develop products that your users will love.

There are a lot of different wireframing tools to choose from in the wild. Which one you choose will depend on your personal preferences and workflow style.

Just like a lot of designers moving to digital design from the print world, I’m an expert in the Adobe applications like Illustrator, InDesign, and Photoshop. I can use them efficiently, everywhere and at any time (even if someone wakes me up in the middle of the night and refuses to give me a cup of coffee). However, these have also become the tools I use to do web and application visual design. So, for my workflow to be the most efficient I use them for wireframing too.

Who knew Adobe CC Could Wireframe

With every project, I usually start designing by doing very rough sketches on paper, or lately more often, if not near my office desk, on my iPad or smartphone screen. These sketches are there only to focus my thoughts regarding the chosen concept and the client will probably never see any of them. When I feel confident enough that my idea works, I jump right away into wireframing. I usually use Adobe Illustrator and InDesign combined. Illustrator for creating most of the UI kit elements and InDesign for wireframing itself.

In this article, I’ll explain a step by step process of how to incorporate those tools into your wireframing workflow as well. But, before I go into details, let me show you what the strengths and weaknesses are of using InDesign as a primary wireframing tool.

The Pros and Cons of Using Adobe InDesign as a Wireframe and Prototyping Tool

For some time now Adobe InDesign has been not only a desktop publishing application, but it’s also widely used for digital publishing and EPUB creation, and there are also some reasons why it is a suitable tool for wireframing too:

  • Master pages – You can quickly and consistently apply global design elements like navigation, headers, footers and so on. You can create as many master pages as you need, and on top of it, one master can be based on another.
  • Solid grid support – Allows you to create easily and apply different kinds of grids, complementing columns, horizontal and vertical guides to create modules, and subgrids for greater complexity and precision.
  • Alternate layouts – Enables wireframes for multiple devices and orientations in the same file.
  • CC Libraries – Give easy access and reuse different assets like commonly used objects, colours, character and paragraph styles. Create assets in InDesign, Illustrator, Photoshop or with the Adobe Capture mobile app, whichever you prefer.
  • Layers – Provide you the ability to organize, group, show/hide and lock/unlock objects and content selectively in the wireframe. Every page of a multi-page InDesign document has the same number and order of layers. All of the changes you make to layers are reflected on all pages, like visibility, stacking order or deletion.
  • Styles and tables – Give complete control over the look of your text, objects and tables through the use of InDesign styles. Styles can be based on each other providing the ability to cascade desired formatting easily throughout the document. Creation and formatting of tables that you can use as wireframe content elements or even helpers for layout purpose is very simple.
  • Typekit integration – In high fidelity mock-ups, you can use any of the Typekit fonts that sync to the desktop.
  • Interactivity and animations – You can use Adobe InDesign built-in interactivity and animation features to create different states of the web or application design for interaction. Most people use these features while creating magazines for Digital Publishing Solution and fixed layout EPUB export but they can be suited for prototyping as well.
  • Export options – InDesign can export the wireframes and prototypes you create in a variety of formats. Interactive PDF will probably be your format of choice in the majority of cases, but you can also use quite new Publish Online Feature to convert your document to interactive HTML that can be viewed in modern desktop and mobile browsers. Unfortunately, you don’t have any control over the export using Publish Online, and exported file is hosted on Adobe servers. You can share the prototype URL to your client, or embed it into your site. For more control and direct export to HTML5 you can use the in5 extension from Ajar Productions.

Adobe InDesign has many pros to be used as a wireframe and prototyping tool, but it also has some disadvantages:

  • Lack of predefined wireframe templates and elements – Since InDesign is not meant to be a wireframing tool, you have to create and prepare templates and object assets by yourself. (I’ll show you how to make that preparation step later in this article.) The good news is that most of this work will be done only once and after a few hours of work you’ll be ready to jump start your InDesign wireframing. Also, there are a lot of assets and wireframe kits that you can download from the internet, so there is no need to draw everything yourself.
  • Interactivity and animation features are limited and can be time-consuming – Although you can easily connect pages and add some interactivity and animations that process sometimes takes a long time. Some of the simple interactions can not be achieved simply, and you have to figure out how to do it. If you haven’t been using InDesign interactivity features yet, you’ll have a slight learning curve before you’ll be able to apply them efficiently.
  • InDesign documents can’t export directly as layered PSD files – If you do your visual design in Adobe Photoshop and want to have separated wireframe elements from building your design on, then you have to export your wireframes to PDF first, then open that PDF in Illustrator and export as layered PSD. People working on the Mac can also use a free script written by Rob Day to save InDesign files as a layered PSD.

Good Wireframe Preparation is Half of the Work

Start by fine tuning your working environment. If you do not already have a saved Workspace in Illustrator and InDesign for this kind of work, create one. In Illustrator start with predefined Web workspace and adapt it to your convenience: close panels you will not use often and open the ones you will, then rearrange them to suit your work style. When done, save the workspace by choosing Window > Workspace > New Workspace… Do the same thing in InDesign using Digital Publishing workspace as a starter.

Assembling Wireframe/Mockup/Prototype Kits

Efficient wireframing workflow using Illustrator and InDesign requests that you invest some time in making your user interface assets kit first. Since the introduction of Adobe Creative Cloud, CC Libraries are the best way for storing all your UI kits components.

You can create one or more Libraries for wireframing and prototyping purposes. For example, you can create one Library for websites wireframing, other for iOS application, third for Android applications and so on.

To create library Open Libraries panel and choose Create New Library from additional drop-down menu. Assets you put in libraries can be made and used in different Adobe desktop or mobile apps on all devices you log into with your Adobe ID. That means you can start with the project on your iPad or iPhone, continue on the desktop computer in the office and made last minute changes on home laptop with all the same assets available on all devices. If you work as a part of a larger team, library assets can be shared between team members and you can collaborate on them. Libraries can contain colours, graphics, layer styles (Photoshop only), paragraph and character styles. You add asset in library by clicking on the corresponding button at the bottom of CC Library panel with respective element selected. You can also add graphic assets by dragging them directly from your artboard to Libraries panel. Assets in libraries are organized by categories. To stick with good practices, rename each asset with meaningful name. Libraries are searchable, and finding an asset in a hip by typing beginning of it’s name will save you tons of time, especially when you have many different items in libraries. You can search only current or all libraries created. To change asset name just double click on it and type a new one.

Creating Kits Components

Although Adobe InDesign has some basic drawing tools that are pretty similar to Illustrator’s, Illustrator is a much better choice for drawing different kinds of elements in your wireframe. As a rule of thumb, make all kit elements that request some drawing beyond basic geometric shapes in Illustrator and simpler elements, that contain text you’ll need to change in layout, like simple buttons, in InDesign.

For starters, make a list of all the elements in the wireframe you’ll need, like navigation elements, page elements including images, video frames and text boxes, icons, avatars, form elements and all other interface elements. After your list is completed you can head to Illustrator and InDesign for elements creation. Start by creating a new document for wireframe or mockup kit components. Double-check that you choose either Web/Devices Profile in Illustrator or Web/Digital Publishing Intent from New Document dialog box, so pixels are used as units, and color mode is RGB.

Make wireframe kit assets as simple as possible, because they need to give fast visual cues for what they represent without been too much detailed. You should use very limited colour palettes of preferably a few shades of grey. Visually accentuate elements that are more important by coloring them with darker shades, or by giving them bigger contrast. For higher fidelity mockups or prototypes, you’ll create UI kits with more detailed elements that use each project’s respective color palette. For easy access to color palettes add them to CC Libraries too.

Who knew Adobe CC Could Wireframe

Adobe Illustrator assets in CC Libraries

Assets you add to Libraries from Illustrator are linked by default (since Adobe CC 2015). That means that when you modify a library asset in Illustrator, changes are reflected in all instances used. If you want to add unlinked asset to document press Option/Alt key while dragging it from the panel.

Who knew Adobe CC Could Wireframe

When you use linked Illustrator assets in InDesign they have little cloud icon in the upper left corner when document is viewed in Normal mode and they are all listed in Links panel. If you modify Library asset in Illustrator changes in the InDesign document won’t be done automatically. Cloud icon will be replaced with Modified Link exclamation mark icon, and you’ll have to update these links.

InDesign assets you place in InDesign document are not linked. That means that you can edit instances independently of the original, and when the original asset is modified those changes are not reflected on assets you already put into layout.

Who knew Adobe CC Could Wireframe

Use those properties when creating wireframes on your behalf: add assets to Library from Illustrator when you assume they’ll need to be modified and updated globally or add them from InDesign when you know you’ll want to modify them individually. Note that you can also make graphics in Illustrator and then Copy/Paste them to InDesign, modify if needed and then add to Library as InDesign asset.

If you happen to forgot which graphic asset is created by which application look at the right side of each item in Library panel while using Show items as a list preview more.

Adobe InDesign Flexibility with Texts

Since you’ll probably want to be able to easily change texts and its formatting create text based assets in InDesign. InDesign has a nice feature for filling text boxes with placeholder text. When you draw text box just make a right mouse click on it and choose Fill With Placeholder Text. You can easily add text box to Library like any other graphic element just by dragging. When you use those text assets later as a part of your wireframes layout you can modify text box itself or text it contains however you like.

Consider to make button UI elements in InDesign too. To create a button, make text frame first, type respective text in it and then use Object > Text Frame Options to define Inset spacing. Adjust Vertical Justification of text inside a box by choosing desired option from Align drop-down menu. Switch to Auto-Size tab and choose appropriate Auto-Sizing (that would probably be Width Only), and convenient reference point. If you do not want let InDesign break your text in more than a one line check No Line Breaks option.

Give Yourself a Hand

There are lot of Adobe Illustrator wireframing and prototyping UI kits available on the internet you can buy or even download for free if you want to fasten your wireframing preparation phase. Maybe you already have lot of those elements drawn that you can dig from your achieved projects. Open those documents, tweak any previously made elements if needed, and put them into respective Libraries.

If you are designing for a particular platform, for example iOS or an Android application be sure that you carefully read their human interface guidelines and use appropriate assets. Don’t put pressure on yourself that every asset possible has to be in your Libraries before you start with actual wireframing process because you can also add assets to your libraries later and on the go.

Creating InDesign Wireframe Templates

Who knew Adobe CC Could Wireframe

There is another important preparation step left that you also need to do: create InDesign templates you’ll use for making wireframes. Start by creating a new document with Web or Digital Publishing Intent and define appropriate page size for the screens you are designing for. Since it is recommended that you use some kind of a grid for laying out your wireframe elements set up the margins and create column grid by setting number of columns and the gutter space. You can change those settings later from Layout > Margins and Columns with respective master page (or pages) selected in Pages panel. If you need horizontal guides and complementary vertical guides, create them manually or make additional grid by using Layout > Create Guides… When creating grid you can help yourself with one of the online grid calculator tools like the Gridulator.

You can also create additional templates for presentation purposes with device mockup as a frame for your wireframes. Since one InDesign document can be placed into another, you can create wireframes in one InDesign document and then place it into another one for presentation purposes. Although it might seem complicated at first it is actually very simple and offers effective workflow. Keeping actual wireframe in separate document makes it easier to continue building from approved wireframes to polished visual design. On the other hand, you have presentation ready template to place wireframes into, add labels and comments and you are all set up to show your best to the client. When you make modifications on wireframe file just update it like any other link in presentation document, and ta-daaa! all changes are in your presentation too.

In the Layers panel you can prepare separate layers for different kind of the content: user interface elements, interactive features, gestures, labels or notes. If you’ll need more layers for a specific project you’ll be able to easily add them anytime during the wireframing process.

When you are done with creating save your templates as InDesign .indt template files. After all the templates you need are saved you are finally ready to start with wireframing efficiently.

Building Wireframes

First things first – start with the Master page. Drag all elements that will be the same on all screens of your project from Library. If you are designing website those are usually headers with logo and navigation and footer. Since you can make more than one Master page and they can be based on each other don’t forget to take advantage of that feature. For example, depending on the project, you can create a Master page for one website category, then make new Masters based on the first one and change on them only elements that need to be different for other categories you’re also having.

Who knew Adobe CC Could Wireframe

You can’t select, change or delete Master elements on regular document pages unless you click on them while holding Command/Control + Shift to override the master. Once your element is overridden you can change any of its parameters or completely delete it from layout. Keep in mind that even when you override the element, it’s parameters that you haven’t change are still dependent on the Master. For example, if you override an element and change it’s color, it’s size is still connected to Master’s and if you change it on Master page it will also be modified on that element you previously overrided. When inserting additional pages to your wireframing document remember to base them on the respective master. If you need to change the Master for pages already in layout, select them in Pages panel, make a right click and choose Apply Master to Pages… When you are finished with Masters, move along with pages for all screens of your project. Use Library assets and arrange them using Smart Guides and Align options to create final UI wireframe layout.

If you are making design for more than one screen size, make alternate layouts from Layouts > Create Alternate Layout or Pages panel. You can use liquid layout rules when creating alternate layouts to automatically or semi-automatically adopt page elements from one size and orientation to another or you can manually control them. For applying and testing Liquid Layout Rules use Page Tool or open panel: Window > Interactive > Liquid Layout.

Who knew Adobe CC Could Wireframe

Adding interactivity

Adobe InDesign has a bunch of interactivity features that you can take advantage of when creating wireframes or prototypes. Which features you’ll include depends on the final format you plan to save your wireframes, prototypes or presentation into. If you are exporting as PDF, interactivity is limited but you can at least make links between screens work. You’ll use Hyperlinks panel to create them. Select the item you want to behave as a link and click on New Hyperlink icon. From Link To drop down menu choose Page and enter desired page number. Repeat that action on all items you want to behave as links between the screens. You can also add hyperlinks to objects residing on the Master pages, and that can be a real time saver: create links on Master page once and they will work on all screens of your document.

Another interactive feature that you can use in interactive PDF format is button with Show/Hide action and that you can use to build all kinds of pop-up content.

You can create button from any graphic, text, image or a group. To create a button from a selected object use Window > Interactive > Buttons and Forms panel and click on the Convert to Button icon. Buttons can have different states created for Normal, Rollover and Click appearance. To add rollover or click state to button click on them in Buttons panel to activate and then edit button appearance for that state the way you want it to look. To add an action to a button, click on a plus sign and choose it from the list. Take into account that actions under SWF/EPUB will not work in interactive PDF. For creating popup elements choose Show/Hide Buttons and Forms. To hide buttons until triggered check Hidden Until Triggered option. You can include multistate objects in interactive PDF, but only if you export them as SWF first and then place those SWFs back in InDesign layout for PDF export. That workflow is tedious and those PDFs can not be properly seen in all PDF readers so you better avoid doing this unless really necessary.

If you want to convert your document to HTML prototype using InDesign CC 2015 Publish Online feature you can use much more interactive options like animations, multistate objects, multiple button actions, including all those intended for SWF/EPUB export.

You can add simple animations using Animation panel and choosing one of the built-in Presets from drop-down menu and setting its properties. One object can have only one animation applied, but if you need to add more of them, group your object with empty box and use the new animation on that newly created object. And repeat that few times if needed. For objects you need to show different states create multi state object. Create object for each state. Object can be a single element (picture, text box, graphic) or a group of different elements. Open Window > Interactive > Object States panel, select all objects you created for multi state object and click on the New button at the panel bottom. After your multi state object is made you’ll need to create buttons to go from one object state to another. Go To Next State or Go To Previous State actions reveal the specific object state with Go to State action.

If you want to have scrollable frame in your wireframe/prototype easiest way to create one is by usingUniversal Scrolling Frames extension from Ajar Productions. After you download and install extension you can use it as InDesign panel. For scrollable frame you’ll need to make content and one frame for container. Content can be text frame, picture, or more elements combined. If using more than one element as a content don’t forget to group them. When you are finished with making content and container box select the content and do Edit > Cut. Then select container and paste content inside by using Edit > Paste Into. Select container and using Universal Scrolling Frames adjust desired scroll direction.

By combining buttons, multistate objects, animations and scrollable frames you can achieve rich interactive experience.

To test interactivity in InDesign use EPUB Interactivity Preview panel. You can preview single page or whole document. Enlarge preview panel to your convenience.

If you haven’t being using Adobe InDesign interactive features yet be prepared that they have some learning curve, but with a little practice and few trial and error attempts you’ll quickly master them.

Exporting finished documents

When you are done with the wireframe and presentation file making all that is left is show your great ideas to the client in best way possible. For that purpose you’ll need to export your wireframes in one of the formats your client can preview. Although InDesign files can be exported in variety of formats you are probably going to use the most common Interactive PDF, or Publish Online feature if testing functional low or high fidelity prototypes. To save as interactive PDF choose Adobe PDF (Interactive) from Format drop-down menu in Export dialog box and adjust properties as needed. Do not forget to tick Forms and Media if there are interactive elements that you want to include. Clients can view PDF wireframes in free Adobe Reader and write all their comments in that same file.

You can also use PDF document you export from InDesign to create InVision (or some other tool that supports PDFs) prototype. If your standard prototyping tool, perhaps Marvel, can’t import PDF export your InDesign wireframe pages as JPEG or PNG images.

To export interactive HTML prototype that can be seen in modern browsers on different devices go to File > Publish Online or click on the Publish Online button from Application Bar. After the document is prepared to be published online and then uploaded you can copy document URL to share with all the stakeholders and start with reviewing process. You can also embed that published prototype on your site.

Downside of Publish Online feature is that it doesn’t have any additional control over the export and files are always stored at Adobe’s servers. Also it’s still preview feature and you can’t be sure in which direction Adobe is going to develop it or even discontinue.

Once your wireframe/prototype is exported it’s time for testing, reviewing and iterating process to start.

This article was written by  IVANA MILIČIĆ, a Toptal freelance designer.

Load balancer for Web Sockets


I am working on a implementation which requires using websockets with failover to comet. Web socket is an upgrade protocol to HTTP, and once established the connection remains open between server and client. Typical HTPP load balancers will not work – so what is the solution.
I did some research on loadbalancer with specific support for Websockets –it turns out that HAPROX is the most reliable and widely used open source option. Other option is NgNix, having community version as well as paid model –but community version lacks active support.

Apache has also released it’s module for websockets, but reviews are not as good as HAPROXY. A good comparison and discussion around these three is available in this post.

The “Greatest Limitation” of HAPROXY –it does not have a build for windows.
It can be worked out for testing with cygwin on windows -but for any production deployment, it has to be a linux machine.