Chrome 图片解码与 Image Decoding Hint

简介: 我在之前的一篇文章[Chrome 图片解码与 Image.decode API][1],说明了为什么图片解码可能会导致非合成器动画的阻塞和如何使用 Image.decode API 来避免动画的阻塞。不过虽然 Image.decode API 给页端提供了更灵活的控制图片解码时机的能力,但是使用起来较为复杂,也容易误用,而 Image Decoding Hint 属性则更简单,容易使用,同时也满足

我在之前的一篇文章Chrome 图片解码与 Image.decode API,说明了为什么图片解码可能会导致非合成器动画的阻塞和如何使用 Image.decode API 来避免动画的阻塞。不过虽然 Image.decode API 给页端提供了更灵活的控制图片解码时机的能力,但是使用起来较为复杂,也容易误用,而 Image Decoding Hint 属性则更简单,容易使用,同时也满足了大部分场景下的性能需求。

Chrome 从 65 版本开始支持 Image Decoding Hint,其它浏览器 Firefox,Edge 也是支持的,Safari 年初时的状态是开发中,不清楚现在是否已经支持。

以下描述来自于 HTML 规范文档

In order to aid the user agent in deciding whether to perform synchronous or asynchronous decode, the decoding attribute can be set on img elements. The possible values of of the decoding attribute are the following image decoding hint keywords:

sync: Indicates a preference to decode this image synchronously for atomic presentation with other content.
async: Indicates a preference to decode this image asynchronously to avoid delaying presentation of other content.
auto: Indicates no preference in decoding mode (the default).

直接翻译过来就是 —— 页端可以通过 Image.decoding 属性来控制图片解码的行为,sync 会强制同步解码,图片会和其它内容同时显示,async 则强制异步解码,可能会造成图片和其它内容不同时显示,默认值 auto 则让浏览器自己来决定。

上述描述的“和其它内容同时显示或者不同时显示”究竟是什么意思呢?这个跟浏览器合成器的光栅化策略有关,当图片元素和其它元素同时进入当前网页的可见区域,或者已经在可见区域内并且内容同时发生变化,合成器需要安排这些元素所在的图层光栅化,并且在所有发生变更的图层都光栅化完毕之后再显示完整的一帧(请参考浏览器渲染流水线解析与网页动画性能优化对非合成器动画渲染流水线的解释)。

在不支持 Image Decoding Hint 之前,Chrome 会强制图片先解码,然后再光栅化,这样保证了包括图片在内的所有同时变更的元素都是同时显示的,也就是所谓的 atomic presentation。而在支持 Image Decoding Hint 之后,Chrome 的光栅化策略就会变为:

  1. 如果 Decoding Hint 是 sync,则跟之前是一样的;
  2. 如果 Decoding Hint 是 async,则图片不会在光栅化之前解码,而是放到另外一个后台 Worker 线程解码,并在图片解码完成后重新光栅化图片所在区域并重绘窗口。这样造成的结果就是在图片所在区域光栅化的时候可能因为图片还未完成解码而无法绘制图片导致空白,跟其它非图片元素的显示不完全同步,也就是说如果有图片元素和非图片元素同时发生变更,非图片元素可能会提前显示;
  3. 如果 Decoding Hint 是 auto,目前 Chrome 的处理是等同于 sync;

即使设置成 async,Chrome 还是会根据一些条件来决定最后的结果是 sync 还是 async,如果运行设备,网页和图片满足下面条件,最后还是会被强制为 sync:

  1. 如果图片还未下载完毕;
  1. 或者是 gif 这样的动图;
  2. 或者在 Chrome for Android 或者 Android WebView 上设备不支持 GPU 光栅化,或者网页无法开启 GPU 光栅化;
  3. 或者在 Chrome for Android 或者 Android WebView 上解码后占用内存小于 512k(相当于分辨率小于 512 x 256),桌面版本为 1024k;
  4. 或者解码后占用内存大于合成器的解码缓存池的上限(也就是说小图片和超大图片,都强制为同步解码,无论是什么设置);

在 AMP 里面的 amp-img 自定义元素,AMP-runtime 在生成对应的 img 元素时,会指定 decoding 属性为 async,在现实中,大部分情况下指定为 async 应该都是合理的。

