使用 CSS 隐藏动画 GIF 是不是可以节省浏览器资源?

Posted

技术标签:

【中文标题】使用 CSS 隐藏动画 GIF 是不是可以节省浏览器资源?【英文标题】:Does hiding an animated GIF with CSS conserve browser resources?使用 CSS 隐藏动画 GIF 是否可以节省浏览器资源? 【发布时间】:2016-02-19 03:52:13 【问题描述】:

我有一个 gif 图像。它仅在非常特定的事件中显示,而不是太频繁。默认情况下,gif 的 html <img> 标签使用 display: none 隐藏。

现在,我们都知道 gif 在计算机的 CPU 上可能非常困难。我不知道如何进行基准测试或检查隐藏的 gif 是否仍使用 CPU 带宽。

我使用开发工具检查了 gif 的重新绘制 - 没有发生,正如预期的那样。那挺好的。 FPS 计量器也不会上升,内存使用量也不会上升。但是我有强大的CPU和电脑;当 gif 出现时,这些也不会上升。

有没有人知道如何对此进行基准测试,或者更了解浏览器?我不希望这个 gif 成为那些从未见过它的人的资源浪费。而且我也不想从 DOM 中删除它。

【问题讨论】:

具有display: none; 的元素不应以任何显着方式影响渲染性能。 在这篇关于 html 性能的讨论中指出,您应该更好地使用 在您的页面中放置 500 个 gif,首先使用 display:none,然后不使用。比较和总结 【参考方案1】:

"display:none" 是你的朋友

如果您在 GIF 的 html 的 <img> 标签上使用 display:none,则根本不会渲染 GIF,并且不会使用任何 CPU 或 GPU 资源。有关说明,请参阅 this 和 this。

使用 javascript 暂停动画 GIF

如果由于某种原因 display:none 不能满足要求,免费的 libgif-js 和 x-gif Javascript 库都提供了以编程方式暂停和重新开始播放动画 GIF 的能力。这些库还提供了许多您可能不感兴趣的其他功能。有关这些库的更多说明,请参阅this SO question 的答案。

在 HTML5 标签中使用 MP4 而不是动画 GIF。

要提高页面加载速度并减少 CPU 和 GPU 负载,请将动画 GIF 转换为 MP4 视频,这需要显着减少内存占用和 CPU/GPU 使用率。请参阅以下文章摘录,"How elegant code can hurt HTML5 performance"George Lawton:

由于文件较小,动画 GIF 在许多网站上越来越受欢迎。但是,应尽可能避免使用它们 (...) 将视频用于动画而不是 GIF 以获得良好的性能。当浏览器尝试制作 GIF 动画时,它会使用图像的变化来渲染对象。尽管文件可能很小,但渲染它们会占用 CPU 和内存。例如,一个 200 KB 的 GIF 动画可能需要千兆字节的内存来渲染。视频格式更容易呈现,可以更好地利用 GPU,并且更容易在呈现后丢弃帧数据。

根据"Optimizing Animated GIFs by Converting to HTML5 Video"Billy Hoffman的文章,

今天超过 90% 的桌面浏览器支持 MP4 视频...对于现代移动设备,支持率接近 100%...

我们的研究发现,动画 GIF 通常比正确编码的 MP4 视频大 5 到 10 倍。这种差异意味着 GIF 不仅浪费了大量带宽,而且加载速度更慢,并造成糟糕的用户体验。

事实上,将动画 GIF 转换为 MP4 视频是一项非常棒的优化,这正是 Twitter、Facebook 和 imgur 等网站在您上传动画 GIF 时所做的。他们默默地将其转换为 MP4 视频并显示出来。

您可以使用免费实用程序ffmpeg 将您的动画 GIF 转换为 MP4 视频。然后,修改您的 HTML:

<img src="video.gif"    />

到这里:

<video autoplay="autoplay" loop="loop"  >
  <source src="video.mp4" type="video/mp4" />
  <img src="video.gif"   /></video>

这将自动启动视频并循环播放,而不显示任何视频控件。这提供了与动画 GIF 相同的体验,但它更快更小。请注意,我们仍然有一个&lt;img&gt; 指向&lt;video&gt; 标签内的原始动画GIF。这样,万一访问者的浏览器不支持 MP4 视频,动画 GIF 仍将显示,用户仍可体验内容。

