用如下命令安装libwebp,当在流量环境下一旦有Wi-Fi高清图片的缓存

Fresco是一个精锐的图纸加载库,想必笔者等码农都有使用过和询问,fresco官网。在此之前app端做过那样叁个优化依照用户手提式有线电电话机的互连网环境加载对应的清晰度的图纸,一来是升格用户体验加载快,二来节省用户的流量终究我们的国外用户流量很贵的。然后功用我们贯彻了,差异网络环境请求例外的图纸对应分歧的U福睿斯L。
–在此基础上领导建议个新要求,当在流量环境下一旦有Wi-Fi高清图片的缓存,就动用高清缓存的图片,不再去乞求低分辨率的图纸。fresco的三级缓存策略的前提条件是唯一的U汉兰达L分明某一张图纸。而老板的渴求想当如UCRUISERL_a的伏乞使用UTiguanL_b的缓存。

流量优化对于二个app来讲意义格外首要,能节约用户的流量,节约用户的蕴藏空间,而且能有拉长互连网请求的回包速度,升高app的进程。因而流量优化历来都以app的优化重点,而且是二个不息优化的点。

好奇心早报是3个多图片的消息类应用,采访编辑喜欢上传gif图来提升内容的表现力,那也使得流量消耗十分大。粗略推测,用户在浏览完第2页全部新闻(共48篇),会消耗流量达100m,个中98m为图片,那里值得优化的空间一点都非常的大。

本着那种地方,大家先后使用的优化包涵:wifi条件下预载全体小说、图片和js、css数据;重用全数曾经下载的js、css和图表的缓存;后台图片的削减以及客户端图片的WebP化。

内部,后台压缩和WebP化信赖第3方多媒体处理服务器,已知比较好的境内服务有腾讯优图和七牛。那里大家运用的七牛的服务,以下居多有血有肉的调用都以基于七牛的。

大家的后台通过七牛的图形压缩(蕴含品质和分辨率),我们将首页流量由100m缩减到了80m,依旧有高大的晋升空间。因而客户端选用基于WebP的流量压缩方案,将流量由80m削减到了20m,收缩了四分之三!相对于早先时代的处理,流量收缩了4/5!(android半数以上机型支持WebP
animated,压缩能落得八成,但iOS的压缩率取决于首页中gif图的个数和尺寸,测试大约优化在十分之六-8/10时期)

上边就介绍下这些成效极好的WebP的流量消除方案。

尝试一:setFirstAvailableImageRequests 方式。

查看fresco文书档案发现有【多图请求及图片复用】介绍,里面包车型大巴【加载起先可用的图】小段讲的麻烦事例是图片上传,本地图片和互联网下载图片应用该办法,我们的风貌那么些就好像能够也适用。

      Uri uri1, uri2;
      ImageRequest request1 = ImageRequest.fromUri(uri1);
      ImageRequest request2 = ImageRequest.fromUri(uri2);
      ImageRequest[] requests = { request1, request2 };

     DraweeController controller = Fresco.newDraweeControllerBuilder()
    .setFirstAvailableImageRequests(requests)
    .setOldController(mSimpleDraweeView.getController())
    .build();
    mSimpleDraweeView.setController(controller);

可实际本人断点测试的结果却非文书档案所讲,有小可能率会会达到梦想洗过。可基本上时候是先使用request1请求的图样,及时是有request2的缓存图片,request1需求网络请求下载图片的。

一、WebP的介绍

品尝二:代码中判断是还是不是留存Wi-Fi高清图片缓存。
      if (NetWorkHelper.netWorkState != NetWorkHelper.kNetWorkWIFI && PreferenceUtil.getBool(App.getInstance(), PreferenceUtil.BOOL_NETWORK_GETING_IMAGE, false)) {
                        //非Wi-Fi环境下,原则上选择当前网络环境的压缩图片。但当存在Wi-Fi环境下的高清图缓存时候,使用Wi-Fi高清图。无则重新下载
                        boolean isCacheInDisk = Fresco.getImagePipelineFactory().getMainBufferedDiskCache
                                ().containsSync(new SimpleCacheKey(url));
                        boolean isCacheInFile = Fresco.getImagePipelineFactory().getMainFileCache()
                                .hasKey(new SimpleCacheKey(url));
                        ImageRequest request;
                        if (isCacheInDisk || isCacheInFile) {
                            request = ImageRequest.fromUri(uri);
                        } else {
                            request = ImageRequest.fromUri(Uri.parse(formatUrl(uri.toString(), getWidth(), getHeight())));
                        }
                        DraweeController controller = Fresco.newDraweeControllerBuilder()
                                .setImageRequest(request)
                                .setCallerContext(callerContext)
                                .setOldController(getController())
                                .build();
                        setController(controller);
                    } else {
                        //Wi-Fi环境下选择高清大图
                        ImageRequest request2 = ImageRequest.fromUri(uri);
                        DraweeController controller = Fresco.newDraweeControllerBuilder()
                                .setImageRequest(request2)
                                .setCallerContext(callerContext)
                                .setOldController(getController())
                                .build();
                        setController(controller);
                    }

