Best Practices for Designing Productive Mobile APIs

Original author: Kate Matsudaira
  • Transfer


There are many informative articles on the web about high performance on mobile devices, and as much about general API design. But there is very little discussion of the architectural solutions necessary to optimize the performance of backend APIs intended for use by mobile clients.

Of course, it is necessary to optimize the performance of the mobile applications themselves. But we, infrastructural engineers, can do a lot to ensure that mobile clients are reliably and quickly provided with data and software resources - thereby supporting a positive experience in using mobile applications.

Here are some things to consider when designing mobile software:

  • Limited screen size . Little space for data, small images.
  • Fewer concurrent connections . This is important because, unlike desktop browsers that can perform many simultaneous asynchronous requests, mobile browsers have a limited number of connections to the same domain.
  • The network is slower . Network performance is greatly affected by the overall level of signal reception, servicing multiple subscribers (and although some of them are sitting on Wi-Fi, some networks become overloaded and perform additional search operations if the user connects to another base station).
  • Lower processing power . Intensive client computing, 3D rendering, and heavy use of JavaScript can greatly reduce performance.
  • Less caches . Mobile clients are generally limited in memory, so it’s best not to rely too much on cached content to improve performance.
  • "Special" browsers . The ecosystem of mobile browsers in many ways resembles the fragmented environment of desktop browsers several years ago, when developers released ever new versions with fatal flaws and incompatibilities.

There are many ways to solve the described difficulties, but this article is mainly devoted to what can be done with the API or backend to improve the performance (or perception) of mobile clients. We will consider two main issues:

  1. Minimize network connectivity and data transfer requirements . Effective multimedia processing, efficient caching and use of longer operations oriented on data processing and with fewer connections.
  2. Sending through the network of "correct" data . Designing such APIs that only return the required / requested data, as well as optimization for different types of mobile devices.

Although this article focuses on the mobile segment, many lessons and ideas can be applied to API clients in other areas.

Minimize network connectivity and data transfer


One of the most important tasks that you need to solve to improve performance on mobile devices is to minimize the number of HTTP requests required to render a web page. This is done in many different ways, and the choice of approach may depend on your data.

Images


If you make one request for each image on the page, then you can improve the speed and take advantage of the caching of individual images. The desktop browser is able to process requests quickly and in parallel, so their number does not significantly reduce performance (and due to caching, the “strength” margin becomes even higher). However, on mobile devices, a large number of requests can become fatal.

Minimizing requests for images can reduce the total number of requests, and in some cases the volume of transmitted data (which also favorably affects performance). What strategies can be followed?

Sprites


Using sprite images helps reduce the number of individual images that need to be downloaded from the server. But this solution has a drawback: sprites can cause trouble in support, and in some situations they are not easy to generate (for example, when searching a product catalog you need to show a large number of previews).

Use CSS instead of images


If everywhere, wherever possible, to avoid images and use CSS rendering for shadows , gradients and other effects, then you can reduce the number of bytes that need to be transferred and downloaded.

Responsive Image Support


Responsive images are a common way to deliver the correct image to the appropriate device. Apple does this by loading regular images, and then using JavaScript to replace them with higher resolution images. There are a number of other approaches , but we are still far from solving this problem .

To use responsive images, make sure that they are supported on the server and that the APIs support different versions of the same image. A specific implementation will depend on client decisions.

Reduce additional queries by using data URIs to inline images


An alternative to sprites is to use data URIs to inline images in HTML. As a result, images become part of the entire page. And although their size in bytes can increase, such images are better compressed using Gzip, which compensates for the increase in the amount of transmitted information.

Tip : if using a URI, then:

  • Reduce the images to the desired size before embedding in the URI.
  • Check that Gzip compresses responses to requests (to take advantage of compression).
  • Please note that the images embedded in the URI are part of the CSS page, which means it will be more difficult to cache individual images. Therefore, avoid inlining if there are good reasons for caching images locally (for example, if they are often used on different pages).

Using local storage and caching


Because mobile networks can work slowly, HTML, CSS and images can be stored in local storage (localStorage). Here is an excellent study on improving Bing performance using local storage, which helped reduce the size of the HTML document from ≈200 Kb to ≈30 Kb.

A great way to improve a subjective assessment of performance by users is to pre-select the data that will be used on mobile devices to send it to customers without additional requests. This includes paginated search results, popular searches, and user data. If you think about this approach and consider it in architecture, you can create APIs that can prepare and cache data before the user requests it, which will improve the subjective perception of performance.

