目前移动端运营素材大部分依赖图片,基于对图片流量更少,渲染速度更快的诉求,我们推动CDN,X5内核,即通产品部共同推出了一套业务透明,无痛接入的CDN图片优化方案:基于CDN的sharpP自适应图片无痛接入方案。据统计效果可在原图基础上节省60%-75%的流量,比之前webP无痛接入方案效果提升40%-50%,减少流量的同时提高页面渲染速度,提升用户体验。

效果数据

目前手Q增值业务:VIP中心、游戏中心、动漫、游戏公会、特别关心 以及增值渠道的QQ钱包,空间的个性化商城已经接入sharpP自适应,优化效果数据:

sharpP自适应方案在原有webP自适应方案效果提升40%-50%,提升效果主要来自sharpP高于webP的编码压缩率,同时能优化到webP无法覆盖的png图片(备注:之前webP无痛方案只实现了jpg的支持),sharpP方案和原图对比可以节省60%-75%的流量。

以我们的VIP中心为例,之前webP方案:

上sharpP方案后

在图片增加的情况下 图片流量减少了近100K,页面速度也有提升,并且sharpP图片的效果也经过设计同学的验证,肉眼几乎无法区分,图片质量参数细节后面会介绍。

方案概述

利用自建CDN结点的缓存,以及带请求头的回源能力做到同一个URL根据终端分辨率,以及是否支持sharpP解码,按需返回不同的原图副本,做到图片资源的最合理利用:
手Q X5内核支持sharpP图片的解码,请求图片时会带上accept: image/sharpp标识,User-Agent中会加上手机的分辨率Pixel参数,CDN节点收到请求后,先检查如果有对应的sharpP自适应副本直接返回,如果没有则将请求回源到CDN源站,源站会根据请求的User-Agent、Accept参数返回对应分辨率的sharpP图片副本(原图上传后,或第一个用户请求触发CDN源站服务器图片转换,生成不同尺寸的sharpP图片), 如果请求头没有sharpP标识,则按原有逻辑返回原图,不影响业务。

整套优化方案接入对基于X5内核的H5业务完全透明,无需改动代码,即可让页面的图片获得可观的图片专项优化效果;app业务接入,音视频有提供sharpP解码的sdk的接入。

方案详解

1.何为sharpP

sharpP是腾讯公司SNG即通产品部音视频技术中心推出的一种图片压缩组件,现已支持iOS、Android、Windows、Linux四个平台。编码压缩率、编码耗时、解码耗时相比webP有明显的优势。

2.CDN sharpP方案

在原有webP自适应无痛方案基础上,我们联合终端、CDN进一步升级优化,做了如下优化改造:
终端支持:增值业务大部分是基于手Q webview的hybird应用,安卓平台基于X5内核,X5内核于2.1.1版本开始引入了sharpP组件,支持sharpP解码,并约定支持sharpP的版本发起的请求会在http请求的头部带上Accept: image/sharpp字段,同时X5内核UA中会带上终端分辨率Pixel字段,iOS平台由于系统对webview内核的限制,暂时无法很好的嵌入sharpP组件,未能支持sharpP解码。未来可以在原生app引入sharpP组件,原生请求带上Accept:image/sharpp,就可以使用到CDN的sharpP能力。

CDN侧改造:CDN源站转换工具集成了sharpP组件,CDN的OC结点新增支持 sharpP副本的缓存,整体流程大致如下:

客户端发起请求后,OC结点根据请求UA检查Accept字段是否带有image/sharpp,并获取Pixel分辨率信息,OC结点判断是否有满足要求的原图副本缓存,没有缓存则将URL+请求头回源,源站识别请求头中的信息,返回图片对应的sharpP副本,OC结点缓存下来。源站图片如果未转换完成(图片上传后或第一次请求触发CDN源站异步转换),源站会先返回原图,max-age=10,让OC结点暂时不缓存,再次请求时,判断转换完成才返回sharpP图片并设置默认的缓存时间max-age=25920000。目前CDN sharpP已支持了我们BGtop5流量的域名:

imgcache.gtimg.cn、i.gtimg.cn、imgcache.qq.com、qzonestyle.gtimg.cn、qzs.qq.com

整体方案:结合之前我们做的自适应、webP方案,与sharpP可以完全兼容,在CDN源站是3项单独的配置,可以按需配合或单独使用,整体方案如下图