代码逻辑正是判断缓存中是或不是留存,存在即请求Wi-Fi环境下的图样url,不设有就请求流量环境下的图片url.至于判断一遍缓存是来自fresco的三级缓存原理,三个是内部存储器中的缓存一个是磁盘缓存。同样这里去乞请Wi-Fi环境下的图样U奥德赛L因为事先有缓存的,也只是直接行使缓存并不会议及展览开实际网络下载的。经测试也满意了领导的需求,在性质上眼睛也未发现肯定的距离。

1、什么是 WebP

WebP (发音 weppy
),是一种同时提供了有损压缩与无损压缩的图形文件格式,是谷歌新生产的形象技术,它可让网页图档有效实行削减,同时又不影响图片格式包容与实际清晰度,进而让总体网页下载速度加速。

  • WebP 无损压缩的图片能够比同等大小的 PNG 小 26%;
  • WebP 有损压缩的图样能够比同等大小的 JPEG 小 25-34%;
  • WebP 支持无损的晶莹图层通道,代价只需追加 22% 的字节存款和储蓄空间;
  • WebP 有损透明图像可以比同一大小的 PNG 图像小3倍。

总结

就算尝试2的点子实现了领导的须求,不过有个小危害的询问缓存的代码是在主线程中实践的,当上列表的时候有导致页面卡顿的大概,但自作者拿项目测试的时候从不发现这么,也就没放在心上。搜了下还有个措施查询,然而代码情势麻烦了些。还有情势一不行只怕是自己姿势不对原因,有趣味的多多交换。

项目demo链接

② 、手提式有线电话机端协理意况

  • WebP在手提式无线电话机端浏览器的支撑情形(WebView & UIWebView)