Tip : data that is unlikely to change during application updates (for example, categories or main navigation) should be delivered inside the application so as not to waste time and resources transferring over the network.

Ideally, data should be transferred as needed, and preloaded when appropriate. If the user does not see the image or content, then do not send it (this is especially important for responsive sites, since some simply “hide” some elements). An excellent application for preliminary image preparation is a gallery of search results. It is better to immediately load the next and previous images to speed up the interface. But do not get carried away, do not upload too many pictures, because the user may not even see them.

Retrieving data from local storage can degrade performance, but this effect is much weaker compared to data transmission over the network. In addition, some applications, besides local storage, use other HTML5 features , for example, appCache , to improve performance and startup speed .

Tip : if you embed CSS and JavaScript directly in a separate request, then save the links to these files and transfer them to the server via cookies, the client will not have to download these resources again (only new files will be transferred over the network). This will save a lot of time and is a great tool for using local caching. Read more about how to embed and link to the mentioned files directly here:http://calendar.perfplanet.com/2011/mobile-ui-performance-considerations/ .

Non-Blocking I / O


When it comes to client optimization, it is recommended that you monitor JavaScript blocking execution , which can severely degrade performance. But for the API, this is even more important. If you have a long API call, for example, with a call to a third-party resource that can time out, then it is important to implement the call as non-blocking (or even make it wait a long time) and choose either a polling or triggering model.

  • Polling (pull-model) : in the polling-API, the client makes a request and then periodically checks for the result, reducing the frequency of checks if necessary.
  • Triggering (push-model) : in the trigger-API, the call generates a request and then listens, waiting for the server to respond. He provides a callback that triggers an event, thanks to which the caller learns about the appearance of the query result.

Usually the triggering API is more difficult to implement, as mobile clients are unreliable. So most often it is better to use the polling model.

For example, in the Decide mobile application, the product pages displayed local prices for the countries in which these products were available. Since the results were provided by a third-party service, with the help of the polling API we were able to make requests and then receive the results without stopping the application and not supporting an open connection while waiting for the results.

Check that your APIs respond quickly and do not block execution pending results, as mobile clients have a limited number of connections.

Tip: Avoid Chatty APIs. In case of a slow network, several API calls should be avoided. A good rule of thumb is to put all the data needed to render the returned page in one API call.

If on the server side some components are much slower than others, then it may be advisable to split the API into separate calls, focusing on the characteristic response time. Thus, the client can start rendering the page after the first quick calls, while waiting for answers to slower ones. That is, we reduce the time required for the appearance of text on the screen.

Avoid redirects and minimize DNS queries


As for queries, redirects can degrade performance, especially if they are redirects between domains that require a DNS query.

For example, many sites work with their mobile versions using client redirects. That is, when a mobile client accesses the URL of the main site (for example, katemats.com ), it redirects to the mobile site m.katemats.com (this is very often found where sites are built on different technology stacks). Here is an example of a similar scheme:

  1. The user googles for “yahoo” and clicks on the first link in the search results.
  2. Google captures a click using its tracking URL and then redirects to www.yahoo.com [redirect]
  3. The answer to the Google redirect passes through the base station of the mobile operator, and then gets on the client phone.
  4. A DNS query is being performed for www.yahoo.com .
  5. The found IP is transmitted via the BS to the phone.
  6. When the phone accesses www.yahoo.com , it is recognized as a mobile client and redirected to m.yahoo.com [redirect]
  7. Then the phone again needs to perform a DNS query, this time for the m.yahoo.com subdomain .
  8. The found IP is transmitted via the BS to the phone.
  9. Finally, the final HTML and necessary resources are transferred via the BS to the phone.
  10. Some images on the pages of a mobile site are provided via CDN via links to another domain, say, l2.yimg.com .
  11. The phone again makes a DNS query for the l2.yimg.com subdomain .
  12. The found IP is transmitted via the BS to the phone.
  13. Pictures are drawn, the page is ready.

As you can see, there are a lot of overhead costs that can be avoided by using redirects on the server side (that is, routing through the server and minimizing the number of DNS queries and redirects on the client), or using adaptive techniques .

Tip : if you cannot avoid a DNS query, then to save time, try using a preliminary DNS query for known domains.

HTTP and SPDY pipelining