优先判断是否有自适应,然后检查sharpP,如果sharpP和webP都支持优先返回sharpP。

3.项目中踩过的坑

1)运营商内容劫持,由于同一个URL可能返回不同的内容(不同分辨率的sharpP/原图) 线上观察发现联通运营商会在请求到我们自建CDN结点之前加一层缓存,默认会按URL来缓存内容,其实就是内容劫持,导致不同请求头,返回错乱与我们期望的不一致,后面找到一种解决方法,基于http协议的vary字段,CDN源站以及CDN结点返回内容的时候带上 Vary:User-Agent,Accept 字段,告诉运营商的缓存服务器根据请求的Accept+User-Agent+Url来缓存内容,经验证可以解决问题。
2)质量参数设置,尽可能保证图片压缩的更小,效果与原图差距不大
sharpP采用有损压缩,转换工具会读取原图质量参数,适当降低:如果原图质量参数低于75则保持原质量参数直接转sharpP,如果质量参数高于75,则在原图基础上降低一些质量参数,根据业务要求自行设置,目前根据观察质量参数不低于75的sharpP图片基本肉眼无法区分。
3)新的业务开启sharpP自适应,源站图片转换导致磁盘IO压力过大
用脚本凌晨闲时对存量图片预转换生成各尺寸的副本;转换工具监听图片目录的新增文件,用户上传后就做转换;转换脚本做了优化,只有第一次请求触发转换。
4)sharpP转换工具对某些图片转换失败,生成空文件
捕获转换失败错误码,空文件用原图替换,避免返回给结点空文件
5)有时候业务图片需要强制使用原图
支持nosharpp参数,url带上参数后,CDN强制返回原图。
6)图片缓存清理
由于一 个图片URL,对应了多份CDN结点缓存副本,如果图片更新的时候,可能有个别副本缓存刷新不及时,导致不同分辨率、sharpP、原图的用户看到的图片不一致,需要优化CDN缓存刷新工具,支持一次清理所有缓存副本。
以上皆为项目推进中遇到的问题,未考虑周全可能就会影响功能,线上实施前得在测试结点充分验证,结点部署要控制节奏,并且要有完善的线上监控机制,以及功能回退的能力。

4.图片检测监控

1)为了提高接入效率,减少人工验证步骤,我们开发了图片检测监控工具,定时监控业务页面图片在各OC结点返回是否正常。原理:工具根据业务URL,抓取页面内所有CDN域名的图片,随机抽取一部分OC结点,构造sharpP,webP,原图3种请求,根据返回的图片格式,大小对比验证图片是否正常。

2)现网图片加载数据上报:为了监控更多用户的图片加载真实数据,我们在业务中接入了图片加载上报组件,原理是利用X5内核收集的资源加载信息,过滤出图片信息,上报图片类型,返回码,加载耗时,网络类型等。

5.sharpP开启验证

上传一张新图片,使用手Q安卓版本访问已支持sharpP域名的CDN图片,如果请求带了Accept:image/sharpp,检查返回图片格式是否为sharpP


如果旧的图片未按预期返回,返回了webP或原图可能是OC结点缓存,正常3天后过期回源则会返回sharpP图片。

未来规划

1)app业务接入sharpP优化方案目前只有安卓平台基于X5内核的应用能得到这套CDN sharpP方案的优化效果,根据CDN日志的流量统计BG内最大的流量还是来自终端发起的请求,后续我们计划联合CDN大流量的终端业务接入sharpP解码组件,让这套方案能给更多业务带来收益,同时也为公司和用户节省流量成本。
2)sharpP工具优化 sharpP组件在不断优化,包括转码效率、成功率,gif格式支持等,CDN转换工具也将迭代支持。

相关推荐

借助腾讯云CDN开启全站https及问题解决分享

腾讯云CDN产品相关文档


此文已由作者授权腾讯云技术社区发布,转载请注明文章出处,获取更多云计算技术干货,可请前往腾讯云技术社区,当然我们也会在博客园持续同步更新~

微信公众号:腾讯云技术社区( QcloudCommunity)

