Nscache and Nsurlcache Network cache optimization

Source: Internet
Author: User

The first thing to say is something important:
Nscache and Nsurlcache didn't have a relationship.
Nscache and Nsurlcache didn't have a relationship.
Nscache and Nsurlcache didn't have a relationship.


One thing to be aware of:
When setting the size of Nsurlcache, most of the following code is used

-(BOOL) Application: (UIApplication *) application
    didfinishlaunchingwithoptions: (nsdictionary *) launchOptions
{
  Nsurlcache *urlcache = [[Nsurlcache alloc] Initwithmemorycapacity:4 * 1024 * 1024
                                                       diskcapacity:20 * 1024 * 1024
                                                           Diskpath:nil];
  [Nsurlcache Setsharedurlcache:urlcache];
}

But even without the code, iOS automatically participates in caching, using the Nsurlcache class created by the system, as well as by the Nsurlcache Sharedurlcache method.

In some cases, the system components in the application set the cached memory capacity to 0MB, which disables caching. One way to resolve this behavior is to nsurlcache the memory cache size to 0 by implementing subclasses of your own. If you can set it up using the following code:

@interface mknonzeroingurlcache:nsurlcache

@end

@implementation mknonzeroingurlcache

-(void) Setmemorycapacity: (Nsuinteger) memorycapacity {
    if (memorycapacity = = 0) {return
        ;
    }
    [Super setmemorycapacity:memorycapacity];
}

@end

@implementation appdelegate

-(BOOL) Application: (UIApplication *) application Didfinishlaunchingwithoptions: (nsdictionary *) launchoptions {
    
    Mknonzeroingurlcache *urlcache = [ Mknonzeroingurlcache Alloc] Initwithmemorycapacity:4 * 1024 * 1024 DISKCAPACITY:20 * 1024 * 1024 DiskPath:nil];
    [Nsurlcache Setsharedurlcache:urlcache];
    
    Return YES
}
// ...
@end

In addition, when the application is not running, if the system encounters too little disk space, the system will also actively purge some of the disk cache.

Han: Setsharedurlcache: The naming and programming behavior of this method can also be learned. It tells us that the creation of a single case is not always the same. Use the Sharedxxx method, or you can use a setsharedxxx: Pass a custom object of this class, although the single Instance object is created externally rather than preset. But after this creation, the Sharedxxx method is still the way to get a single example.

This article mainly introduces a network caching optimization strategy, in fact, this optimization scheme is to enhance the network performance of a small scheme. Upgrading network performance is a big issue, it mainly includes the following aspects of the improvement:

The strategy of optimizing network request performance
A. Reduce request bandwidth
1. Request compression
2. Response compression
Two. Reduce Request Latency
For example: Open Pipeline support for Nsurlreqeust
Three. Avoid network requests
Basically using cache optimization to go back to the top a caching optimization scheme

The HTTP protocol specification defines etag as the entity value of the requested variable. Alternatively, ETag is a token (token) that can be associated with a Web resource. A web resource can be a Web page, JSON, or XML data, a file, and so on. ETag is somewhat similar to a file hash or information digest.

In the browser default behavior, when a URL request is made, the server returns the ' Etag ' response header, and the next time the browser requests the same URL, the browser automatically sets it to the value of the request header ' If-none-match '. After the server receives this request, it starts to do the information verification work will own this generation ETag and request passes over ' if-none-match ' contrast, if the same, then returns the HTTP status Code 304, and response the data body does not have the data.

Further analysis of this process: the second request from where to get the value of ' Etag ' and assigned to the request header ' If-none-match '. Nature is taken out of the browser's cache. Then what does the browser do after it receives a 304 status code? As I said, there is no data in the response data body, but the browser still needs to load the page, which reads the last cached page from the cache.

The browser and server above work together to complete a series of tasks such as:

if (not cached locally) {
    make first request
} else {local cache
    fetch last response etag, make network request as ' If-none-match ' value for this request
    If ( HTTP status Code = = = 304) {
        //Response's data body is empty, reducing the prerequisite for a data transfer
        //cache presence, fetching data from the cache
    } else {
        //not 304, stating that the content of the request has changed , the server gives the new data, the data body is not empty
        //Use the latest data
    }
}

However, the above mentioned a chase is only browser behavior, not the default behavior of iOS request, for iOS development, although do not need to manage the cache manually, but caching policy will affect the behavior above.
The following are the URLRequest caching strategies that are defined in iOS:

