【问题标题】:Image resizing causing slow scrolling图像大小调整导致滚动缓慢
【发布时间】:2016-12-27 05:12:10
【问题描述】:

我正在加载大图像并让浏览器调整它们的大小。我明确设置了大小。

<img src="http://example.com/image1.jpg" width="240" height="360"/>

页面上有很多这样的图像。滚动非常缓慢且不稳定。滚动时,chrome 中的事件时间轴看起来像这样:

Paint

* Image decode (JPEG)
* Image resize (non-cached)
* Image decode (JPEG)
* Image resize (non-cached)
* ...

Paint

* Image resize (cached)
* Image resize (cached)
* Image resize (cached)
* Image resize (cached)

Paint

* Image decode (JPEG)
* Image resize (non-cached)
* Image decode (JPEG)
* Image resize (non-cached)
* ....

Paint

* Image resize (non-cached)
* Image resize (non-cached)
* Image resize (non-cached)
* Image resize (non-cached)

Paint

* Image decode (JPEG)
* Image resize (cached)
* Image decode (JPEG)
* Image resize (cached)
* ...

等等

我不确定为什么某些 Paint 事件包含图像解码而其他事件不包含,也不知道为什么有时调整大小会被缓存而有时却没有。我想这一定与进入视口的新图像有关。

我能做些什么来确保我在页面加载时只为每张图片支付一次调整图片大小的费用,并避免在滚动期间调整图片大小?

(当然,我知道最好的解决方案是通过加载已经具有适当大小的图像来避免浏览器调整大小。在这种情况下,这是不切实际的。)

【问题讨论】:

标签: html css


【解决方案1】:

此功能将允许您只调整一次图像大小,将其替换为按所需比例调整大小的新图像:

function resizeImage(image, maxWidth, maxHeight) {

  // Output scale is the minimum of the two possible scales
  var scale = Math.min((maxWidth / image.width), (maxHeight / image.height))

  // Output canvas
  var outputCanvas = document.createElement('canvas')
  outputCanvas.width = image.width * scale
  outputCanvas.height = image.height * scale

  // Draw image content in output canvas
  var outputContext = outputCanvas.getContext('2d')
  outputContext.drawImage(image, 0, 0, parseInt(image.width * scale), parseInt(image.height * scale))

  // Replace image source
  image.src = outputCanvas.toDataURL()
}

它将您作为image 参数传递的图像创建一个画布,并在其中调整image 的大小,然后使用toDataURL()image.src 属性设置为输出画布的内容。

您调整大小的图像必须在相对路径中(是的,这并不酷),否则如果不满足 CORS,您将遇到安全错误。

但是你可以将base64数据作为src属性传递,使用AJAX很容易做到。

【讨论】:

  • 这是这里唯一真正理解问题并给出有效答案的答案... +1
  • 该死的没有更好的办法吗?我正在使用 Phonegap 开发一个移动应用程序,这真的很痛苦
【解决方案2】:

您的问题是同时下载大量图像,大量大图像。如果有大量大图像并且用户个人内存和处理器限制,则将它们渲染为原始尺寸以外的其他尺寸也会很慢。

无论您告诉浏览器渲染图像的大小,浏览器仍会加载原始图像大小,然后动态调整它。大图像必须通过用户的互联网连接从服务器传输到浏览器。通过使用 html 属性,您实际上所做的只是使用 CSS 来更改下载后的图像大小。

在 mho 中,您最好的选择是在服务器端创建多个图像尺寸,最好是在创建资产时而不是在运行时调用最接近您需要的图像尺寸。如果您使用脚本等动态创建图像,请将它们保留在服务器上以供以后再次使用并减少加载时间和服务器资源。

最后一个提示也是确保您正在缓存。更多信息在这里http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/

【讨论】:

    【解决方案3】:

    CSS 在这里会有所帮助。这将作为默认设置,可能会减慢单个加载时间。要实现这一点,只需为图像做基本的 css。参考如下:

     <img src="....." />
    

    对于您的 css,您需要以下代码作为示例:

     img {
    height: 360;
    width: 240;
    }
    

    然后您可以添加额外的代码来获得圆角、边框或任何您可能想要的效果。

    为了避免所有调整大小,这当然有助于在 Photoshop 中调整图像大小。然后它只会显示图像,而不是在显示页面的不同部分时渲染每个图像。

    【讨论】:

      【解决方案4】:

      大图像需要更多时间加载到内存 (RAM),即使图像已经在内存 (RAM) 上,如果内存消耗很大(大图像过多或后台应用程序占用大量内存),不可见(可见区域之外)图像被推送到分页/交换文件(在硬盘驱动器上),因此当图像到达可见区域时,浏览器将以硬盘驱动器速度(慢速)从分页/交换文件加载。

      在这种情况下,如果您在一页上有很多大图像,则不能依赖客户端调整大小,因为这会使您的客户端浏览体验变差。

      您应该考虑在服务器端调整图像大小,可以按需调整,也可以预先调整大小(缩略图)。

      在按需方法的情况下,您可以使用 Apache 的 mod_rewrite 将图像指向一个脚本以调整您的客户端浏览器请求的图像的大小。

      查看流行的图像共享/托管站点,查看随机图像并复制其 URL,将其粘贴到另一个选项卡,然后通过更改/删除 URL 的某些部分来使用 URL。 您可以看到他们在服务器端动态调整图像大小。

      TLDR:如果您坚持不使用缩略图,则无法平滑滚动页面上的许多大图像,要么使用缩略图,要么滚动不稳定。

      哦,还有一件事要考虑,那就是增加您(和您的客户)RAM 来处理此类内存需求

      【讨论】:

        猜你喜欢
        • 2012-10-03
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 2017-10-23
        • 1970-01-01
        • 2018-02-11
        • 1970-01-01
        • 2014-10-08
        相关资源
        最近更新 更多