以下内容针对在IE11浏览器的情况,其他edge,chrome可能有些微差别。
GIF文件本质上是一个包含多帧静态图片的动画文件。当GIF播放时,浏览器只需按顺序显示这些帧,从而产生动画效果。
GIF动画帧切换过程:
-
解码GIF文件:当GIF被加载时,浏览器会解码GIF文件,提取出每一帧的图像数据。每帧都是独立的静态图像。
-
定时切换帧:GIF文件中包含了帧的显示时间(通常以毫秒为单位)。浏览器根据这个时间来决定何时切换到下一帧。这个过程由浏览器内部的定时机制管理。
-
帧的重绘(注意是“重绘”(repaint),而不是“渲染”(render),因为渲染通常指的是生成一个新图像或内容的过程,而重绘则是指在已有内容的基础上更新显示的内容):
- 清除旧帧:在显示新帧之前,浏览器可能会先清除或覆盖掉当前显示的帧。
- 显示新帧:浏览器将解码后的新帧图像绘制到屏幕上。这部分的操作非常快,因为帧图像数据已经解码完成,只需将其显示出来。
-
循环播放:如果GIF设置为循环播放,浏览器会在最后一帧显示完后,回到第一帧,继续按照相同的过程切换帧。
GIF动态图片播放过程中,如果在浏览器中执行JavaScript代码,可能会导致GIF动画掉帧或播放不流畅。这是因为JavaScript执行和浏览器的渲染(包括重绘)是单线程处理的(同步),这意味着当JavaScript脚本在执行时,会阻塞浏览器的渲染进程,如果这时候刚好是GIF下一帧动画的显示时间,就会被阻塞,从而被跳过,画面就会表现为有一帧没显示。
具体来说,浏览器的渲染引擎和JavaScript引擎通常共享一个线程(通常称为主线程)。当JavaScript代码执行时间较长时,主线程无法及时处理其他任务,比如页面的渲染或动画的更新。这就可能导致GIF动画掉帧或表现不流畅。
比如下面这个例子(也是这次项目遇到的一个问题)
当页面向后台发送请求并获取新的画面时,页面的更新是在新内容被成功接收并初次渲染之后发生。具体流程如下:
-
发出请求:通过
XMLHttpRequest
、fetch
API、form的commit,或其他方式向后台发出请求。 -
等待响应:在请求发送出去后,页面会等待后台返回响应。在此期间,页面通常不会做出任何变化。
-
接收响应并更新:当后台响应到达后,浏览器会解析并构建DOM,CSSOM以及渲染树。
-
首次渲染新内容:有了渲染树后,浏览器会渲染这个新内容。
-
旧内容消失:旧的画面或内容会在新内容首次渲染后消失。
在第一步发出请求后,我在画面加载了一个转圈的GIF动画,以遮住旧内容,直至新内容表示出来,但是第三部里面,返回的HTML中包含有立刻执行的JS代码,这时候执行JS代码就会阻塞转圈的GIF动画的部分换帧动作,因为换帧是通过重绘实现的,而执行JS阻塞了重绘处理,因此造成GIF动画播放掉帧现象,表现为动画播放不流畅。
标签:动画,浏览器,GIF,渲染,gif,画面,播放,重绘,图片 From: https://www.cnblogs.com/shixiaobin/p/18391766