Performance issues with HTML to canvas, where to begin?
I have been working on an experiment to render HTML into a canvas image, by having javascript read all the necessary information from the loaded DOM. As canvas lacks many of the standard parts of CSS, especially when it comes to text formatting, a lot of work arounds and performance intense processes need to be done (letter-开发者_如何学运维spacing
for one). The intent is and never will be to make a fool proof HTML renderer, as it simply won't be possible, but instead try and make as accurate as it can be.
For the sample pages, Google Chrome usually loads them significantly faster than FF. However, for some pages (usually the bigger ones), Chrome completely freezes, where as Firefox loads them fine. Now, I have been trying to pinpoint where exactly things go haywire, but haven't had much luck as it doesn't end up outputting anything in Chrome.
Does Chrome have some limit of how many canvas draws can be performed within a certain time span, or how much system resources a page can use? How can I start untangling the bottleneck if I can't get any sort of feedback from the page at all (as it just hangs up)?
Examples (what it should do, is render a canvas image on top of the page, which should look more or less same than the actual HTML page. You can toggle the canvas image (show/hide) by clicking it. Please don't open them either if you got unsaved work in your browsers, as it may end up hanging them as well.):
simple test, works fine in FF/Chrome
another simple test, works fine in FF/Chrome
Complete page, works fine in FF/Chrome
Complete page, only works in FF < 4, Chrome freezes
They all use the same js which can be found here.
I am not looking for a blazing fast script, as with the type of emulation this renders the images, I don't think it could even be done. Simply trying to find ways to make it perhaps slightly more efficient, without losing any of its current functionality.
Where to begin?
Break it down.
Use the same example and cut how much you do it it (your rendering code) in half. Does it still not work? In half again, etc. Did it work? Put back half of what you took out.
As in, get rid of all attempted text rendering, or all border/padding code. Just comment it out. Does it work then?
Or try just commenting out ctx.drawImage(img,x,y);
on line 199 and nothing else. Does it work then?
If you're lucky you'll be able to determine a critical point where Chrome is spending a lot of time doing something.
Have you tried using Chrome's built-in performance profiler?
The problem appeared to be with the css attribute background-repeat
, and specifically repeat-x
. Commenting out
for(bgx=(x+background_position_left);bgx<=w;){
drawImage(image,bgx,(y+background_position_top));
bgx = bgx+image.width;
}
Fixed the issue at least for chrome, and looking at that it most likely was an endless loop as Kinlan proposed, but why exactly it gets stuck only on newer versions of FF and chrome is something I'll need to look more in detail (most likely not having the image.width available yet, or something similar).
精彩评论