19

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

<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 事件包括图像解码而其他事件不包括,也不知道为什么有时调整大小被缓存而有时却没有。我想这一定与进入视口的新图像有关。

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

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

4

4 回答 4

8

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

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,然后将image.src属性设置为输出画布的内容,使用toDataURL().

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

但是您可以将 base64 数据作为src属性传递,并且使用 AJAX 可以很容易地做到这一点。

于 2013-02-07T21:19:42.890 回答
1

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

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

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

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

于 2013-02-11T09:33:32.180 回答
0

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

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

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

 img {
height: 360;
width: 240;
}

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

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

于 2013-02-03T22:35:08.950 回答
-1

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

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

您应该考虑在服务器端根据需要或预先调整大小(缩略图)来调整图像大小。

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

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

TLDR:页面上的许多大图像不能平滑滚动,要么使用缩略图,要么如果你坚持不使用缩略图,则滚动不流畅。

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

于 2013-02-04T02:47:06.337 回答