问题 懒人加载图片如何


我正在开发一个eshop。基于类别的产品页面我推出了一些基于javascript的过滤。但是,如果某个类别包含大量产品,则会出现问题。 这个链接有类似我做的... http://www.snowandrock.com/sunglasses/snowboard/fcp-category/list?resetFilters=true

这个页面是多么痛苦地慢,超过2mb!

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

还有其他想法吗?


9081
2017-10-27 13:13


起源

做分页 服务器端。如果你一次只加载20张图像,它应该不会很慢。 - galambalazs


答案:


四种选择:

以下是三个选项:

使用背景图片

Kangkan的背景答案 有这个涵盖。

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

使用插件

分页有 已经完成了。你在评论中说你正在使用jQuery。有很多用于分页的jQuery插件。找一个你喜欢的,并使用它。它们的质量会有所不同,所以你需要测试它们并检查它们的代码,但我确信那里有一个体面的质量。

服务器端分页

这是主页面加载完全没有任何产品,或只有第一页产品。通常,您将所有产品放入容器中,如下所示:

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

然后,您将拥有通常的UI控件,用于在结果页面之间移动。您有一个服务器端资源,它返回了可用于填充该列表的HTML片段或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");

这是一个 示例原型 (不是生产代码);它伪造了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开始,您可以定义您的owwn data-xyz 属性和您的页面仍将通过验证。在早期版本的HTML中,您不允许定义自己的属性(尽管实际上没有主要的浏览器关注),因此如果您使用自己的属性,页面将无法验证。

参考文献(w3.org):

偏离主题,但是 批量 如果你使用像这样的JavaScript库,这些东西会变得容易多了 jQuery的关闭原型YUI, 要么 其他几个人 为你平滑粗糙的边缘。 (你已经说过你正在使用jQuery。)


7
2017-10-27 13:23



数据属性验证与否?有没有办法让它验证? - GorillaApe
@Parhs:我在答案中谈到验证。如果您将文档声明为HTML5(<!DOCTYPE html>),是的,它会验证。如果你不这样做,它就不会。它没有 物 除非验证是您工作实践的重要组成部分(应该是这样),因为即使您不使用HTML5声明,所有主流浏览器都允许使用自定义属性。尽管如此,尽管HTML5工作组成员发表了一些stoopid评论, 我和John Resig在一起:没有理由不使用HTML5 doctype 马上。 - T.J. Crowder
我想知道使用HTML5 doctype是否会在ie6等触发怪癖模式。那将是不好的 - GorillaApe
实际上我在设置这个doctype时遇到了问题。我在图像下面得到了某种无形的边距填充 - GorillaApe
@Parhs: “我想知道使用HTML5 doctype是否会在ie6等触发怪癖模式。” 不,几乎任何 DOCTYPE 告诉浏览器进入标准模式:HTML5: jsbin.com/uligo3 HTML4: jsbin.com/uligo3/2 怪癖: jsbin.com/uligo3/3 - T.J. Crowder


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


4
2017-10-27 13:19



这是所有浏览器的行为?如果隐藏它不可见你的意思? - GorillaApe
有时一段时间后,我看到背景图像永远不会加载..我... - GorillaApe
@Parhs:这是所有主流浏览器中的行为,我已经检查过了。但是,如果它是标准,我们可能需要检查它。此外,如果有时,加载实际上由于加载时间很长而失败。当你有大图像时,这是一个已知的问题。但是有很多小图像(如目录中的情况),它通常有效。 - Kangkan
您检查了哪些浏览器?知识的任何来源?谢谢你,这是件好事。 - Adrien Be
5年多以后,这似乎不再起作用了。 (无论如何)Chrome - Chris Fremgen


我相当肯定在没有某种Javascript干预的情况下,在纯HTML中是不可能的。

毕竟,如果没有脚本可以做到这一点,为什么有人会首先在Javascript中实现它?

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

(ps - 我猜你正在使用 Jquery的LazyLoad插件 对于启用Javascript的人?)


1
2017-10-27 13:20



我还没有实现这个... - GorillaApe
“我认为你正在为启用Javascript的人使用Jquery的LazyLoad插件?” 他没有说他正在使用jQuery。 jQuery!= JavaScript !! ;-) - T.J. Crowder
我正在使用Jquery,但还没有为我描述的问题做任何事情 - GorillaApe
@TJ:是的我知道JQuery!= JS。 ;)我猜他已经在使用那个插件,因为他在问题中使用了它的名字。 (我提供了链接,以防他没有,以防它有用) - Spudley


我建议实施 响应式图像方法 为了避免设备上的巨大图像文件无法正常显示(或人类无法区分)。


1
2018-06-05 17:00



这个博客文章中介绍的非常有趣的概念+1 - Adrien Be


我为自己的网站编写了以下代码。我用过JQuery: 1.命名所有类,其中U想要通过相同的名称延迟加载,说“异步” 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/


1
2017-10-22 05:15



非常感谢.. :)非常简单的代码.. - Sudheera


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

以下是一些用于Image Lazy Loading的Javascript库。

它们可以通过简单地更改图像src属性来帮助您加载元素“将”在视图中所需的图像。

重要:我仍在调查哪些Javascript库最好使用。做你的作业我会说,花一些时间来搜索什么是最好的工具。我的要求通常是: licensedependenciesbrowser supportdevice supportweightcommunity,和 history


0
2018-06-25 11:25