NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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:398569
用户头像

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

关注

评论

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

低代码实现探索(二十六)移动端H5开发

零道云-混合式低代码平台

简单的线程池实现多线程对大文件的读取

CRMEB

云信小课堂|如何实现音视频安全检测?

网易云信

安全 音视频

精彩回顾!| Google DevFest 2021 广州国际嘉年华

江湖老铁

喜报!东方证券携手博睿数据荣获《金融电子化》2021科技赋能金融业务突出贡献奖

博睿数据

消息队列 RocketMQ 遇上可观测:业务核心链路可视化

阿里巴巴云原生

阿里云 RocketMQ 云原生 消息队列 可观测

OpenMLDB在AKULAKU实时特征计算场景的应用

第四范式开发者社区

机器学习 大数据 OpenMLDB 特征平台

征文投稿丨使用轻量应用服务器部署Hadoop云集群

阿里云弹性计算

hadoop 轻量应用 征文投稿

明道云助力东航食品营销数据整合

明道云

销量之王,去年程序员最爱看的技术书就是它!

博文视点Broadview

架构实战营:模块六作业

Geek_93ffb0

「架构实战营」

浪花过后,2022低代码该往哪儿走?

ToB行业头条

女生不适合当程序员?XTransfer这位程序员妈妈绝了!生娃半年内升职加薪

XTransfer技术

技术人 程序媛 XTransfer

低代码实现探索(二十七)低代码如何继承传统

零道云-混合式低代码平台

通证经济是更高层次的自由

CECBC

使用hydra对端口进行爆破

喀拉峻

Flink 实践教程-进阶(7):基础运维

腾讯云大数据

flink 实战 流计算 Oceanus

mark: mac 开启chrome webrtc 日志

webrtc developer

chrome WebRTC

使用APICloud AVM框架开发预约应用

YonBuilder低代码开发平台

前端框架 APP开发 APICloud 跨端开发 小程序开发

RadonDB PostgreSQL on K8s 2.1.0 发布!

RadonDB

数据库 postgresql 开源 RadonDB

Redis OM .NET Redis对象映射框架

MASA技术团队

C# .net 微软 后端 redis'

【网络研讨会】“专家面对面”-MongoDB模式设计

MongoDB中文社区

mongodb

流计算 Oceanus | Flink JVM 内存超限的分析方法总结

腾讯云大数据

flink 实战 流计算 Oceanus

markdown-it 插件如何写(二)

冴羽

前端 markdown vuepress markdown-it markdown-it插件

Nacos电子书 读后感(一)

努力努力再努力

1月日更

网络安全kali渗透学习 web渗透入门 ARL资产侦察灯塔系统搭建及使用

学神来啦

12月云短信报告出炉,阿里云闯进前三

博睿数据

用11本白皮书搭建3座桥:联想企业科技集团让智能化转型不再有孤岛

脑极体

哲元科技×飞桨EasyDL|助力世界500强企业打造“灯塔工厂”,探索智能制造星辰大海

百度大脑

i人事CTO王景飞:i人事+计算巢,协同赋能HR业务

阿里云弹性计算

阿里云 计算巢

安全研究人员发现:Nanocore等多个远控木马滥用公有云服务传播

H

网络安全

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