抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

为什么前端监控要用 GIF 打点

2019 年 9 月 25 日

为什么前端监控要用GIF打点

1 背景

灯塔是贝壳找房前端架构组推出的一款前端监控系统, 最近和业务方对接时, 被问到了这样一个问题:


为什么前端监控要用 GIF 打点?


这个问题很有意思。我们知道,目前主流的前端监控(百度统计/友盟/谷歌统计)都在用 GIF 进行打点。但是,为什么这些系统都会使用 GIF,难道是因为没有其他的解决方案吗?


这得从前端监控的原理说起。


2 前端监控的原理

所谓的前端监控,其实是在满足一定条件后,由 Web 页面将用户信息(UA/鼠标点击位置/页面报错/停留时长/etc)上报给服务器的过程。一般是将上报数据用 url_encode(百度统计/CNZZ)或 JSON 编码(神策/诸葛 io)为字符串,通过 url 参数传递给服务器,然后在服务器端统一处理。


这套流程的关键在于:


1)能够收集到用户信息;


2)能够将收集到的数据上报给服务器。也就是说,只要能上报数据,无论是请求 GIF 文件还是请求 js 文件或者是调用页面接口,服务器端其实并不关心具体的上报方式。


向服务器端上报数据,可以通过请求接口,请求普通文件,或者请求图片资源的方式进行。为什么所有系统都统一使用了请求 GIF 图片的方式上报数据呢?



可能的方式


3 为什么主流方案用 GIF 上报数据

解答这个问题,要用排除法。


首先,为什么不能直接用 GET/POST/HEAD 请求接口进行上报?


这个比较容易想到原因。一般而言,打点域名都不是当前域名,所以所有的接口请求都会构成跨域。而跨域请求很容易出现由于配置不当被浏览器拦截并报错,这是不能接受的。所以,直接排除。



可能的方式_排除接口请求


其次,为什么不能用请求其他的文件资源(js/css/ttf)的方式进行上报?


这和浏览器的特性有关。通常,创建资源节点后只有将对象注入到浏览器 DOM 树后,浏览器才会实际发送资源请求。反复操作 DOM 不仅会引发性能问题,而且载入 js/css 资源还会阻塞页面渲染,影响用户体验。


但是图片请求例外。构造图片打点不仅不用插入 DOM,只要在 js 中 new 出 Image 对象就能发起请求,而且还没有阻塞问题,在没有 js 的浏览器环境中也能通过 img 标签正常打点,这是其他类型的资源请求所做不到的。


所以,在所有通过请求文件资源进行打点的方案中,使用图片是最好的解决方案。



可能的方式_排除文件请求


那还剩下最后一个问题,同样都是图片,上报时选用了 1x1 的透明 GIF,而不是其他的 PNG/JEPG/BMP 文件。


这是排除法的最后一步,原因其实不太好想,需要分开来看。


首先,1x1 像素是最小的合法图片。而且,因为是通过图片打点,所以图片最好是透明的,这样一来不会影响页面本身展示效果,二者表示图片透明只要使用一个二进制位标记图片是透明色即可,不用存储色彩空间数据,可以节约体积。因为需要透明色,所以可以直接排除 JEPG(BMP32 格式可以支持透明色)。


然后还剩下 BMP、PNG 和 GIF,但是为什么会选 GIF 呢?


因为体积!


下方是 1x1 像素透明图,最小的 BMP/PNG/GIF 文件结构。


BMP:



BMP


PNG:



PNG


GIF:



GIF


可以看到,最小的 BMP 文件需要 74 个字节,PNG 需要 67 个字节,而合法的 GIF,只需要 43 个字节。


同样的响应,GIF 可以比 BMP 节约 41%的流量,比 PNG 节约 35%的流量。这样比较一下,答案就很明显了。


上报数据,显然 GIF 才是最佳选择。



可能的选择_最终结果


##4 总结


前端监控使用 GIF 进行上报主要是因为:


  • 没有跨域问题;

  • 不会阻塞页面加载,影响用户体验;

  • 在所有图片中体积最小,相较 BMP/PNG,可以节约 41%/35%的网络资源。


最后,感谢提供支持的各位大佬:


@周晨 提出了这个问题;


@大董 指出加载图片不需要操作 DOM,性能更好;


@CC 老师 指出在没有 JS 的环境中,只有图片打点才能正常工作(GET 方式需要用户触发);


@丸九 介绍了各种图片格式的特点,解释了为什么一定要 1 像素透明图;


@伍子胥 查阅了网上的资料,并确认关键因素:文件体积。


作者介绍:


大布(企业代号名),目前负责贝壳找房前端开发工作。


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/v6R2w26qZkEilXY0mPUBCw


2019 年 9 月 25 日 23:271574

评论 1 条评论

发布
用户头像
服务器直接响应 content-type image/gif 呢?
2019 年 09 月 27 日 17:01
回复
没有更多了
发现更多内容

1.Flink检查点算法-15

小知识点

scala 大数据 flink

数据分析之伯克森谬误:颜值和性格真成反比吗

KAMI

人生 数据分析 数据

C/C++函数指针与指针函数

C语言与CPP编程

c++ C语言 函数指针

C语言与C++常见面试题

C语言与CPP编程

c++ 面试题 C语言

GPU虚拟机创建时间深度优化

滴滴技术

云计算 虚拟化 滴滴技术

滴滴数据通道服务演进之路

滴滴技术

大数据 滴滴技术 数据服务通道

实时数仓在滴滴的实践和落地

滴滴技术

大数据 滴滴技术 数据通道服务

【Spring注解驱动开发】AOP核心类源码解析,这是最全的一篇了!!

冰河

spring aop ioc

架构师训练营0期 第十二周作业

WW

可编程网卡芯片在滴滴云网络的应用实践

滴滴技术

云计算 芯片 滴滴技术

滴滴Ceph分布式存储系统优化之锁优化

滴滴技术

云计算 分布式存储 Ceph 滴滴技术

物联网的银河,华为的桨,少年的歌

脑极体

缓冲区溢出

C语言与CPP编程

c++ C语言 缓冲区 堆栈溢出

突破传统 区块链如何实现病历永存

CECBC区块链专委会

区块链 电子病历 信息共享

自定义线程池来实现文档转码

架构师修行之路

【高并发】要想学好并发编程,关键是要理解这三个核心问题

冰河

写作 多线程 高并发 同步 分工

滴滴数据仓库指标体系建设实践

滴滴技术

大数据 数据仓库 滴滴技术

滴滴七层接入平台实践和探索

滴滴技术

运维 滴滴技术 微服务治理 七层接入

Redis做消息队列全攻略

架构师修行之路

redis MQ 消息队列

在Rust里面嵌入python代码

lipi

Python rust

指针变量的传值和传址

C语言与CPP编程

c++ 指针 C语言

基于Prometheus的微服务应用监控

易观大数据

滴滴推理引擎IFX:千万规模设备下AI部署实践

滴滴技术

人工智能 学习 AI 滴滴技术 IFX

Zeppelin SDK :Flink 平台建设的基石

Apache Flink

flink

分布式QoS算法解析

焱融科技

分布式 算法 焱融科技 分布式文件存储 QoS

拥抱K8S系列-03-服务器部署应用和docker部署应用区别(MySQL篇)

张无忌

MySQL Docker 运维

滴滴ElasticSearch千万级TPS写入性能翻倍技术剖析

滴滴技术

大数据 elasticsearch 滴滴技术

第 0 期架构师训练营第 8 周作业2-总结

傅晶

滴滴云平台事业群——就是稳!

滴滴技术

招聘 滴滴技术 滴滴云平台事业群分享月

c语言函数指针之回调函数

C语言与CPP编程

C语言 回调函数 函数 函数指针

区块链技术成为金融业务应用热点

CECBC区块链专委会

区块链 人工智能 金融

Study Go: From Zero to Hero

Study Go: From Zero to Hero

为什么前端监控要用GIF打点-InfoQ