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
- 实际更为简单的方法是在绘制新图形前将就的图像remove。
$(".slice").remove();
createPie(".pieID.pie_legend", ".pieID.pie");
我猜测浏览器中image标签导致的内存持续增加问题也可以通过这个方法解决,下次遇到试试
附录:pie chart的源码及注解,开箱即用
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