typedef ns_enum (Nsuinteger, Nsurlrequestcachepolicy)
{
    nsurlrequestuseprotocolcachepolicy = 0,

    Nsurlrequestreloadignoringlocalcachedata = 1,//never read cache, but response cached
    after request Nsurlrequestreloadignoringlocalandremotecachedata = 4,//unimplemented
    nsurlrequestreloadignoringcachedata = Nsurlrequestreloadignoringlocalcachedata,

    //The following two types of cache may be fetched with expired data
    Nsurlrequestreturncachedataelseload = 2 ,//cache is not to initiate the request to load, there is no network request
    Nsurlrequestreturncachedatadontload = 3,//cache does not load, never initiate network request, the cache does not return error

    Nsurlrequestreloadrevalidatingcachedata = 5,//unimplemented
};

Let's take a look at the default caching policy useprotocolcachepolicy and ignoring cached policy Reloadignoringlocalcachedata when using the default caching policy:

The first time a URL is requested, the response and data are cached.
When the same URL is requested again, the ETag in the cache is used as the ' If-none-match ' value for the request requested, so that the server returns 304 and the response data body is empty, and iOS helps to read the data body in the cache. Modify the response of the secondary request, change the HTTP status code to 200, and perform the completion callback using the modified response and the data fetched in the cache as parameters.

The process seems perfect, except that the status code is not 304, and the other process is almost identical to the browser. But he has a flaw, before studying this flaw we first understand one of the facts: the content of the request can be divided into three kinds of 1. Script 2. Pages rendered with data 3. static files.

For the processing of the script request, the server ignores the etag and processes it each time, so that the returned data is new and returns an HTTP status code of 200.
For pages that are rendered with data, the server calculates the etag after rendering according to certain rules of calculation, then compares and then decides to return 304 or 200.
For static files, some servers have the ability to detect static file changes, once the file changes, the server will immediately detect, thus returning 200 to the client, and some servers detect file changes in the function is delayed, or do not have this function, so even if the contents of the file changed, The server still thinks it hasn't changed, so the contrast etag is still the same, and the result returns 304. (This test uses Apache and Express, the default configuration of Apache for file change detection is delayed, express is real-time detection)

The above description exposes a disadvantage of using the default caching strategy, and if the server is unable to detect file changes in real time, the result is inaccurate. The worst case scenario: When the file changes, the server thinks it's still unchanged, returning 304, without the latest data. when Reloadignoringlocalcachedata policy:

The cache is ignored before each request, and the header of the request never comes with the ' if-none-match ' value, and the server returns 200 each time it is successfully processed, so that every time the server's data is received (each response's date header is a new value), The response returned by the server has a complete data body. After the iOS receives the data, it response and caches the data and executes the callback as a parameter.

Here we can also see the drawbacks of using the Reloadignoringlocalcachedata strategy: Even though the server-side files do not change, iOS still does not use the local cache, and each service has to send the data to the client, which is a waste of bandwidth. This is not good, use this is not good, in the end how to

We expect the state to be like this:
For the service side, no matter how the configuration, all want the file to change the test results are the most accurate. For iOS clients, get status code 200 naturally do not do much processing, if the status Code 304, then the data from the cache.

The following caching optimization scenarios were made:

-(void) Refreshedrequest: (NSString *) urlstring success: (void (^) (nshttpurlresponse *httpresponse, id responsedata)) SUCCESSS failure: (void (^) (nserror *error)) Failure {nsmutableurlrequest *urlrequest = [Nsmutableurlrequest requestWit
    
    Hurl:[nsurl Urlwithstring:urlstring]];
    Nsurlcache *urlcache = [Nsurlcache Sharedurlcache];
    Nscachedurlresponse *cacheurlresponse = [Urlcache cachedresponseforrequest:urlrequest];
        if (cacheurlresponse) {nshttpurlresponse *httpresponse = (Nshttpurlresponse *) cacheurlresponse.response;
        NSString *cachedresponseetag = [Httpresponse.allheaderfields objectforkey:@ "Etag"];
        if (Cachedresponseetag) {[URLRequest setvalue:cachedresponseetag forhttpheaderfield:@ ' If-None-Match '];
    } [URLRequest Setcachepolicy:nsurlrequestreloadignoringcachedata]; [[[Nsurlsession Sharedsession] datataskwithrequest:urlrequest completionhandler:^ (NSData * _Nullable data, Nsurlresponse * _nullable response, NserROR * _nullable error) {if (!error && successs) {nshttpurlresponse *newhttpresponse = (nshtt
            Purlresponse *) response;
                 if (Newhttpresponse.statuscode = = 304) {

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.