Chrome 图片解码与 Image.decode API之前演示过的一个例程,如果我们修改会导致动画阻塞的 sync.html 的代码如下:

function prepareImage() {
  var img = new Image();
  img.src = "nebula.jpg";
  img.decoding = "async";
  img.onload = function() { document.body.appendChild(img); };
}

上述代码增加了一句 img.decoding = "async";,其运行的结果跟另外一个使用 Image.decode API 的 async.html 就基本一样了,时针的动画不会被阻塞,并且在实际的应用中要比使用 Image.decode API 简单的多。(上面的代码 async 不会在 Chrome for Android 或者 Android WebView 上生效,是因为网页无法开启 GPU 光栅化)

目录
相关文章
|
5月前
|
Web App开发 前端开发
canvas保存图片时,谷歌浏览器Chrome报错【解决方案】Not allowed to navigate top frame to data URL
canvas保存图片时,谷歌浏览器Chrome报错【解决方案】Not allowed to navigate top frame to data URL
159 0
|
Web App开发 缓存 JavaScript
Chrome 图片解码与 Image.decode API
在这篇文章里面,我会对 Chrome 是何时对图片进行解码进行说明,并结合 Chrome 的渲染流水线说明为什么图片解码可能会造成动画卡顿,而新的 Image.decode API 是如何让我们控制图片解码的时机,通过预先解码来避免动画卡顿。 为了让读者更好地了解本文的内容,请阅读我之前的文章 —— [浏览器渲染流水线解析与网页动画性能优化][1]。 ## 图片解码 ### 图片
2347 0
|
Web App开发 安全 Windows
Chrome浏览器无法将网页中的图片保存到本地的问题
今天在浏览网页时看到一张图片不错,想保存下来,在图片上点击右键》图片另存为,结果试了好多次都没有反应。 环境: Windows 7操作系统 Chrome 版本 41.0.2272.76 m (64-bit) 原因: 后来发现是这个安全警告框的原因,点击运行以后一下子弹出好多个文件保存对话框,之前试了好多次都没有反应,现在全都弹出来了。
2750 0
|
Web App开发 前端开发 iOS开发
CSS设置DIV Herf底层图片和链接同时改变,兼容IE,Firefox,Opera,Safari,Chrome等
/*CSS樣式設置 塗聚文 Geovin Du**/ .text8 { font-family: Arial, Helvetica, sans-serif; background-image: url(../images/05.jpg); height:42px; text-align:center; } .geovindu { cur
1138 0
|
3月前
|
Web App开发 数据采集 存储
WebDriver与Chrome DevTools Protocol:如何在浏览器自动化中提升效率
本文探讨了如何利用Chrome DevTools Protocol (CDP) 与 Selenium WebDriver 提升浏览器自动化效率,结合代理IP技术高效采集微博数据。通过CDP,开发者可直接操作浏览器底层功能,如网络拦截、性能分析等,增强控制精度。示例代码展示了如何设置代理IP、cookie及user-agent来模拟真实用户行为,提高数据抓取成功率与稳定性。适用于需要频繁抓取互联网数据的应用场景。
542 3
WebDriver与Chrome DevTools Protocol:如何在浏览器自动化中提升效率
|
1月前
|
Web App开发 缓存 安全
WIN11 Chrome 双击打不开闪退及Chrome浏览器不能拖拽文件crx
【11月更文挑战第6天】本文介绍了 WIN11 系统中 Chrome 浏览器双击打不开闪退及不能拖拽文件 crx 的原因和解决方法。包括浏览器版本过旧、扩展程序冲突、硬件加速问题、缓存过多、安全软件冲突、系统文件损坏、用户配置文件损坏等问题的解决方案,以及 crx 文件的屏蔽、权限问题和文件格式问题的处理方法。
109 2
|
1月前
|
Web App开发 Linux iOS开发
Chrome浏览器如何导出所有书签并导入书签
【11月更文挑战第4天】本文介绍了如何在 Chrome 浏览器中导出和导入书签。导出时,打开书签管理器,点击“整理”按钮选择“导出书签”,保存为 HTML 文件。导入时,同样打开书签管理器,点击“整理”按钮选择“导入书签”,选择之前导出的 HTML 文件即可。其他主流浏览器也支持导入这种格式的书签文件。
176 2
|
1月前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
252 9
|
2月前
|
Web App开发 开发者