How to detect when an image has finished rendering in the browser (i.e. painted)?

老子叫甜甜 提交于 2019-12-17 23:37:05

问题


On a web app I need to work with a lot of high-res images, which are dynamically added to the DOM tree. They are pre-loaded, then added to the page.

It's one thing to detect when such an image has finished loading, for this I use the load event, but how can I detect when it has finished being rendered within the browser, using Javascript? When working with high resolution images, the actual painting process can take a lot of time and it's very important to know when it ends.


回答1:


I used requestAnimationFrame to do the trick. After image loaded it will be rendered during the next animation frame. So if you wait two animation frame your image will be rendered.

function rendered() {
    //Render complete
    alert("image rendered");
}

function startRender() {
    //Rendering start
    requestAnimationFrame(rendered);
}

function loaded()  {
    requestAnimationFrame(startRender);
}

See http://jsfiddle.net/4fg3K/1/




回答2:


I had the same problem. I have created the preloader page with progress bar. When the image is loaded, the white background preloader page disappears smoothly to opacity: 0, but the image is still not rendered.

I have finally used the setInterval, when the image is loaded (but not rendered). In the interval I check the naturalWidth and naturalHeight properties (Support: IE9+). Initialy it equals 0 and when the image is rendered it shows its current width and height.

const image = document.getElementById('image');

image.src = "https://cdn.photographylife.com/wp-content/uploads/2014/06/Nikon-D810-Image-Sample-1.jpg";

image.onload = function () {
  console.log('Loaded: ', Date.now());
  const interval = setInterval(() => {
    if (image.naturalWidth > 0 && image.naturalHeight > 0) {
      clearInterval(interval);
      rendered();
    }
  }, 20);
}

function rendered() {
  console.log('Rendered: ', Date.now());
}
img{
  width: 400px;
}
<img id="image"/>



回答3:


from mdn,

The MozAfterPaint event is triggered when content is repainted on the screen and provides information about what has been repainted. It is mainly used to investigate performance optimization

Hope you are doing this to gauge performance of the rendered image.




回答4:


Update: Do not use this approach - doesn't work in cases where the image dimensions are set to something else than the default

You could set the element's height to auto (with a fixed width) and with a timeout keep on checking of the element's dimensions match with the natural dimensions of the image. It's not the best solution but if you really need to do something after rendering and not after loading, it's a good option.

More or less that's how it could look:

//this is NOT a real code
function checkIfRendered(img, onRender) {
    var elRatio = img.width() / img.height();
    var natRatio = img.naturalWidth / img.naturalHeight;

    if (elRatio === natRatio)
        onRender();
    else {
        setTimeout(function() {
            checkIfRendered(imgEl, onRender)
        }, 20);
    }
}

img.onload(checkIfRendered(img, function() { alert('rendered!'); }));



回答5:


You need the onload event on the <img> tag. For example:

function loadImage () {
  alert("Image is loaded");
}
<img src="w3javascript.gif" onload="loadImage()" width="100" height="132">

source

If the image is the background of another element, load the image in the background (with a simple Ajax GET request) and when the result comes back, set the background after it has been loaded.



来源:https://stackoverflow.com/questions/14578356/how-to-detect-when-an-image-has-finished-rendering-in-the-browser-i-e-painted

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!