系统相关
首页 > 系统相关> > CSS频繁绘图中transform导致的内存占用问题

CSS频繁绘图中transform导致的内存占用问题

作者:互联网

摘要

解决频繁使用CSS中transform转换图像绘制pie chart时导致内存占用持续增加的解决方案。

正文

场景,我需要使用https://codepen.io/ejsado/pen/yLNMPG 这个饼图样式每隔1ms绘制预测结果,使用过程中浏览器内存占用暴涨,研究发现,这个饼图组件使用"transform" : "rotate("+sizeRotation+"deg) translate3d(0,0,0)",绘制图形,而transform每次绘制完后,旧图像依然占据内存,如截图所示:

一次绘图产生五条transform的div,内存占用不断增长,占据的内存没有在下一次绘图前回收。
解决方法:

那是因为 transform并没有让元素脱离标准流;解决方法:可以考虑在写了transform属性后,结合position:absolute脱标
link:https://m.imooc.com/wenda/detail/527182

$(".slice").remove();
createPie(".pieID.pie_legend", ".pieID.pie");

我猜测浏览器中image标签导致的内存持续增加问题也可以通过这个方法解决,下次遇到试试

附录:pie chart的源码及注解,开箱即用

image
pie.css:

/*@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700);*/

@keyframes bake-pie {
    from {
        transform: rotate(0deg) translate3d(0,0,0);
    }
}

.pieID {
    display: inline-block;
    vertical-align: top;
}
.pie {
    height: 200px;
    width: 200px;
    position: relative;
    margin: 0 30px 30px 0;
}
.pie::before {
    content: "";
    display: block;
    position: absolute;
    background: #FFFFFF;
    z-index: 1;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    top: 50px;
    left: 50px;
}
.pie::after {
    content: "";
    display: block;
    width: 120px;
    height: 2px;
    background: rgba(0,0,0,0.1);
    border-radius: 50%;
    box-shadow: 0 0 3px 4px rgba(0,0,0,0.1);
    margin: 220px auto;

}
.slice {
    position: absolute;
    width: 200px;
    height: 200px;
    clip: rect(0px, 200px, 200px, 100px);
    animation: bake-pie 1s;
}
.slice span {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    background-color: black;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    clip: rect(0px, 200px, 200px, 100px);
}
.pie_legend {
    list-style-type: none;
    padding: 0;
    margin: 0;
    background: #FFF;
    padding: 15px;
    font-size: 13px;
    box-shadow: 1px 1px 0 #DDD,
    2px 2px 0 #BBB;
}
.pie_legend li {
    width: 150px;
    height: 1.25em;
    margin-bottom: 0.7em;
    padding-left: 0.5em;
    border-left: 1.25em solid black;
}
.pie_legend em {
    font-style: normal;
}
.pie_legend span {
    float: right;
}

pie.js

function sliceSize(dataNum, dataTotal) {
    return (dataNum / dataTotal) * 360;
}
function addSlice(sliceSize, pieElement, offset, sliceID, color) {
    $(pieElement).append("<div class='slice "+sliceID+"'><span></span></div>");
     offset = offset - 1;
    var sizeRotation = -179 + sliceSize;
    $("."+sliceID).css({
        "transform": "rotate("+offset+"deg) translate3d(0,0,0)"
    });
    $("."+sliceID+" span").css({
        "transform"       : "rotate("+sizeRotation+"deg) translate3d(0,0,0)",
        "background-color": color
    });
}
function iterateSlices(sliceSize, pieElement, offset, dataCount, sliceCount, color) {
    var sliceID = "s"+dataCount+"-"+sliceCount;
    var maxSize = 179;
    if(sliceSize<=maxSize) {
        addSlice(sliceSize, pieElement, offset, sliceID, color);
    } else {
        addSlice(maxSize, pieElement, offset, sliceID, color);
        iterateSlices(sliceSize-maxSize, pieElement, offset+maxSize, dataCount, sliceCount+1, color);
    }
}
function createPie(dataElement, pieElement) {
    var listData = [];
    $(dataElement+" span").each(function() {
        listData.push(Number($(this).html()));
    });
    var listTotal = 0;
    for(var i=0; i<listData.length; i++) {
        listTotal += listData[i];
    }
    var offset = 0;
    var color = [
        "cornflowerblue",
        "olivedrab",
        "orange",
        "tomato",
        "crimson",
        "purple",
        "turquoise",
        "forestgreen",
        "navy",
        "gray"
    ];
    for(var i=0; i<listData.length; i++) {
        var size = sliceSize(listData[i], listTotal);
        iterateSlices(size, pieElement, offset, i, 0, color[i]);
        $(dataElement+" li:nth-child("+(i+1)+")").css("border-color", color[i]);
        offset += size;
    }
}

HTML



<!-- 插入到页面的内容-->
                            <section style="margin-top:10px">
                                <div class="pieID pie">
                                </div>
                                <ul class="pie_legend pieID ">
                                    <li>
                                        <em id = "sym1"></em>
                                        <span id = "prob1"></span>
                                    </li>
                                    <li>
                                        <em id = "sym2"></em>
                                        <span id = "prob2"></span>
                                    </li>
                                    <li>
                                        <em id = "sym3"></em>
                                        <span id = "prob3"></span>
                                    </li>
                                    <li>
                                        <em id = "sym4"></em>
                                        <span id = "prob4"></span>
                                    </li>
                                    <li>
                                        <em id = "sym5"></em>
                                        <span id = "prob5"></span>
                                    </li>
                                </ul>
                            </section>
<!-- 插入到页面的内容-->


<script>
/*
使用前需要赋值的几个属性
                 indices = findIndicesOfMax(pred, 5)
                 probs = findTopValues(pred, 5, indices)
                 names = getClassNames(indices)
                setTable(names, probs)
*/

    function findIndicesOfMax(inp, count) {
        var outp = [];
        for (var i = 0; i < inp.length; i++) {
            outp.push(i); // add index to output array
            if (outp.length > count) {
                outp.sort(function(a, b) {
                    return inp[b] - inp[a];
                }); // descending sort the output array
                outp.pop(); // remove the last index (index of smallest element in output array)
            }
        }
        return outp;
    }
    //找到前五个最大的值
    function findTopValues(inp, count,indices) {
        var outp = [];
        // show 5 greatest scores
        for (var i = 0; i < indices.length; i++)
            outp[i] = inp[indices[i]]
        return outp
    }
    // 找到对应的类名
    function getClassNames(indices) {
        var outp = []
        for (var i = 0; i < indices.length; i++)
            outp[i] = classNames[indices[i]]
        return outp
    }
    function setTable(top5, probs) {
        //loop over the predictions
        for (var i = 0; i < top5.length; i++) {
            let sym = document.getElementById('sym' + (i + 1))
            let prob = document.getElementById('prob' + (i + 1))
            sym.innerHTML = top5[i]
            prob.innerHTML = Math.round(probs[i] * 100.0)
        }
        //create the pie
        $(".slice").remove();
        createPie(".pieID.pie_legend", ".pieID.pie");
    }
</script>

标签:outp,pie,transform,indices,内存,var,CSS,200px
来源: https://www.cnblogs.com/abestxun/p/16303623.html