Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does IE freeze on Layout when rendering an empty SVG element?

I am currently hitting an issue in IE 10 and 11 where the browser tab is hanging every now and then on Layout in the UI Responsiveness tool. I am part of a team writing a fairly large knockout.js web app, so nailing down the exact condition that is creating this issue has been extremely difficult. From what I can tell, the browser tab hangs when Layout is performed when the removal of loading indicator HTML is removed from the page and some divs plus an empty SVG tag is appended to the DOM in its place.

I have been able to nail down that the empty SVG tag is the culprit, but I do not know why and I cannot remove that tag from the page is it is an important element to a D# data visualization that I am trying to create.

Here is the US Responsiveness report that IE 11 has provided me. I have zoomed in on the problematic area, and as you can see in the picture, the Layout thread spikes the CPU to 100%.

enter image description here

Before I get into the code samples my question is:

Why would the browser tab intermittently freeze/hang from adding an empty SVG element to the page?

The HTML gets appended to the DOM via javascript in as minimal of a way as possible from my research on reducing reflow in the browser:

var contentHTML = "";
contentHTML += '<div class="axis-title y-axis-title">' + renderString(bindingData.yAxis.title) + "</div>";
contentHTML += '<div class="' + CANVAS_CLASS + '"></div>';
contentHTML += '<svg class="x-axis"></svg>'; // The problematic element

element.innerHTML = contentHTML;

This results in the following HTML (note: all of the data-bind stuff is for knockout.js binding handlers, which triggers the JS above):

<div class="chart" data-bind="
barChart: {
    data: rowData,
    categoryTextKey: 'label',
    valueKey: 'keyOnObject',
    xAxis: {
        title: 'xAxisTitle',
        domain: [-1, 1]
    },
    yAxis: {
        title: 'yAxisTitle'
    },
    onClick: onLabelClick,
    formatValueText: formatPercentage
}
"></div>
    <div class="axis-title y-axis-title">Y Title</div>
    <div class="chart-canvas"></div>
    <svg xmlns="http://www.w3.org/2000/svg" class="x-axis" />
    <div class="axis-title x-axis-title">X Title</div>
</div>

Lastly, I also am using flexbox CSS rules to lay out my HTML. I am not sure if that is affecting this issue, but here is the CSS in case it helps:

.chart {
    .flexbox();
    .flex-direction(column);
    height: 100%;
    width: 100%;

    .chart-label-click {
        cursor: pointer;
    }

    .chart-header,
    .axis-title,
    .x-axis {
        .flex-grow(0);
        .flex-shrink(0);
    }

    .chart-canvas {
        .flex-grow(1);
        .flex-shrink(1);

        overflow-x: hidden;
        overflow-y: auto;
        width: 100%;
    }

    .chart-canvas svg {
        display: block;
        width: 100%;
    }

    .axis-title {
        font-weight: bold;
    }

    .x-axis {
        .flexbox();
        .flex-grow(0);
        .flex-basis(20px);

        margin-bottom: 5px;
        overflow: visible;
        width: 100%;
    }

    .x-axis line,
    .x-axis path {
        fill: none;
        stroke: #d1d1d1;
        stroke-width: 1px;
        shape-rendering: crispEdges;
    }
}

Thank you for any help you may have. I am not sure how to nail this down is it is intermittent in one section of our app and our codebase is pretty big to figure out the exact combination of code in other files that may also be contributing to this issue.

like image 264
linusthe3rd Avatar asked Aug 12 '14 21:08

linusthe3rd


1 Answers

The described issue seems to be this bug: https://connect.microsoft.com/IE/feedback/details/796745/mouse-events-are-not-delivered-at-all-anymore-when-inside-an-svg-a-use-is-removed-from-the-dom

In the comments is a workaround described which at least worked for us: You have to set style="pointer-events: none;" on the use elements. Or simply add this to your css:

svg use { pointer-events:none; }

But be aware that this also disables any mouse events triggered on the use element.

like image 175
brass monkey Avatar answered Sep 21 '22 13:09

brass monkey