如果你还想要证据

如果你真的想证明你的动画 GIF 不会消耗你的 CPU/GPU,你可以使用 David Corvoysier 在他的文章Effectively measuring browser framerate using CSS 中描述的一个聪明的方法:

原理很简单: - 在页面中插入一个非常简单的 CSS 动画项目, - 定期计算该项目的计算位置, - 每经过一秒,计算该项目占据的不同位置的数量.

相当愚蠢,嗯?好吧,也许吧,但实际上它给出了令人惊讶的准确结果......

你可以下载他的Javascript代码here。他的demo 仅评估 CSS 动画的加载,但您可以将您的 GIF 添加到他的代码中创建的每个 &lt;div&gt; 以查看其对测试的影响。

在执行动画基准测试时,您可以通过禁用硬件加速来故意使您的计算机稍有障碍,这会将渲染活动从 GPU 转移到 CPU。这可能有助于您更轻松地注意到动画对性能的影响。

【讨论】:

感谢您的真正杰作。我将赏金归功于您,并接受了我的问题的编辑建议! 嘿!很棒的帖子,没有显示的项目怎么样:没有,但被某些东西覆盖了?为了这个例子,说一个动画背景完全被某些东西覆盖。它的行为是否显示为:无?【参考方案2】:

display:none 元素仍然存在并由浏览器解析,它们只是对用户隐藏。

你可以使用visible=false,因为这些元素在浏览器中没有解析,但我不知道你是否可以使用它。

我还会检查visibility: hidden,因为我不知道这个选项是如何呈现的。

您可以用老式的方法对其进行基准测试,只需在您的页面中添加 50 个(或更多,如有必要)gif,直到您的 CPU 达到峰值,然后将其隐藏并观察您的 CPU。

我还要指出,该行为在很大程度上取决于浏览器本身,因此您需要使用不同的浏览器进行检查才能确定。

【讨论】:

以老式方式对其进行基准测试的好点。我想我太年轻了,不是我自己想出来的。我会报告结果。 好吧,我放弃了。我向 DOM 添加了 1000 个 gif,但仍然看不到任何差异,只有轻微的 RAM 变化。有趣的是,可见性:隐藏原因重绘...可能这种优化不值得花时间,但现在我更感兴趣的是获得理论答案而不是实际答案。 你要添加什么样的 gif,简单的加载器 gif?转到此处devopsreactions.tumblr.com 并获取一些适当的重型 gif :) 这应该会刺激你的 CPU。【参考方案3】:

不应该。 In the MDN document for none value on display,据说

文档呈现为好像该元素不存在。

在 chrome 上进行 Timeline 测试:

使用的图片:https://imgur.com/download/i8kbwLN ( 37M )

HTML:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <img src="a.gif" >
    </body>
</html>

控制台:

use_jQuery();

setTimeout(function() 
    $('img').css(display: 'block');
    setTimeout(function() 
        $('img').css(display: 'none');
    , 1000);
, 2000);

Same things seems to happens with CSS animation:

可能元素甚至不渲染。

【讨论】:

【参考方案4】:

如果您通过 css 的 display:none 隐藏任何图像/iframe,或者您通过此 css 规则 (display:none) 隐藏任何 div(或其他标签),image(s) / iframe( s) 此标签中的等将不会加载到浏览器中。这意味着浏览器不会对这些元素发出 http 请求。

在您将显示属性更改为非显示属性后,浏览器会将请求发送到服务器。

这不是关于 img,而是所有发出服务器请求的资源。

【讨论】:

OP 所问的不是浏览器是否会加载图像。它询问display: none;ed 元素中的加载 gif 是否会继续使用计算资源进行解码。

以上是关于使用 CSS 隐藏动画 GIF 是不是可以节省浏览器资源?的主要内容,如果未能解决你的问题,请参考以下文章

具有广泛浏览器支持的动画 gif 替代方案?

是否可以在 .jpg 中“隐藏”一个 .gif?

隐藏后如何在 IE 中制作 gif 动画?

具有延迟和不透明度的 CSS 动画

检测属性是不是可以通过 CSS3 过渡设置动画?

使用javascript和css模拟帧动画的几种方法浅析