【问题标题】:Lazy loading images how延迟加载图像如何
【发布时间】:2023-03-07 16:46:01
【问题描述】:

我正在开发一个 eshop。在基于类别的产品页面上,我放置了一些基于 javascript 的过滤。但是,如果一个类别有很多产品,就会出现问题。 这个链接有类似的东西我做...... http://www.snowandrock.com/sunglasses/snowboard/fcp-category/list?resetFilters=true

这个页面怎么会非常慢并且超过 2mb !!!

对我来说,每个产品都需要半个 killobyte,但图像是问题.. 所以我正在寻找如何延迟加载图像.. 由于我的页面与该站点不同,因此我认为加载仅对页面可见的图像是一种解决方案。然而,问题是如何做到这一点,以便同时为 javascript 和非 javscript 启用的人工作。 我唯一的解决方案是在css类中以某种方式存储不可见产品的图像的链接,如果在通过javascript过滤更改后显示图像src ... 非 javascript 用户没有此问题,因为单击过滤器会将他们导航到其他页面...

还有什么想法吗?

【问题讨论】:

  • 服务器端进行分页。如果一次只加载 20 张图片,应该不会很慢。

标签: javascript html css lazy-loading lazy-evaluation


【解决方案1】:

四个选项:

这里有三个选项供您选择:

使用背景图片

Kangkan's background answer 已涵盖此内容。

如果这对您不起作用,我假设您只需要启用 JavaScript 的帮助,因为您说过非 JavaScript 用户会看到不同的页面。

使用插件

分页已完成。您在评论中说过您正在使用 jQuery。有很多用于分页的 jQuery 插件。找到一个你喜欢的,并使用它。它们的质量参差不齐,因此您需要对它们进行测试并查看它们的代码,但我敢肯定那里有质量不错的。

服务器端分页

这是主页加载的地方,或者根本没有任何产品,或者只有产品的第一页。通常,您会将所有产品放入一个容器中,如下所示:

<ul id='productList'>
</ul>

然后,您将拥有在结果页面之间移动的常用 UI 控件。您将拥有一个返回 HTML sn-ps 或 JSON 格式数据的服务器端资源,您可以使用这些数据填充该列表。为简单起见,我将使用 HTML(尽管我可能会在生产应用程序中使用 JSON,因为它往往更小)。每个产品条目都是它自己的独立块:

<li id='product-001'>
  <div>This is Product 001</div>
  <img src='http://www.gravatar.com/avatar/88ca83ed97a129596d6e8dd86deef994?s=32&d=identicon&r=PG'>
  <div>Blurb about Product 001</div>
</li>

...然后页面返回您认为合适的数量。您使用 Ajax 请求页面并使用 JavaScript 更新产品列表。既然你说你使用 jQuery,这可以很简单:

$('#productList').load("/path/to/paging/page?start=X&count=Y");

这是example prototype(不是生产代码);它伪造了 Ajax,因为 JSBin 给了我 Ajax 问题。

一个大页面下载,然后是客户端 JavaScript 分页

我不确定您是如何进行过滤的,但如果您有一个包含产品信息的元素,您可以将图像 URL 存储在其上的 data-xyz 属性中:

<div id='product-123' data-image='/images/foo.png'>

然后,当您的代码使其可见时,您可以轻松地向其添加 img

var prod, imgsrc, img;
prod = document.getElementById('product-123');
prod.style.display = 'block'; // Or whatever you're doing to show it
imgsrc = prod.getAttribute('data-image');
if (imgsrc) {
    img = document.createElement('img');
    img.src = imgsrc;
    prod.appendChild(img); // You'd probably put this somewhere else, but you get the idea
    prod.removeAttribute('data-image');
}

编辑 在其他地方的评论中您说您正在使用 jQuery。如果是这样,上面的翻译可能如下所示:

var prod, imgsrc, img;
prod = $('#product-123');
prod.show();
imgsrc = prod.attr('data-image');
if (imgsrc) {
    $("<img/>").attr('src', imgsrc).appendTo(prod); // You'd probably put this somewhere else, but you get the idea
    prod.removeAttr('data-image');
}

隐藏时无需再次删除,因为图像已经显示,这就是为什么我在使用后删除该属性。

我使用data- 前缀的原因是验证:从HTML5 开始,您可以定义自己的data-xyz 属性,您的页面仍将通过验证。在早期版本的 HTML 中,不允许您定义自己的属性(尽管实际上主流浏览器并不关心),因此如果您为此使用自己的属性,页面将无法验证。

参考资料(w3.org):

题外话,但是如果你使用像 jQueryClosurePrototypeYUI 这样的 JavaScript 库,那么其中的很多东西会变得容易得多。或 any of several others 为你平滑粗糙的边缘。(你已经说过你正在使用 jQuery。)

