最稳健的方式来预加载图像,以防止可见的图像加载?(没有JS)


Most robust way to preload image to prevent visible image load? (Without JS)

我刚刚创建了一个图片上传功能,我有点失望。

访问包含一张或多张照片的页面时,我遇到:

  • 加载时间冗长(~0.5秒)。

  • 不美观的图片加载(你可以看到照片从上到下加载)。

我的问题是:我怎么能确保整个照片加载之前呈现给用户(我试图找出一种方法来确保image是完全加载body之前)不使用Javascript?

注意:这个问题假设照片是从同一目录下的文件夹缓存加载的。

1。进步的JPEG

为了避免"从上到下"加载图像,你可以使用"渐进式jpeg",在加载过程中呈现"模糊"版本的图片,而不是"从上到下":示例:http://blog.patrickmeenan.com/2013/06/progressive-jpegs-ftw.html

2。嵌入式(base64编码)

如果你真的想同时显示图片和页面,你应该将它们编码为base64并包含在你的页面中:

<img src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..." alt="" />

你可以通过PHP或任何服务器端脚本来实现。

<img src="data:image/jpeg;base64,<?=base64encode(file_get_contents($file_path))?>" alt="" />

https://en.wikipedia.org/wiki/Data_URI_scheme Web_browser_support

3。伪装成样式表(可怕的hack)

如果你想在加载图像之前真正阻止渲染,你可以在你的页面的<head>部分的<link rel=stylesheet>标签中添加页面中的图像。

浏览器不会显示页面,直到CSS加载,即使你的文件不是CSS,它会加载和缓存它们,一旦加载页面将呈现,你的图像将从缓存中加载。

<html>
<head>
  <link rel="stylesheet" href="your_image_01.jpg" />
  <link rel="stylesheet" href="your_image_02.jpg" />
</head>
<body>
...
  <img src="your_image_01.jpg" alt="" />
  ...
  <img src="your_image_02.jpg" alt="" />
...
</body>
</html>

我不认为你可以没有javascript。

部分解决方法是加载用户打开的第一页中的所有图像,以便所有图像都保存到缓存中,但正确的方法是使用javascript。

为什么你不想用javascript?

使用http2/spdy将允许您使用服务器端推送,并将给您一个服务器端控制何时&如何获取图像。你可以尝试这种方式,但我认为使用javascript是一个更容易的路径。

我从来没有尝试过,但是幻想告诉我你可以用

对上传的图像进行编码
$im = file_get_contents('filename.gif');
$imdata = base64_encode($im);  
//taken from http://stackoverflow.com/questions/35879/base64-encoding-image

在服务器请求上传验证后生成内联CSS样式并将结果作为div背景

当然在htaccess中启用gzip/deflate。第一张图片出现时有点无意义,但谁知道呢…

使用链接预取会达到你想要的效果吗?它不会对每个用户都是完美的,但它可能是实现您想要的功能的一种简单方法。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ

单张图片:<link rel="prefetch" href="/images/big.jpeg">

整个页面:<link rel="next" href="2.html">

预呈现页面内容:<link rel="prerender" href="2.html">

这些标签需要放在你的站点的html标题部分。

你可能还想考虑使用CDN或子域名,将提供静态内容,不传递头(主要是cookie),如果你在同一页面上加载大量的图像。

https://jack.ofspades.com/prefetching-preloading-and-prerendering-content-with-html/

另一个可能适合您的方法:https://perishablepress.com/a-way-to-preload-images-without-javascript-that-is-so-much-better/

您无法在页面打开之前加载图像,因为浏览器不知道您的页面将需要哪些图像。为了避免在没有JS的情况下自上而下的加载效果,你可以把图像变小,或者用隔行保存。

尝试加载它作为另一个元素的背景。

或者将其加载到一个隐藏元素中(display:none)

#tinyElement{ background: url(images/picture.png) no-repeat -9999px -9999px; }

另见:https://css-tricks.com/snippets/css/css-only-image-preloading/

仅使用PHP是不可能做到这一点的(不包括与DOM加载和HTML相关的方法,推荐的方法是使用监视器并在检测图像加载完成时触发事件)。

然而,有一些方法可以加快PHP中的图像加载速度:

确保图像存储在目录中,而不是BLOB

如果您将图像以硬编码格式存储在数据库中,并且不能从目录直接访问,那么您应该停止这样做。这极大地增加了加载时间和渲染图像。

调整本地大小

在上传到服务器之前直接对图像进行大小调整。您可以通过使用PHP内置函数来实现这一点。像这样:

$source_imagex = imagesx($source_image);
$source_imagey = imagesy($source_image);
$dest_imagex = AVATAR_IMAGE_WIDTH;
$ratio = $dest_imagex / $source_imagex;
$dest_imagey = $ratio * $source_imagey;
$dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);
$image = imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0, $dest_imagex, $dest_imagey, $source_imagex, $source_imagey);

您可以计算预大小图像的宽度和高度,并适当缩放以保持宽高比。常数AVATAR_IMAGE_WIDTH可以设置为任何值(或AVATAR_IMAGE_HEIGHT),也可以根据自己的喜好调整变量。这将防止CSS不得不加载DOM并加载图像的完整尺寸,然后将其调整为您想要的任何大小。