How can I prevent memory leaks when removing images in the DOM?

前端 未结 5 478
不思量自难忘°
不思量自难忘° 2020-12-23 11:50

There is a known bug in webkit that when you remove an image from the DOM, it doesn\'t free the memory associated with it.

This is an issue with single page apps tha

5条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-23 12:15

    A basic image pool should allow you to recycle img elements for re-use. Since you don't know how many images there will be total ahead of time, just have the pool size expand as necessary.

    Something like this should work:

        function getImg( id, src, alt ) {
            var pool = document.getElementById( 'image_pool' );
            var img = ( pool.children.length > 0 ) ? pool.removeChild( pool.children[0] ) : document.createElement( 'img' );
            img.id = id;
            img.src = src;
            img.alt = alt;
            return img;
        }
        function recycleImg( id ) {
            var img = document.getElementById( id );
            document.getElementById( 'image_pool' ).appendChild( img.parentNode.removeChild( img ) );
        }
    

    Place a hidden "image_pool" container on your page somewhere, to hide the recycled images between usage:

    
    

    Then any time you need a new img element, call:

    document.getElementById( 'some_element_id' ).appendChild( getImg( 'my_image_id', 'images/hello.gif', 'alt_text' ) );
    

    And when you are done with it:

    recycleImg( 'my_image_id' );
    

    jQuery alternative

        function getImg( id, src, alt ) {
            var img;
            if( $("#image_pool").children().length > 0 ) {
                return $("#image_pool img:first-child").attr( { 'id': id, 'src': src, 'alt': alt } ).detach();
            }
            return $( "'" ).attr( { 'id': id, 'src': src, 'alt': alt } );
        }
        function recycleImg( id ) {
            $( "#" + id ).detach().appendTo( $("#image_pool") );
        }
    

    When you need a new img element:

    getImg( 'my_image_id', 'images/hello.gif', 'alt_text' ).appendTo( $( "#some_element_id" ) );
    

    (recycling works the same as above)

提交回复
热议问题