大家可以尝试去掉封装EventTarget.prototype.addEventListener的那段代码,感受下。
上报接口
为什么不能直接用GET/POST/HEAD请求接口进行上报?
这个比较容易想到原因。一般而言,打点域名都不是当前域名,所以所有的接口请求都会构成跨域。
为什么不能用请求其他的文件资源(js/css/ttf)的方式进行上报?
创建资源节点后只有将对象注入到浏览器DOM树后,浏览器才会实际发送资源请求。而且载入js/css资源还会阻塞页面渲染当前页面的脚本发生错误,影响用户体验。
构造图片打点不仅不用插入DOM,只要在js中new出Image对象就能发起请求,而且还没有阻塞问题,在没有js的浏览器环境中也能通过img标签正常打点。
使用new Image进行接口上报。最后一个问题,同样都是图片,上报时选用了1x1的透明GIF,而不是其他的PNG/JEPG/BMP文件。
首先,1x1像素是最小的合法图片。而且当前页面的脚本发生错误,因为是通过图片打点,所以图片最好是透明的,这样一来不会影响页面本身展示效果,二者表示图片透明只要使用一个二进制位标记图片是透明色即可,不用存储色彩空间数据,可以节约体积。因为需要透明色,所以可以直接排除JEPG。
同样的响应卡盟,GIF可以比BMP节约41%的流量,比PNG节约35%的流量。GIF才是最佳选择。
使用1\*1的gif[1]
非阻塞加载
尽量避免SDK的js资源加载影响。
通过先把window.onerror的错误记录进行缓存,然后异步进行SDK的加载,再在SDK里面处理错误上报。
"en">
<script> (function(w) {
w._error_storage_ = [];
function errorhandler(){
// 用于记录当前的错误
w._error_storage_&&w._error_storage_.push([].slice.call(arguments));
}
w.addEventListener && w.addEventListener("error", errorhandler, true);
var times = 3,
appendScript = function appendScript() {
var sc = document.createElement("script");
sc.async = !0,
sc.src = './build/skyeye.js', // 取决于你存放的位置
sc.crossOrigin = "anonymous",
sc.onerror = function() {
times--,
times > 0 && setTimeout(appendScript, 1500)
},
document.head && document.head.appendChild(sc);
};
setTimeout(appendScript, 1500);
})(window); </script>
<body>
这是一个测试页面(new)