timesnap技术拆解
一些备注
两次截屏之间的间隙时间似乎可设置 addAnimationGapThreshold;不对,只针对动画?
核心:p = timeHandler.goToTimeAndAnimateForCapture(browserFrames, marker.time);
关键:改写浏览器时间函数、控制时间线
思考:时间线能倒退么?不能,注释明确写了不能
需要了解browserFrames这个对象,puppeteer 的 Frame 对象?
初始化 marker 数组
循环 marker
进入某个 marker
根据 marker.time,进入该时间点
转换为虚拟时间_timesnap_processUntilTime(ms)
_pendingBlocks 是为了阻塞?中间不做处理?
block的概念:
1 | |
感觉有点像是 JS 执行栈的概念,也是先进后出、后进先出。
执行期间,会不停往_pendingBlocks 中添加 block,因此每次执行完一个 block,都需要进行_sortPendingBlocks();
还是没找到它怎么放慢的、放多慢?
到底是 timesnap 放慢的还是 puppeteer 放慢的?读下 timesnap 文档
不是放慢,是阻塞!截图有多快,就看你的 CPU 有多强,这基本上就是各种文件操作和计算操作!
如何做到每一帧都执行截图操作的:_runAnimationFrames
如何插入_animationFrameBlocks 的:通过_requestAnimationFrame 插入的
goToTimeAndAnimateForCapture 返回的是个 Promise 实例,在这个实例的 then 方法中,执行截屏操作。
timesnap 通过 puppeteer 的 page.evaluateOnNewDocument()方法,给无头浏览器注入了一段立即执行函数,改写了诸如 requestAnimationFrame()等函数。
这是在页面一开始就执行的。
常见问题
为什么前端报错,就会导致截屏终止?
在 timesnap/lib/overwrite-time.js 中,有如下这个函数,用于执行指定的某个时间点的操作;其核心是通过 puppeteer 的frame.evaluate函数给浏览器注入自定义的 JS:
1 | |
如果 Puppeteer 打开的网页报错了(Uncaught xxxError),这里就会因为未捕获错误而导致程序中断,进而导致截屏中断。
如何捕获浏览器的报错信息
timesnap 有一个 logToStdErr 参数,但是不是用于这个的
正确的方式是通过 puppeteer 给浏览器注入自定义的 js,可以参考这个文章:
https://www.cnblogs.com/wuweiblogs/p/12918968.html
1 | |
不过由于我们目前有前端的 femonitor 了,其实可以直接在网页里面通过 femonitor 捕获到错误,上报给我们。