![](https://upload-images.jianshu.io/upload_images/224456-981cce7a16dd7a80.jpg)

1468596300.jpg
  • Native
    Android在4.0以上Image直接援救对WebP的解码。iOS可以经过google提供的WebP解析库来落到实处UIImageView中展示WebP。

QDaily不援助4.0以出手提式有线电话机(今后推测也没啥接济的了啊。。。),所以上面包车型客车机能并从未测试,无脑搬运:
Android 4.0 以下 WebP
解析库(链接)

iOS WebP
解析库(链接)

③ 、WebP工具在Mac Os下的设置(本地编解码)

2.安装到位后,用如下命令安装libwebp。

brew install webp
  • 方式二:使用MacPorts安装

1.到此网站链接下载与系统版本对应的MacPorts,安装MacPorts在此之前供给安装Xcode。

2.比照此文书档案对MacPorts进行安装,链接,作者选拔的是下载.pkg文件进行设置的。整个安装进程中国建筑工程总集团议准备梯子进行不易上网。

3.设置到位后更新:

sudo port -v selfupdate

4.然后安装libwebp,

sudo port install webp
  • 使用工具举办WebP编解码

1.采用 cwebp 将 JPEG 或 PNG 图像转换来 WebP 格式。

cwebp [options] -q quality input.jpg -o output.webp

2.应用 dwebp 实用程序将 WebP 图像转换回 PNG、PAM、PPM 或 P威他霉素 图像。

dwebp input_file.webp [options] [-o output_file]

② 、QDaily iOS客户端中图纸流量优化方案

1、iOS Native

QDaily的Native图片加载使用的SDWebImage,该零件间接支持WebP的解码。需求在将预编写翻译宏’WebP’置为1,并在pod中引入’iOS-WebP’即可。

咱俩图片突显后台是七牛的,默许传给客户端的参数是一张jpg或许png的图片链接,通过修改url的伸手参数完成对WebP图片的取得。亲测iOS下对WebP
Animated的援助很差,平日有转码退步意况,所以iOS中绝非援助WebP的动图呈现。

全体SDWebImage的图纸加载都首先通过SDWebImageManager中下边包车型地铁点子:

    - (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
                                     options:(SDWebImageOptions)options
                                    progress:(SDWebImageDownloaderProgressBlock)progressBlock
                                   completed:(SDWebImageCompletionWithFinishedBlock)completedBlock

我们由此在该格局最初修改url的参数来促成对请求url的轮换和本地缓存的读取:

    {
        if ([url isKindOfClass:NSString.class]) {
            url = [NSURL URLWithString:(NSString *)url];
        }
        if (![url isKindOfClass:NSURL.class]) {
            url = nil;
        }
        url = [url qd_replaceToWebPURLWithScreenWidth];
        ...
        ...
    }

为NSULacrosseL扩大扩充NSUCR-VL+ReplaceWebP

NSURL+ReplaceWebP.h

@interface NSURL (ReplaceWebP)
- (NSURL *)qd_replaceToWebPURLWithScreenWidth;
- (NSString *)qd_defultWebPURLCacheKey;
- (BOOL)qd_isShouldReplaceImageFormat;
@end

NSURL+ReplaceWebP.m

static NSString * const qdailyHost = @"img.qdaily.com";
@implementation NSURL (ReplaceWebP)
- (NSString *)qd_defultWebPURLCacheKey {
    if (![self qd_isShouldReplaceImageFormat]) {
        return self.absoluteString;
    }
    NSString *key;
    if ([self isWebPURL]) {
        key = self.absoluteString;
    } else {
        key = [self qd_replaceToWebPURLWithScreenWidth].absoluteString;
    }
    return key.lowercaseString;
}

- (NSURL *)qd_replaceToWebPURLWithImageWidth:(int)width {
    if ([self qd_isShouldReplaceImageFormat]) {
        NSString *urlStr;
        if ([self URLStringcontainFomartString:@"?"]) {
            if ([self URLStringcontainFomartString:@"format/jpg"]) {
                urlStr = [self.absoluteString stringByReplacingOccurrencesOfString:@"format/jpg" withString:@"format/webp"];
            } else {
                NSString *suffixStr = @"imageView2/0/format/webp/ignore-error/1";
                urlStr = [NSString stringWithFormat:@"%@/%@", self.absoluteString, suffixStr];
            }
        } else {
            NSString *pathExtension = [[self.absoluteString.pathExtension componentsSeparatedByString:@"-"] firstObject];
            urlStr = [NSString stringWithFormat:@"%@.%@-WebPiOSW%d",self.absoluteString.stringByDeletingPathExtension, pathExtension, width];
        }
        return [NSURL URLWithString:urlStr];
    }
    return self;
}

- (NSURL *)qd_replaceToWebPURLWithScreenWidth {

    int width = (int)([UIScreen mainScreen].bounds.size.width * [UIScreen mainScreen].scale);
    return [self qd_replaceToWebPURLWithImageWidth:(int)width];
}

- (BOOL)isQdailyHost {
    NSString *nsModel = [UIDevice currentDevice].model;
    BOOL s_isiPad = [nsModel hasPrefix:@"iPad"];
    if (s_isiPad) return NO;
    return [self URLStringcontainFomartString:qdailyHost];
}

- (BOOL)qd_isShouldReplaceImageFormat {
    if (![self isQdailyHost]) {
        return NO;
    }
    if ([self isWebPURL]) {
        return NO;
    }
    NSArray *extensions = @[@".jpg", @".jpeg", @".png"];
    for (NSString *extension in extensions) {
        if ([self.absoluteString.lowercaseString rangeOfString:extension options:NSCaseInsensitiveSearch].location != NSNotFound){
            return YES;
        }
    }
    return NO;
}

- (BOOL)URLStringcontainFomartString:(NSString *)string {
    return ([self.absoluteString.lowercaseString rangeOfString:string options:NSCaseInsensitiveSearch].location != NSNotFound);
}

- (BOOL)isWebPURL {
    return [self URLStringcontainFomartString:@"-webp"] || [self URLStringcontainFomartString:@"/webp"];
}
@end

因改动了url值,若在上层通过SDImageCache判断是还是不是有本土缓存时,也急需对url先做qd_defultWebPU奥迪Q7LCacheKey来赢得其诚实缓存的key。

2、iOS WebView中

苹果连串具有的webkit内核今后都不帮忙解析WebP格式的图片,QDaily处理那里最首要利用的iOS系统的NSU陆风X8LProtocol来替换其网络请求,再讲互联网回包数据进行转码成jpg可能png(为了光滑度),再回来给webview举行渲染的。

一致的,iOS在那边还是不对gif举行其余处理。

除此以外要注意的是,NSU翼虎LProtocol会拦截全局的网络流量,为防止误伤,那里要求单独识别是还是不是是WebView发起的央浼,能够因此识别request中的ua是不是含有”AppleWebKit”来落到实处。

直白上代码:

@implementation QDWebURLProtocol

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
    NSString *ua = [request valueForHTTPHeaderField:@"User-Agent"];
    if ([request.URL qd_isShouldReplaceImageFormat] && [ua lf_containsSubString:@"AppleWebKit"]) {
        return YES;
    }
    return NO;
}

+(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request{
    return request;
}

- (void)startLoading {
    if ([self.request.URL qd_isShouldReplaceImageFormat]) {
        [[SDWebImageManager sharedManager] downloadImageWithURL:self.request.URL
                                                        options:0
                                                       progress:nil
                                                      completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL)
                                                    {
                                                          NSData *data;
                                                          if ([imageURL.absoluteString.lowercaseString lf_containsSubString:@".png"]) {
                                                              data = UIImagePNGRepresentation(image);
                                                          } else {
                                                              data = UIImageJPEGRepresentation(image, 1);
                                                          }
                                                          [self.client URLProtocol:self didLoadData:data];
                                                          [self.client URLProtocolDidFinishLoading:self];
                                                      }];

    }

}
- (void)stopLoading { 
}
@end

除此以外,QDaily完成了内部文章的缓存,包括js、css以及image等。那里经过NSU劲客LCache来实现。相应的,基于WebP的图样缓存的读取也理应在NSULacrosseLCache中拍卖,在先处理完U凯雷德L后,用新的Key来拓展览放映射。

此地提出持有基于WebView的流量优化都最佳用UA的判断包住,制止带来难点。因为不论NSUEnclaveLProtocol依旧NSUHighlanderLCache都以大局网络决定。

三 、QDaily Android客户端的图形流量优化方案

WebP正是google出的编码格式,和Android同宗同源,帮忙自然会好一些。4.0之上的系统,原生默许帮忙WebP的体现。然则是因为国内android手提式有线电话机各类奇葩的系统,有需要在WebView中进行WebP的识别帮忙。

1、Native部分的WebP

QDaily的Android客户端的图样请求使用的glide,全体请求的缓存通过GlideModule的花样举行任何的本土接管,没有选拔他们默许的cache。

为理解耦方便和制止侵入性,我们在glide和事务代码之间封装了ImageManager,全数的图样请求都会走那里开始展览发送,因而,WebP的优化和拍卖重庆大学在那边举行。

注重涵盖以下多少个点子:

//主处理方法,根据对url进行处理
public static String getWebpUrl(String url, boolean isWebView);
//判断当前url是否已经是WebP的请求了
public static boolean isWebP(String url);
//url是否支持转成WebP请求
public static boolean supportConvertWebP(String url);
//获取文章的host
public static String getHost(String url);
//域名判断,限定七牛域名才可以进行转换url
public static boolean isQiNiuImageHost(String url);
// url后跟的WebP请求后缀
public static String getWebpExtBaseScreen();
// WebView对WebP静图的支持
public static boolean isWebViewSupportWebp();
// WebView对WebP动图的支持
public static boolean isWebViewSupportWebpAnimation();
 // Native对WebP静图的支持
public static boolean isSupportWebp();
// Native对WebP动图的支持
public static boolean isSupportWebpAnimation();

负有Native部分的ImageView在加载图片时候,调用的艺术第二步,会先调用getWebpUrl方法对url进行处理,该方法会依据机器状态进行相应的url参数拼凑。具体贯彻如下:

 public static String getWebpUrl(String url, boolean isWebView) {
        if (TextUtils.isEmpty(url)) {
            QLog.e("", "url 不能为空");
            return "";
        }

        boolean isSupportWebp = isWebView? isWebViewSupportWebp(): isSupportWebp();
        boolean isSupportWebpAnimation = isWebView? isWebViewSupportWebpAnimation(): isSupportWebpAnimation();

        if (supportConvertWebP(url) && isSupportWebp) {
            String ext = MimeTypeMap.getFileExtensionFromUrl(url);
            if (TextUtils.isEmpty(ext) || (ext.contains("gif") && !isSupportWebpAnimation)) //扩展名为空就不知道是什么鬼,不转
                return url;

            if (url.contains("?")) {
                if (url.contains("format/jpg")) {
                    return url.replace("format/jpg", "format/webp");
                }

                int index = url.indexOf("gif");
                if (index != -1) {
                    return url.substring(0, index) + "gif" + WebpExtGif;
                }
                return url + WebpExtDefault;
            } else {
                String query = ext.contains("gif") ? WebpExtGif : getWebpExtBaseScreen();
                int index = url.indexOf(ext);
                return url.substring(0, index) + ext.split("-")[0] + query;
            }
        }
        return url;
    }

    public static boolean isWebP(String url) {
        return url.contains("/format/webp") || url.contains("-Webp");
    }

    public static boolean supportConvertWebP(String url) {
        return MManagerCenter.getManager(DevConfigManager.class).isUseWebp() && isQiNiuImageHost(url) && !url.contains("/format/webp") && !url.contains("-Webp");
    }

    //获取文章的host
    public static String getHost(String url) {
        if (url == null || url.trim().equals("")) {
            return "";
        }
        String host = "";
        Pattern p = Pattern.compile("(http://|https://)?([^/]*)", Pattern.CASE_INSENSITIVE);
        Matcher matcher = p.matcher(url);
        if (matcher.find()) {
            host = matcher.group();
        }
        return host;
    }

    public static boolean isQiNiuImageHost(String url) {
        String host = getHost(url);
        return host.equals("http://img.qdaily.com");
    }

    public static String getWebpExtBaseScreen(){
        int width = LocalDisplay.SCREEN_REAL_WIDTH_PIXELS;
        if (width >= 1080) {
            return WebpExtW3;
        }
        if (width < 540) {
            return WebpExtW1;
        }
        return WebpExtW2;
    }

    public static boolean isWebViewSupportWebp(){
        return MManagerCenter.getManager(QDConfigManager.class).isWebViewSupportWebp();
    }

    public static boolean isWebViewSupportWebpAnimation(){
        return MManagerCenter.getManager(QDConfigManager.class).isWebViewSupportWebpAnimation();
    }

     // Native默认支持WebP静图
    public static boolean isSupportWebp(){
        return true;
    }

    // TODO: 16/7/15  所有列表页,最终会用ImageView渲染的,暂时不支持webp animated
    public static boolean isSupportWebpAnimation(){
        return false;
    }

2、WebView部分的WebP

依据预加载和缓存的内需,QDaily的稿子选用的主意是经过接口下载html文件,在该地加载进webview的法门来贯彻的,具体方法如下:

loadDataWithBaseURL(curUrl, "html string", "text/html", "UTF-8", curUrl);

因为android的WebView能够一向解码WebP格式,所以那边直接进行了html中的url替换,即正则取出全体的image请求url,用地点的getWebpUrl的法子开始展览转移,再交替原来的url即可。具体落真实境况势如下:

public static String converHtmlToWebPHtml(String html){
   Map<String, String> map = getSupportWebPImgArray(html);
    if (map != null && map.size() > 0) {
        for (Map.Entry<String,String> entry: map.entrySet()) {
            html = html.replaceAll(entry.getKey(), entry.getValue());
      }
   }
    return html;
}

private static Map<String, String> getSupportWebPImgArray(String html) {
    if (!(isWebViewSupportWebp() || isWebViewSupportWebpAnimation()) && TextUtils.isEmpty(html))
        return null;

    Map<String, String> result = new HashMap<>();
    Pattern p = Pattern.compile("<img[^>]*data-src=\"([^\"]*)\"[^>]*>");
    Matcher m = p.matcher(html);
    while (m.find()) {
        String url = m.group(1);
        String value = getWebpUrl(url, true);
        if (!url.equals(value)) result.put(url, getWebpUrl(url, true));
    }
    p = Pattern.compile("<img[^>]*src=\"([^\"]*)\"[^>]*>");
    m = p.matcher(html);
    while (m.find()) {
        String url = m.group(1);
        String value = getWebpUrl(url, true);
        if (!url.equals(value)) result.put(url, getWebpUrl(url, true));
    }
    return result;
}

3、判断Android端WebView对WebP Animated的支持

官方称4.3上述系统直接扶助WebP
Animated,但亲测部分金立手提式有线电话机(例如索爱!)在4.4的EMUI中WebView不可能符合规律解码WebP
Animated,消除方案是在App首回运行时举行WebView的WebP支持情状检查,并将值保存在sp中。

检检查办理法为在WebView中分头加载1像素的WebP静图和动图,并用JS检查和测试是或不是中标展现,成功体现即为帮衬。

直白上代码:

<html>  
<head>  
<meta charset="UTF-8" />  
<title>WEBP TEST</title>
<script type="text/javascript">  
;(function() {
    var image = new Image();
            image.onerror = function() {
                console.log('QDaily:supportWebp=false')
            };
            image.onload = function() {
                if (image.width == 1) {
                    console.log('QDaily:supportWebp=true')
                } else {
                    console.log('QDaily:supportWebp=false')
                }
            } 
            image.src = 'data:image/webp;base64,UklGRiwAAABXRUJQVlA4ICAAAAAUAgCdASoBAAEAL/3+/3+CAB/AAAFzrNsAAP5QAAAAAA=='; 
})();

;(function() {
    var image = new Image();
    image.onerror = function() {
        console.log('QDaily:supportWebpAnimation=false')
    };
    image.onload = function() {
        if (image.width == 1) {
            console.log('QDaily:supportWebpAnimation=true')
        } else {
            console.log('QDaily:supportWebpAnimation=false')
        }
    }
    image.src = 'animation.webp';
})();        
</script>   
</head>  
<body>
</body>  
</html>

内部,第①个js方法用来检查和测试是还是不是扶助静态webp,src对应一段webp图片的base64编码,呈现出来的大幅为1px。第二个点子src对应贰个动态webp,由于animated
webp的base64相比较长,所以直接将2个1k的1px宽的webp
animation和那段html一起放在了assets中,用于调用检查和测试。

上边说将html文件以及所用到的图纸都置身 assets
目录下。然后在页面上通过WebView来显示。上边上webview的检查和测试代码:

//以下代码放在第一个启动的Activity中
private WebView webView;//必须成员变量,临时变量无效
private void checkWebpSupport(){
    if (isInitWebViewCheckSupportWebp)
        return;

    webView = new WebView(this);
    webView.setWebChromeClient(new WebChromeClient() {
        @Override
        public boolean onConsoleMessage(ConsoleMessage cm) {
            String log = cm.message();
            if (!TextUtils.isEmpty(log) && log.contains("QDaily:")) {
                if (log.equals("QDaily:supportWebp=true")) {
                    setWebViewSupportWebp(true);
                } else if (log.equals("QDaily:supportWebp=false")) {
                    setWebViewSupportWebp(false);
                } else if (log.equals("QDaily:supportWebpAnimation=true")) {
                    setWebViewSupportWebpAnimation(true);
                } else if (log.equals("QDaily:supportWebpAnimation=false")) {
                    setWebViewSupportWebpAnimation(false);
                }
                isInitWebViewCheckSupportWebp = true;
            }
            return true;
        }
    });
    //注意下面这行一定要加,否则js不能执行!
    webView.getSettings().setJavaScriptEnabled(true);
    webView.loadUrl("file:///android_asset/webp.html");
}

叁 、别的财富的缓存优化

QDaily在互连网请求小编的优化主要有对http请求的gzip压缩,和对图片大小和格式的定制化(依据荧屏尺寸请求大小,依照客户端意况选用是或不是WebP)。
其余一些在流量的优化都在缓存部分,为的是相同能源不再请求第一次。上面将不难介绍那里,一些有血有肉的部分会在以后文章再做展开。

联合图片的当地缓存处理

三个app中,WebView和ImageView都会呈请图片,Android端和iOS端都定制了协调统一的内部存款和储蓄器LRU
Cache和Disk LRU Cache进行处理,制止重新请求。

css和js的缓存

QDaily里小说用了统一的css和js文件。客户端这边主要开始展览缓存和复用,以进行重复使用

http请求的缓存

此地关键是将volley的缓存管理起来,通过etag进行立异判断

地点介绍的相比范,前面会有相比较具体的牵线。


参照链接

http://chiemy.com/android/android-webp

http://hahack.com/wiki/sundries-webp.html

http://blog.teamtreehouse.com/getting-started-webp-image-format

谷歌(谷歌)官方文档扶助
https://developers.google.com/speed/webp/

http://www.smarting.me/glide-images-loading-library-introduction-and-usage.html