Another useful technique is HTTP pipelining . It allows you to combine multiple queries into one. Although I would choose SPDY , which optimizes HTTP requests so that they are much more efficient. This protocol is supported on Amazon Kindle, Twitter, and Google.

Sending the "right" data


Different clients need to send different files, CSS and JavaScript. Even the number of results may vary. Designing APIs that support different combinations and versions of results and files will give you maximum flexibility in creating a great collaboration experience.

Use limit and offset to get results.


As in the case of conventional APIs, extracting results using limit and offset allows customers to request various data necessary for a particular use (there will be fewer results for mobile clients). I prefer notation limit and offset, since it is more common (than, say, start and next), it is well understood by many databases, and therefore easy to use.

/products?limit=25&offset=75

Choose the default value that corresponds to the largest or smallest common multiple (common denominator), with which you can select the most important customers for your business (less - if the core of your audience is mobile clients, more - if you’re mainly visited desktop computers, this is usually true for B2B sites and services).

Partial response and partial update support


Design your APIs so that customers can request only the information they need. This means that the API must support a set of fields, and not return a complete view of the resource each time. If the client does not have to collect and parse unnecessary data, requests are simplified and productivity improves.

A partial update allows customers to do the same with the data that they write to the API (and then you do not need to define all the elements within the classification of the resource).
Google supports a partial response using additional optional fields in the form of a comma-delimited list: If specified for a call , this means that the caller only requests a partial set of fields.

http://www.gоogle.com/calendar/feeds/[emаil prоtected]/private/full?fields=entry(title,gd:when)

entry

Avoid or minimize the use of cookies.


Each time a client sends a request to a domain, it includes all cookies received from this domain - even duplicated or extraneous values. Therefore, another way to reduce the amount of data transferred and improve performance is to maintain the small size of the cookies (and not to request them if they are not needed). Do not use or require cookies unnecessarily. Provide static content that does not need permissions from a domain without cookies (for example, images from a static domain or from a CDN). Here is a description of some methods of working with cookies: https://developers.google.com/speed/docs/best-practices/request .

Create device profiles for the API


Given the variety of screen sizes and resolutions for desktops, tablets, and smartphones, it’s useful to create profiles that you will support. For each profile, you can provide different images, data and files suitable for specific devices. This is done using media queries to the client .

The more profiles, the better the interaction experience for a particular device. But then it will be more difficult to maintain all kinds of supported functions and scripts (because the devices are constantly changing and developing). So it’s better to maintain only the absolutely necessary number of profiles. As for the compromises and opportunities for creating a good interaction experience, I recommend reading this article:https://mobiforge.com/design-development/effective-design-multiple-screen-sizes .

For most applications, three profiles are sufficient:

  1. Mobile phones: smaller images, touch control available, low network bandwidth.
  2. Tablets: images are larger, but adapted for a network with low bandwidth, touch control is available, more data is transmitted in the request.
  3. Desktop Computers: Images for tablets and higher resolution images for Wi-Fi and desktop browsers.

The desired profile can be selected on the client. The server-side APIs should be designed to take these profiles and send different information depending on which device sent the request. For example, smaller images will be sent, or the size of the results will be reduced, or CSS and JavaScript will inline.

Suppose if one of your APIs returns search results, then the profiles can be as follows:

/products?limit=25&offset=0

A default profile (desktop) is used, a standard page is given that requests each picture separately, so subsequent views can be loaded from the cache. 10 results are returned, low-resolution images are transmitted as URIs in a single HTTP request.

/products?profile=mobile&limit=10&offset=0



/products?profile=tablet&limit=25&offset=0

20 results are returned, low-resolution images, but larger in size, are transmitted as URIs in one HTTP request.

You can even create profiles for gadgets such as feature phones . They, unlike smartphones, allow you to cache files only page by page. So for such clients it is better to use profiles than send CSS and JavaScript in each request.

It is recommended to use profiles instead of partial responses if server responses vary greatly depending on the profile. For example, if in one case the response contains inline URI images and a compact layout, and in the other case, it no longer exists. Of course, profiles can also be set using “partial answers”, although they are usually used to determine a part (or portion) of a standard scheme (for example, a subset of a larger classification), and not just another set of data, formats, etc.

Finally


There are many ways to make the web faster, including on mobile devices. I hope this article will be a useful guide for API developers who design server parts for working with mobile clients.

Also popular now: