JavaScript 预加载是如何工作的?
我不想知道预加载图像的方法,我在网上找到了很多,但我想知道它是如何工作的。 javascript 如何预加载图像? 我的意思是,我尝试了这里的一个片段,即使它有效,它似乎也没有预加载图像。
当我检查 firebug 时,我可以看到图像加载了两次,一次是在预加载时,另一次是在显示时!
为了改进这段代码,我想知道它是如何工作的。
这就是我所做的:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
//(new Image()).src = this;
alert(this +' && ' + i++);
});
}
然后我做了类似的事情:
preloader = function() {
preload(myImages);
}
$(document).ready(preloader);
这是我显示/添加图像的方式:
$("li.works").click(function() {
$("#viewer").children().empty();
$('#viewer').children().append('<img src=\'images/ref/'+this.firstChild.id+'.jpg\' alt="'+this.firstChild.id+'" \/>')
$("#viewer").children().fadeIn();
I don't want to know a way to preload images, I found much on the net, but I want to know how it works.
How is javascript able to preload images?
I mean, I tried a snippet from here, and even if it works, it doesn't seem to preload images.
When I check firebug, I can see that the image is loaded twice, once while the preloading, another time when displaying it!
To improve this code I'd like to know how it works.
Here is what i do:
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
//(new Image()).src = this;
alert(this +' && ' + i++);
});
}
then i do something like that:
preloader = function() {
preload(myImages);
}
$(document).ready(preloader);
Here is how i display/add the image :
$("li.works").click(function() {
$("#viewer").children().empty();
$('#viewer').children().append('<img src=\'images/ref/'+this.firstChild.id+'.jpg\' alt="'+this.firstChild.id+'" \/>')
$("#viewer").children().fadeIn();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
你的基本 Javascript 预加载器是这样做的:
它的工作方式只是创建一个新的 Image 对象并设置它的 src,浏览器将去抓取图像。 我们不会将这个特定图像添加到浏览器中,但是当需要通过我们设置的任何方法在页面中显示该图像时,浏览器将已经将其保存在其缓存中,并且不会再去取吧。 不过,如果不查看代码,我无法真正告诉您为什么您拥有的任何东西都不能以这种方式工作。
在此问题中讨论了一个有趣的问题< /a> 是当您有一组图像并尝试使用相同的 Image 对象预加载它们时会发生的情况:
这只会预加载最后一个图像,因为在循环再次出现以更改图像之前,其余图像将没有时间预加载对象的来源。 查看示例。 单击按钮后,您应该能够立即看到第二个图像,但第一个图像必须加载,因为当您尝试查看它时它没有机会预加载。
因此,一次执行多项操作的正确方法是:
Your basic Javascript preloader does this:
The way it works is simply by creating a new Image object and setting the src of it, the browser is going to go grab the image. We're not adding this particular image to the browser, but when the time comes to show the image in the page via whatever method we have setup, the browser will already have it in its cache and will not go fetch it again. I can't really tell you why whatever you have isn't working this way without looking at the code, though.
One interesting gotcha that is discussed in this question is what happens when you have an array of images and try preloading them all by using the same Image object:
This will only preload the last image as the rest will not have time to preload before the loop comes around again to change the source of the object. View an example of this. You should be able to instantly see the second image once you click on the button, but the first one will have to load as it didn't get a chance to preload when you try to view it.
As such, the proper way to do many at once would be:
JavaScript 预加载的工作原理是利用浏览器使用的缓存机制。
基本思想是,一旦资源被下载,它就会在客户端本地存储一段时间,这样浏览器下次需要显示时就不必再次从网络上检索该资源/由浏览器使用。
您的代码可能工作得很好,您只是误解了 Fire Bug 显示的内容。
要测试这个理论,只需使用干净的缓存访问 www.google.com 即可。 即首先清除您的下载历史记录。
第一次完成所有操作的状态可能为 200 OK。 这意味着您的浏览器请求资源并且服务器发送它。 如果您查看 Fire Bug 窗口的底部,它会显示页面有多大(例如 195Kb)以及从缓存中提取了多少内容。 在本例中为 0Kb。
然后重新加载同一页面而不清除缓存,您仍然会在 FireBug 中看到相同数量的请求。
原因很简单。 该页面没有更改,并且仍然需要以前所需的所有相同资源。
不同之处在于,对于大多数请求,服务器返回 304 未修改状态,因此浏览器检查其缓存以查看是否已在本地存储了资源,在本例中,它是从上一个页面加载中获取的。 所以浏览器只是从本地缓存中拉取资源。
如果您查看 Fire Bug 窗口的底部,您将看到页面大小仍然相同 (195Kb),但其中大部分(在我的例子中为 188Kb)是从本地缓存中提取的。
所以缓存确实起作用了,当我第二次点击 Google 时,我保存了 188Kb 的下载内容。
我相信您会在预加载图像时发现同样的情况。 请求仍然发出,但如果服务器返回状态 304,那么您将看到图像实际上只是从本地缓存而不是网络中提取。
因此,使用缓存的优点不是您会终止所有未来的资源请求,即仍然对网络进行 Uri 查找,而是如果可能的话,浏览器将从本地缓存中提取内容以满足内容的需求,而不是在网上跑来跑去寻找它。
Javascript preloading works by taking advantage of the caching mechanism used by browsers.
The basic idea is that once a resource is downloaded, it is stored for a period of time locally on the client machine so that the browser doesn't have to retrieve the resource again from across the net, the next time it is required for display/use by the browser.
Your code is probably working just fine and you're just misinterpeting what Fire Bug is displaying.
To test this theory just hit www.google.com with a clean cache. I.e. clear your download history first.
The first time through everything will likely have a status of 200 OK. Meaning your browser requested the resource and the server sent it. If you look at the bottom on the Fire Bug window it will says how big the page was say 195Kb and how much of that was pulled from cache. In this case 0Kb.
Then reload the same page without clearing your cache, and you will still see the same number of requests in FireBug.
The reason for this is simple enough. The page hasn't changed and still needs all the same resources it needed before.
What is different is that for the majority of these requests the server returned a 304 Not Modified Status, so the browser checked it's cache to see if it already had the resource stored locally, which in this case it did from the previous page load. So the browser just pulled the resource from the local cache.
If you look at the bottom of the Fire Bug window you will see that page size is still the same (195Kb) but that the majority of it, in my case 188Kb, was pulled locally from cache.
So the cache did work and the second time i hit Google I saved 188Kb of download.
I'm sure you will find the same thing with preloading your images. The request is still made but if the server returns a status of 304 then you will see that the image is in fact just pulled from local cache and not the net.
So with caching, the advantage is NOT that you kill off all future resource requests, i.e. a Uri lookup is still made to the net but rather that if possible the browser will pull from the local cache to satisify the need for the content, rather than run around the net looking for it.
您可能对“预加载”的概念感到困惑。 如果您的 HTML 中有一堆带有
的图像,则它们无法使用 Javascript 预加载,它们只是随页面一起加载。
使用 Javascript 预加载图像是指加载文档源中尚未存在的图像,然后稍后显示它们。 它们在页面首次呈现后加载。 它们被预加载,以便在使它们出现时消除/最小化加载时间,例如在鼠标悬停时更改图像时。
对于大多数应用程序,通常更好的做法是使用“CSS sprites”作为预加载的形式,而不是 Javascript。 所以对此应该有很多问题。
You may be confused by the concept of "preloading". If you have a bunch of images in your HTML with
<img src="...">
, they cannot be preloaded with Javascript, they just load with the page.Preloading images with Javascript is about loading images not already in the document source, then displaying them later. They are loaded after the page has rendered for the first time. They are preloaded in order to eliminate/minimize loading time when it comes to making them appear, for example when changing an image on mouse rollover.
For most applications, it is usually better practice to use "CSS sprites" as a form of preloading, in lieu of Javascript. SO should have a ton of questions on this.
它只涉及创建一个新的 DOM 图像对象并设置 src 属性。 没什么聪明的,据我所知,它一直对我有用。
第二个“加载”萤火虫是否有可能向您显示它是否从缓存加载?
It just involves making a new DOM image object and setting the
src
attribute. Nothing clever and AFAIK, it has always worked for me.Is it possible the second "load" firebug is showing you is it loading it from cache?
编辑:回想起来,这是错误的,我可以看到您正在尝试创建图像元素。 我根本不明白为什么索引在那里,不需要有索引。 我认为该函数应该如下所示:
为了实例化它,为什么不这样做:
JavaScript 图像预加载之所以有效,是因为当创建包含图像的 DOM 元素时,会下载并缓存该图像。 即使在实际从 HTML 渲染图像时发出另一个请求,服务器也会发回 304(未更改),浏览器将简单地从其缓存中加载图像。
Paolo 建议使用以下表示法来创建图像对象:
虽然这可行,但符合 DOM 的方式是:
这是在脚本中完成的方式,只不过它使用 jQuery 的 HTML 字符串文字语法来完成此操作。 此外,大多数现代浏览器通过简单地调用 DOM 标准方法来提供与
Image()
构造函数的兼容性。 例如,如果您打开 Google Chrome JavaScript 控制台并输入Image
,您将得到以下结果:Chrome 仅使用本机 DOM 方法来创建图像元素。
Edit: In retrospect, this was wrong and I can see you're trying to create image elements. I don't understand why the index is there at all, there need not be an index. I think the function should look like this:
And to instantiate it, why not just do this:
JavaScript image preloading works because when a DOM element that contains an image is created, the image is downloaded and cached. Even if another request is made when the image is actually rendered from the HTML, the server will send back a 304 (not changed), and the browser will simply load the image from its cache.
Paolo suggests using the following notation to create an image object:
While this will work, the DOM-compliant way of doing this is:
Which is the way it is being done in the script, except it's using jQuery's HTML string literal syntax to do it. Additionally, most modern browsers offer compatibility with the
Image()
constructor by simply calling DOM-standard methods. For example, if you open up the Google Chrome JavaScript console and typeImage
, this is what you'll get:Chrome merely uses the native DOM methods to create an image element.