【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

Facebook 移动端照片预览背后的技术

  • 2015-08-14
  • 本文字数:1578 字

    阅读完需:约 5 分钟

当在 Facebook 移动端上浏览某个人的用户资料或页面时,首先看到的往往是图片。这些图片是构成 Facebook 体验不可缺少的一部分,但有时候,图片的下载与展示非常慢,在低速或移动网络中尤其如此。而在像印度这样的发展中国家市场上,许多 Facebook 新用户主要是使用 2G 网络。近日,Facebook 工程师 Brian K Cabral Edward Kandrot 撰文描述了Facebook 解决这一问题的过程。

封面照片是屏幕上最显眼的部分,但它也是加载最慢的部分之一。这主要有两个原因:一是封面照片的大小常常达到100KB,而2G 连接的传输速度可能只有32KB/ 秒;二是应用程序需要发送两个网络请求才能显示封面照片。它首先向 GraphQL 服务器发送请求,获得照片 URL,然后发送第二个网络请求,使用该 URL 从 CDN 获取照片。第二个网络请求的延迟相当长,比第一个长许多。

为了解决上述问题,他们希望能够由原照片生成一张 200 字节大小的效果图,然后将其作为 GraphQL 响应的一部分在第一次请求应答中直接返回,这样可以省掉第二次请求,极大地缩短用户资料和页首的显示延迟。当然,他们最终还是要从 CDN 下载完整照片并进行展示,但这可以在后台进行。至此,问题变成如何将照片压缩成 200 字节。

他们希望照片的效果图有一种磨砂玻璃的效果。这既有趣,又能与原始照片保持一致。磨砂玻璃效果采用高斯滤波器比较容易实现,而且图片越模糊,分辨率就越低,图片的尺寸就越小。不过,为了提供良好的用户体验,分辨率也不能太低。通过多次尝试,他们得出,42x42 的图片可以达到他们想要的效果,而分辨率再高一些并不会带来更好的效果。但是,即使只显示图片的DC 分量,每个像素仍然需要3 个字节,那么42x42x3 就是5292 字节,远远超出200 字节的目标。

他们开始评估标准的压缩技术,试图找出一种最好的方法,将数据压缩至200 字节。遗憾的是,只是对图片进行熵编码(比如 zlib )的话,只能将图片压缩一半,仍然太大。他们还评估了其它若干非标准技术,但最终,他们决定试一下 JPEG 图像编码。遗憾的是,JPEG 头本身就有几百个字节的大小。不过,去掉 JPEG 头,编码的数据有效负荷接近 200 字节。

于是,他们开始探索,JPEG 图片是否有可能使用一个固定的头,那样就可以将其存储在客户端,而不需要传输。JPEG 头包含多个表。在 Q 值一定的情况下,量化表是不变的。通过试验,他们发现,Q20 生成的图片可以满足他们的要求。虽然他们的图片不是固定尺寸,但基本上都限制在 42x42 以下。他们还仔细查看了 JPEG 头中的其它内容,发现只有 Huffman 表会随着图片的不同发生变化。Q 值、图片数据及图片尺寸决定着 Huffman 表中的频率值,每一项变化都会导致不同的压缩比和有效负荷字节数。他们在一组图片上进行了试验,并最终找出了一个可以作为标准的 Huffman 表。

虽然他们处理了大量的图片,但总有一些该方案不适用的情况。为此,他们增加了一个版本号。如果发现任何极端情况,或者未来发现了更好的 Huffman 表,那么他们就可以更新相关图片的版本号,并将新表发送给客户端。最终的格式包含一个字节的版本号、一个字节的宽度、一个字节的高度和大约 200 字节的有效负荷。服务器只将这一格式作为 GraphQL 响应的一部分发送,然后由客户端将 JPEG 体附加到预定义的 JPEG 头上,生成一个普通的 JPEG 图片。经过标准的 JPEG 解码后,客户端可以运行预定的高斯模糊,并拉伸其尺寸以适应窗口大小。

最终,他们获得一种可以满足需求的格式。在网速缓慢的情况下,这帮助他们将用户资料和页面加载时间缩短了 30%。而在网速非常快的情况下,这可以确保用户立即看到封面照片预览,提升了整体体验。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-08-14 08:398567
用户头像

发布了 1008 篇内容, 共 374.0 次阅读, 收获喜欢 340 次。

关注

评论

发布
暂无评论
发现更多内容

Koordinator 助力云原生应用性能提升:小红书混部技术实践

阿里巴巴云原生

阿里云 云原生 Koordinator

MSE Serverless 正式商用,构建低成本高弹性的微服务架构

阿里巴巴云原生

阿里云 微服务 云原生

独立于 Github,更方便地管理自己的静态网站?来试试这套自托管 Git 仓库方案!

快乐非自愿限量之名

git 网站

Calico IPIP模式下的Cross Subnet特性分析

华为云开发者联盟

开发 华为云 华为云开发者联盟

2023 年中国金融级分布式数据库市场报告:TiDB 位列领导者梯队,创新能力与增长指数表现突出

PingCAP

数据库 TiDB

多语言应用监控最优选,ARMS 应用监控 eBPF 版正式发布

阿里巴巴云原生

阿里云 云原生

看孙玲TEDX演讲有感

五月的风

轻松搭建基于服务网格的 AI 应用,然后开始玩

阿里巴巴云原生

阿里云 云原生 asm

TiDB 7.5 LTS 发版丨提升规模化场景下关键应用的稳定性和成本的灵活性

PingCAP

数据库 TiDB pingCAP

构建高效数据流转的 ETL 系统:数据库 + Serverless 函数计算的最佳实践

阿里巴巴云原生

阿里云 Serverless 云原生

2024值得关注的技术社区

南城FE

前端 技术社区 技术论坛

场外白名单达到1200U?Solana 生态铭文跨链桥 Sobit 是何神圣?

石头财经

2024 Python开发者转型Go开发

K8sCat

Python Go 语言

如何使用Rust进行系统编程?

程序饲养员

Linux 系统编程 LibC rust语言

linux系统,合并分区是需要重新安装系统吗

德迅云安全杨德俊

云原生场景下月省 10 万元资源成本,这家企业做对了什么

阿里巴巴云原生

阿里云 容器 云原生

TiDB 7.1 多租户在中泰证券中的应用

PingCAP

数据库 TiDB

日志框架简介-Slf4j+Logback入门实践 | 京东云技术团队

京东科技开发者

淘宝店铺订单接口丨天猫店铺订单接口丨淘宝店铺订单交易信息接口

tbapi

淘宝店铺订单接口 淘宝店铺交易接口 淘宝店铺订单交易接口

TiDB 助力保险业首个全栈自主的核心保单系统成功投产

PingCAP

数据库 TiDB 保险业

探索 Seata 项目开源开发之旅

阿里巴巴云原生

阿里云 云原生 seata

活动回顾丨云原生开源开发者沙龙深圳站回放 & PPT 下载

阿里巴巴云原生

阿里云 云原生

深入解读kubewharf项目:适用场景、优势与劣势 |社区征文

克莱因蓝

云原生 2023 #技术人的2023总结

0.1+0.2≠0.3,揭秘Python自带的Bug

程序员晚枫

Python

更顺畅的极狐GitLab安装升级体验来了,赶快尝鲜吧!

极狐GitLab

文心一言 VS 讯飞星火 VS chatgpt (166)-- 算法导论13.1 6题

福大大架构师每日一题

福大大架构师每日一题

无锡梁溪携手极视角共同举办2023无锡首届国际人工智能算法大赛

科技热闻

Solana 生态铭文跨链桥 Sobit 是何神圣?其场外白名单已达到1200U

BlockChain先知

活动回顾|阿里云云原生 Serverless 技术实践营深圳站回放 & PPT 下载

阿里巴巴云原生

阿里云 Serverless 云原生

高光回眸:阿里云容器服务如何全面助力精彩亚运

阿里巴巴云原生

阿里云 容器 云原生

QCN9074 and QCN6274: Get through the fog of technology and choose your communication partner

wallysSK

Facebook移动端照片预览背后的技术_Meta_谢丽_InfoQ精选文章