html2canvas icon indicating copy to clipboard operation
html2canvas copied to clipboard

Calling html2canvas multiple times increases memory usage on Chrome

Open koenpoppe opened this issue 6 years ago • 16 comments

Bug reports:

Calling html2canvas multiple times increases memory usage.

Specifications:

  • html2canvas version tested with: html2canvas 1.0.0-alpha.12
  • Browser & version: Chrome 68.0.3440.75
  • Operating system: Mac OS 10.13.6 (17G65)

How to reproduce

  1. Go to https://html2canvas.hertzen.com/
  2. Open the developer tools performance monitor: 717 DOM Nodes, JS heap size 14.8 MB
  3. Press 'Try it out'
  4. Press 'Capture' and close the image
  5. Repeat this several times
  6. Open the developer tools performance monitor: 3578 DOM Nodes, JS heap size 19.3 MB

It appears the clean up of the cloned nodes is not working as expected, or Chrome isn't cleaning it up.

chrome

koenpoppe avatar Jul 28 '18 18:07 koenpoppe

me too, wait fix...

Albatrosses avatar Dec 26 '18 09:12 Albatrosses

I use vue-cli3, calling html2canvas multiple times increases memory usage, and fail to compile my project. Otherwise, some picture in my page can't display, calling several times but no out of usage.

ding-xu avatar Jan 22 '19 06:01 ding-xu

I am having the same problem. The nodes are all detached but aren't being garbage collected.

dselgo avatar May 02 '19 14:05 dselgo

Hello! I made some memory profiling using chrome and found a bottleneck with one closure, in my case I commented out the code snippet which isn't used in our case, so this solves the issue for us.

SourceCodeScreenshot

ThunderWorm avatar May 06 '19 11:05 ThunderWorm

Thanks for the suggestion @ThunderWorm, but unfortunately this did not fix the problem for me.

dselgo avatar May 21 '19 14:05 dselgo

We fixed our memory leak by making a change in the file Clone.js around line 541. The previous code was: image It seems that this kept a reference to documentClone so it was never deleted. Instead we made the function async to wait for the response from iframeLoader. The code looks like this: image

nrs32 avatar May 21 '19 17:05 nrs32

This seems to be fixed in the last version (1.0.0-rc3). However, in this version, logging cannot be disabled due to a bug.

Shadorc avatar Aug 12 '19 13:08 Shadorc

This bug still happen in the last version (1.0.0-rc5). Please fixed this.

hungpp250795 avatar Feb 05 '20 07:02 hungpp250795

Any good news here? I got the problem too.

wufeng87 avatar May 21 '20 11:05 wufeng87

I'm also very troubled about this bug... I use last version (1.0.0-rc.5). I called canvas.remove() after called html2canvas but heap memory remained. Do you have any idea to delete heap memory by html2canvas?

スクリーンショット 2020-05-31 01 22 56

yuto7th avatar May 30 '20 15:05 yuto7th

I recommend this one: https://github.com/bubkoo/html-to-image. It is very easy to use. The multiple screenshot function can be realized without memory leak.

yutou15 avatar Dec 23 '20 07:12 yutou15

I recommend this one: https://github.com/bubkoo/html-to-image. It is very easy to use. The multiple screenshot function can be realized without memory leak.

it was way worse for my use case it froze the app entirely

codingedgar avatar Sep 23 '21 17:09 codingedgar

Any progress with that? Those memory leaks are a big problem for me since I use html2canvas about 100 times on the same page...

JeniaGl avatar Nov 15 '21 20:11 JeniaGl

Hello, has the problem been solved?

ffavia avatar Aug 01 '22 09:08 ffavia

I used merge-images lib instead, it worked for me, the memory doesn't overflow anymore. When inserting text data into the image I use the text-to-image library (version 2.4.4), to rotate image I used base64-rotate. https://www.npmjs.com/package/merge-images https://www.npmjs.com/package/text-to-image https://www.npmjs.com/package/base64-rotate

huonghong112 avatar Aug 05 '22 09:08 huonghong112

try this:

html2canvas(dom,{removeContainer:false}).then(function(canvas) {
    document.querySelectorAll('.html2canvas-container').forEach(el => {
        const iframe = el.contentWindow;
        if (el) {
            el.src = 'about:blank';
            iframe.document.write('');
            iframe.document.clear();
            iframe.close();
            el.remove();
        }
    })
    canvas.toBlob(blob => {
      // your code
    });

});

the memory leak comes from those iframes. with those cleanup code it should work better than just remove the iframe from dom tree.

works for me in rendering 10000+ images, 200 max without this fix. will PR later.

yuyuyzl avatar Sep 05 '22 19:09 yuyuyzl

Any Update? I am using latest 1.4.1. Calling 10 times itself crashing chrome. aw snap coming.

thilsenoffice avatar Jul 11 '23 10:07 thilsenoffice

Will this be addressed? @niklasvh please suggest some solution. I am using html2pdf and it is internally using this library, and on Safari, it fails and gives warning Total canvas memory use exceeds the maximum limit (480 MB). After which getContext('2d') returns null and code crashes.

alizaidi606 avatar Aug 16 '23 05:08 alizaidi606

try this:

html2canvas(dom,{removeContainer:false}).then(function(canvas) {
    document.querySelectorAll('.html2canvas-container').forEach(el => {
        const iframe = el.contentWindow;
        if (el) {
            el.src = 'about:blank';
            iframe.document.write('');
            iframe.document.clear();
            iframe.close();
            el.remove();
        }
    })
    canvas.toBlob(blob => {
      // your code
    });

});

the memory leak comes from those iframes. with those cleanup code it should work better than just remove the iframe from dom tree.

works for me in rendering 10000+ images, 200 max without this fix. will PR later. @yuyuyzl When I try this it breaks my code because I use html2canvas separately for each element and element can not be found later.

muratcanoguzhan avatar Oct 13 '23 14:10 muratcanoguzhan