如何隐藏页面内容直到所有图像完全加载?

4
我正在尝试优化一个加载速度非常慢的网站。我已经重新排列、压缩和合并了js和css文件,但最大的问题在于图片。这个网站中有一些非常重的图片,因此当它开始加载时,内容会跳动,直到所有图片都被加载完毕为止。
由于这些图片是用户提交的,所以我无法手动设置包含图片的div的高度,尽管宽度是固定值,但高度不是。
我知道这可能不是一个好的实践方法,但我认为这比页面在两秒钟内展示内容之前变得跳跃且无法使用要好。
1.) 这是否在技术上可行?如何实现?(即使这不是一个好的做法,我也想知道)
2.) 如果这不是一个好的实践方法,您将如何避免这个问题?

1
不是最佳实践。也许可以尝试使用预加载器,或者等待所有图像加载完成后再显示它们,这样就只有一个跳跃而不是多个。 - ayyp
1
即使图像是由用户提交的,您仍应该知道服务器端的尺寸。确保在img标签上设置宽度和高度。在呈现图像标记的HTML时,使用一个读取图像并提供属性的函数。您可以在某个地方缓存这些尺寸。 - Ruan Mendes
5个回答

2

使用JQuery非常简单。无论如何,我建议您使用该框架,即使不是为了解决这个特定的问题:

function preload(arrayOfImages) {
    $(arrayOfImages).each(function(){
        $('<img/>')[0].src = this;
    });
}

请按照以下方式使用:

preload([
    'img/apple.jpg',
    'img/banana.jpg',
    'img/pear.jpg'
]);

在这个阶段隐藏您的网站非常容易,只需使用CSS和JQuery即可:
CSS:
body {
    display:none;
}

JQuery:

$(function(){
    $('body').show();
    // or fade it in: $('body').fadeIn();
});

我认为预加载不会解决这个问题,因为这些图片需要同时显示,而且问题在于它们需要时间来加载。这段 JavaScript 代码将在页面主体加载完成后再加载图片,所以它不会隐藏图片的缺失直到它们被加载完毕。 - Pheonix
看起来不错,@AlienWebGuy,但我真的不知道它在做什么。我不知道在预加载函数中你对SRC值做了什么,以及在什么事件上显示正文。你介意解释一下吗? - agente_secreto
基本上,该代码循环遍历您想要预加载的所有图像,并将它们添加到DOM中(不在屏幕上的任何实际位置,只是模型本身)。然后$(function(){...触发,这是$(document).ready(function(){的简写形式。 - AlienWebguy
使用CSS将body设置为display:none,这会隐藏所有内容 - 然后,在DOM准备就绪并加载完成后,您可以显示body的内容。 - AlienWebguy
这看起来不错,但是如果您不知道页面上会有什么图像怎么办?例如,客户制作了一个带有大量图像的页面。 - Chris G-Jones

1
在Body标签后面,添加一个Div元素来覆盖整个页面的长度和宽度,将其背景设置为白色或添加“加载”图像,将其z-index设置为最大值(9999或其他),使其位于所有元素的顶部,并给它一些ID/名称。
使用JavaScript和Body onLoad事件来隐藏或删除该Div元素。
类似于:
<body onload='document.body.removeChild(document.getElementById("bigDiv"));'>

<div style="width:100%;height:100%;background:white;" id=bigDiv>Loading...</div>

onLoad事件能够检测到图像完全加载吗?还是只能检测HTML文档的加载? - agente_secreto
其实我是为我的网站做的这个,它有一个非常长的表单(40个字段和很多额外的内容),但我想它也可以检测图片,你可以试试看。:) - Pheonix

1
我之前写过自己的js图像预加载器,但是我要发布的伪代码和它有些相似,但需要进行一些修改。 基本上,为了使您的页面漂亮地加载,答案不是隐藏主体以防止它跳来跳去,而是美化图片加载时发生的事情。 除了把孩子随着浴水一起扔掉外,通常情况下,如果用户在等待时可以看到某些东西正在发生,则网站似乎更快地加载。
因此,您需要做的(对于每个图像或至少每个主要或大图像)是显示一个加载gif(查看http://ajaxload.info),同时图像加载,然后当它完成后,您可以使用jQuery来动画化容器以达到正确的高度并淡入图像。 这样就停止了您的页面跳动(或者让它看起来更漂亮,因为它跳动)。
为了实现这种效果,这样做应该可以解决问题:
function imageLoader(elem)
{
  //set all images in this elem to opacity 0
  elem.children('img').css('opacity', '0');
  var image = new Image();
  //show loading image
  elem.append('html for loading image');

  //when the image loads, animate the height of the elem and fade in image
  image.onload=function()
  { 
       var h = image.height;
       elem.animate({height:h+'px'}, function(){
         elem.children('img').fadeIn();
         elem.children('html for loading image').remove(); 
       });
  };

  image.src=elem.children('img').attr('src');
}

使用方法如下:

imageLoader($('someElementWithAnImageTagInside'));

这只是伪代码,但希望能给你一些想法。

希望这有所帮助。


嗯,那是一个不错的解决方案,但我认为它在这个网站上表现不佳。这种情况经常发生在很多图片上,所以同时看到三四个旋转的圆圈并不会显得很好看。 - agente_secreto

1

检查的第一件重要事情 - 确保图像是可缓存的。有时图像缓存被禁用。检查的方法是直接调用Web服务器:

 telnet localhost 8080
 GET /images/flibble.gif HTTP/1.0

看看返回了什么。 它应该返回类似于过期:或缓存控件之类的内容。

这个页面似乎很好地描述了它:http://www.web-caching.com/mnot_tutorial/how.html

另一个诀窍是在标记中指定图像的大小。 这极大地提高了性能,因为浏览器不需要等到页面加载完毕才能显示图像。


有趣,但这不会解决首次访问者的问题,对吗? - agente_secreto
非常正确。个人而言,当我访问一个新网站时,我希望页面加载缓慢,但如果这是不可接受的,那么您需要另一种解决方案。 - cs94njw

0

您可以使用块插件来阻止页面。 链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接