图片流量节省大杀器:基于腾讯云CDN的sharpP自适应图片技术实践的更多相关文章

  1. 图片流量节省大杀器:基于CDN的sharpP自适应图片技术实践

    版权声明:本文由陈忱原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/156 来源:腾云阁 https://www.qclou ...

  2. 使用docker-compose 大杀器来部署服务 上

    使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 ...

  3. 使用docker-compose 大杀器来部署服务 上(转)

    使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 ...

  4. [NewLife.XCode]反向工程(自动建表建库大杀器)

    NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...

  5. 一文读懂机器学习大杀器XGBoost原理

    http://blog.itpub.net/31542119/viewspace-2199549/ XGBoost是boosting算法的其中一种.Boosting算法的思想是将许多弱分类器集成在一起 ...

  6. [转]使用docker-compose 大杀器来部署服务 上

    本文转自:https://www.cnblogs.com/neptunemoon/p/6512121.html 使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker ...

  7. 离群点检测与序列数据异常检测以及异常检测大杀器-iForest

    1. 异常检测简介 异常检测,它的任务是发现与大部分其他对象不同的对象,我们称为异常对象.异常检测算法已经广泛应用于电信.互联网和信用卡的诈骗检测.贷款审批.电子商务.网络入侵和天气预报等领域.这些异 ...

  8. 使用docker-compose 大杀器来部署服务

    使用docker-compose 大杀器来部署服务 上 我们都听过或者用过 docker,然而使用方式却是仅仅用手动的方式,这样去操作 docker 还是很原始. 好吧,可能在小白的眼中噼里啪啦的对着 ...

  9. Postgresql-模糊匹配大杀器

    # Postgresql-模糊匹配大杀器 ## 问题背景 随着pg越来越强大,abase目前已经升级到5.0(postgresql10.4),目前abase5.0继承了全文检索插件(zhparser) ...

随机推荐

  1. 字符集 ISO-8859-1(2)

    HTML 支持的数学符号 结果 描述 实体名称 实体编号 ∀ for all ∀ ∀ ∂ part ∂ ∂ ∃ exists &exists; ∃ ∅ empty ∅ ∅ ∇ nabla ∇ ...

  2. 扩展BaseAdapter实现不存储列表项的ListView

    下面的实例将会通过扩展BaseAdapter来实现Adapter,扩展BaseAdapter可以取得对Adapter最大的控制权:程序要创建多个列表项,每个列表项的组件都由开发者来决定. 下面的布局文 ...

  3. HTML5 简介、浏览器支持、新元素

    什么是 HTML5? HTML5 是最新的 HTML 标准. HTML5 是专门为承载丰富的 web 内容而设计的,并且无需额外插件. HTML5 拥有新的语义.图形以及多媒体元素. HTML5 提供 ...

  4. HTML 颜色

    HTML 颜色 HTML 颜色由红色.绿色.蓝色混合而成. 颜色值 HTML 颜色由一个十六进制符号来定义,这个符号由红色.绿色和蓝色的值组成(RGB). 种颜色的最小值是0(十六进制:#00).最大 ...

  5. 《你不知道的js》 ------1.作用域是什么

    相关定义 引擎:从头到尾负责整个JavaScript程序的编译及执行过程. 编译器:负责语法分析及代码生成等. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规 ...

  6. Quill编辑器介绍及扩展

    从这里进入官网. 能找到这个NB的编辑器是因为公司项目需要一个可视化的cms编辑器,类似微信公众号编辑文章.可以插入各种卡片,模块,问题,图片等等.然后插入的内容还需要能删除,拖拽等等.所以采用vue ...

  7. js之Math对象

    ; var num1 = Math.floor(num); // 向下取整 var num2 = Math.ceil(num); // 向上取整 document.write(num2+'-<b ...

  8. C++编程练习(2)----“实现简单的线性表的链式存储结构“

    单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素. 对于查找操作,单链表的时间复杂度为O(n). 对于插入和删除操作,单链表在确定位置后,插入和删除时间仅为O(1). 单链表不需要分配存储 ...

  9. c#中读取数据库bit布尔字段数据转换Int和bool时的错误

    数据库里bit这个布尔类型的字段,非常实用,但是在c#里读取时,许多人喜欢犯一些错误,导致运行报错. 实际中,有效的正确读取方法只有以下两种: int xxx= Convet.ToInt16(read ...

  10. 关于hashmap的底层实现

    注:以下内容并非基于最新的jdk版本 q1:hashmap为什么叫hashmap? 答:hashmap基于hashtable(不是hashtable类)实现. q2:hashtable(不是hasht ...