Image loading performance improvements

Performance improvements are achieved by using requestAnimationFrame when
a tile's visibility changes, and by not starting with a blank image when
creating a new tile image. It seems that even Firefox does not show a
loading placeholder when the tile is made visible in an animation.
This commit is contained in:
ahocevar
2012-10-05 09:24:53 +02:00
parent e3a5091ebd
commit 7e5e221c8d
2 changed files with 32 additions and 35 deletions

View File

@@ -232,7 +232,6 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
OpenLayers.Tile.prototype.clear.apply(this, arguments);
var img = this.imgDiv;
if (img) {
OpenLayers.Event.stopObservingElement(img);
var tile = this.getTile();
if (tile.parentNode === this.layer.div) {
this.layer.div.removeChild(tile);
@@ -252,11 +251,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
*/
getImage: function() {
if (!this.imgDiv) {
this.imgDiv = document.createElement("img");
this.imgDiv.className = "olTileImage";
// avoid image gallery menu in IE6
this.imgDiv.galleryImg = "no";
this.imgDiv = OpenLayers.Tile.Image.IMAGE.cloneNode(false);
var style = this.imgDiv.style;
if (this.frame) {
@@ -302,36 +297,20 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
if (this.url && img.getAttribute("src") == this.url) {
this.onImageLoad();
} else {
// We need to start with a blank image, to make sure that no
// loading image placeholder and no old image is displayed when we
// set the display style to "" in onImageLoad, which is called
// after the image is loaded, but before it is rendered. So we set
// a blank image with a data scheme URI, and register for the load
// event (for browsers that support data scheme) and the error
// event (for browsers that don't). In the event handler, we set
// the final src.
var load = OpenLayers.Function.bind(function() {
if (img.getAttribute("src") !== this.blankImageUrl) {
OpenLayers.Event.stopObservingElement(img);
OpenLayers.Event.observe(img, "load",
OpenLayers.Function.bind(this.onImageLoad, this)
);
OpenLayers.Event.observe(img, "error",
OpenLayers.Function.bind(this.onImageError, this)
);
this.imageReloadAttempts = 0;
this.setImgSrc(this.url);
}, this);
if (img.getAttribute("src") == this.blankImageUrl) {
load();
} else {
OpenLayers.Event.stopObservingElement(img);
OpenLayers.Event.observe(img, "load", load);
OpenLayers.Event.observe(img, "error", load);
if (this.crossOriginKeyword) {
img.removeAttribute("crossorigin");
}
img.src = this.blankImageUrl;
}
OpenLayers.Event.observe(img, "load",
OpenLayers.Function.bind(this.onImageLoad, this)
);
OpenLayers.Event.observe(img, "error",
OpenLayers.Function.bind(this.onImageError, this)
);
this.imageReloadAttempts = 0;
this.setImgSrc(this.url);
}
},
@@ -359,6 +338,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
} else {
// Remove reference to the image, and leave it to the browser's
// caching and garbage collection.
OpenLayers.Event.stopObservingElement(this.imgDiv);
this.imgDiv = null;
if (img.parentNode) {
img.parentNode.removeChild(img);
@@ -410,12 +390,14 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
var img = this.imgDiv;
OpenLayers.Event.stopObservingElement(img);
img.style.visibility = 'inherit';
img.style.opacity = this.layer.opacity;
OpenLayers.Animation.requestFrame(OpenLayers.Function.bind(function() {
img.style.visibility = 'inherit';
img.style.opacity = this.layer.opacity;
this.events.triggerEvent("loadend");
}, this));
this.isLoading = false;
this.canvasContext = null;
this.events.triggerEvent("loadend");
if (this.layerAlphaHack === true) {
img.style.filter =
@@ -477,3 +459,16 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
CLASS_NAME: "OpenLayers.Tile.Image"
});
/**
* Constant: OpenLayers.Tile.Image.IMAGE
* {HTMLImageElement} The image for a tile.
*/
OpenLayers.Tile.Image.IMAGE = (function() {
var img = new Image();
img.className = "olTileImage";
// avoid image gallery menu in IE6
img.galleryImg = "no";
return img;
}());