【讨论】:

  • 数据属性是否有效?有没有办法让它验证?
  • @Parhs:我在回答中谈到了验证。如果您将文档声明为 HTML5 (&lt;!DOCTYPE html&gt;),是的,它将验证。如果你不这样做,它就不会。除非验证是您工作实践的重要组成部分(它应该是),否则它并不重要,因为即使您不使用 HTML5 声明,所有主要浏览器都允许自定义属性。也就是说,尽管 HTML5 工作组成员有一些愚蠢的 cmets,I'm with John Resig:没有理由不使用 HTML5 文档类型现在
  • 我想知道使用 HTML5 doctype 是否会在 ie6 等中触发 quirks 模式。那会很糟糕
  • 实际上我在设置这个 doctype 时遇到了问题。我在图像下得到了某种不可见的边距填充
  • @Parhs: “我想知道使用 HTML5 doctype 是否会在 ie6 等中触发 quirks 模式。” 不,几乎任何 DOCTYPE 都会告诉浏览器进入标准模式:HTML5:jsbin.com/uligo3 HTML4:jsbin.com/uligo3/2 Quirks:jsbin.com/uligo3/3
【解决方案2】:

如果您只是希望缓慢加载图像并首先加载页面的其余部分,您可以将图像作为背景而不使用&lt;img&gt; 标签。如果您使用&lt;img&gt; 标签,则在加载页面时会加载图像,因此页面加载会变慢。但是,背景图像会在页面显示给用户之后加载。用户可以阅读文本并在一段时间后查看加载的图像。

【讨论】:

  • 这是所有浏览器的行为吗?如果它被隐藏它不可见你的意思是?
  • @Parhs:这是所有主流浏览器的行为,我已经检查过了。但可能我们需要检查它是否是标准。此外,有时,由于加载时间过长,加载实际上会失败。当您有大图像时,这是一个已知问题。但是对于很多小图像(例如目录),它通常可以工作。
  • 你检查了哪些浏览器?这些知识的任何来源?谢谢,知道这是件好事。
  • @AdrienBe:这是我很久以前观察到的。这可能随着现代浏览器和更好的连接性而改变。但是对于某些网站,我这样做的效果很好。
  • 5 年多之后,这似乎不再起作用了。 (无论如何都是 Chrome)
【解决方案3】:

我相当肯定,如果没有某种 Javascript 干预,纯 HTML 是不可能的。

毕竟,如果可以在不编写脚本的情况下做到这一点,为什么会有人首先在 Javascript 中实现它?

我的问题是:现在有多少访问者没有启用 Javascript?我敢打赌它很少。无论如何,这些人习惯于禁用 javascript 后无法完全正常运行的网站;如果他们必须忍受的唯一区别是加载速度较慢,那么您的网站实际上会比大多数网站更好。

(ps - 我猜你是在使用 Jquery's LazyLoad plugin 为启用 Javascript 的人?)

【讨论】:

  • “我猜你正在为启用 Javascript 的人使用 Jquery 的 LazyLoad 插件?” 他没有说他在使用 jQuery。 jQuery != JavaScript !! ;-)
  • 我正在使用 Jquery,但还没有为我描述的问题做任何事情
  • @TJ:是的,我知道 JQuery != JS。 ;) 我猜他已经在使用该插件,因为他在问题中使用了它的名称。 (我提供了链接,以防他不这样做,以防万一它有用)
【解决方案4】:

我建议实现responsive image approach 以避免设备上的巨大图像文件无法正确显示(或人类无法区分)。

【讨论】:

  • 为这篇博文中介绍的非常有趣的概念+1
【解决方案5】:

我为自己的网站编写了以下代码。我使用了 JQuery: 1.命名所有类,你想用相同的名字延迟加载,说“异步” 2.将真实图像位置从'src'复制到'alt'属性 3. 完成页面加载后,我的脚本会将所有 'alt' 值复制到 'src' 看例子。这是完整的工作示例 html:

<html> 
<head> 
<script src="http://code.jquery.com/jquery-1.9.1.js"></script> 
<script type="text/javascript">
        $(document).ready(function(){
            $('img.async').each(function(i, ele) {
                 $(ele).attr('src',$(ele).attr('alt'));
            });
        });
        </script> </head> <body> <img class="async" title="Гороскопы" alt="http://virtual-doctor.net/images/horoscopes.jpg" width="135" height="135"/> 
</body>
</html>

您可以在我使用它的真实站点中感受到速度 http://virtual-doctor.net/

【讨论】:

    【解决方案6】:

    浏览器级支持

    现代浏览器可以使用loading="lazy"属性延迟加载图片!

    <img src="image.png" loading="lazy" alt="…" width="200" height="200">
    

    欲了解更多信息,请访问here

    【讨论】:

      【解决方案7】:

      编辑:我重新阅读了您的问题并注意到您也希望这也适用于禁用 Javascript 的人!那么是的,我的回答是不可接受的 - 但我会留作记录。

      这里有一些用于图像延迟加载的 Javascript 库。

      它们可以帮助您在元素“将”出现时加载所需的图像,只需更改图像 src 属性即可。

      重要提示:我仍在研究哪些 Javascript 库最适合使用。我会说,做你的功课,花点时间寻找最适合这项工作的工具。我的要求通常是:licensedependenciesbrowser supportdevice supportweightcommunityhistory

      【讨论】:

        猜你喜欢
        • 2020-08-12
        • 2016-12-08
        • 1970-01-01
        • 2013-10-24
        • 2021-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多