【问题标题】:Why does IE freeze on Layout when rendering an empty SVG element?渲染一个空的 SVG 元素时,为什么 IE 会在 Layout 上冻结?
【发布时间】:2014-10-06 03:15:47
【问题描述】:

我目前在 IE 10 和 11 中遇到了一个问题,即浏览器选项卡时不时地挂在 UI 响应工具中的布局上。我是一个编写相当大的 knockout.js Web 应用程序的团队的一员,因此确定造成此问题的确切条件非常困难。据我所知,当从页面中删除加载指示符 HTML 并且一些 div 加上一个空的 SVG 标记被附加到 DOM 的位置时,执行 Layout 时,浏览器选项卡会挂起。

我已经能够确定空的 SVG 标记是罪魁祸首,但我不知道 为什么 我无法从页面中删除该标记,因为它是 D# 的重要元素我正在尝试创建的数据可视化。

这是 IE 11 提供给我的美国响应度报告。我已经放大了有问题的区域,正如你在图片中看到的那样,Layout 线程使 CPU 达到 100%。

在我进入代码示例之前,我的问题是:

为什么浏览器标签会因向页面添加空 SVG 元素而间歇性冻结/挂起?

根据我对减少浏览器重排的研究,HTML 通过 javascript 以尽可能少的方式附加到 DOM:

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;

这会产生以下 HTML(注意:所有数据绑定的东西都是针对 knockout.js 绑定处理程序的,它会触发上面的 JS):

<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>

最后,我还使用 flexbox CSS 规则来布局我的 HTML。我不确定这是否会影响这个问题,但这里是 CSS 以防万一:

.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;
    }
}

感谢您提供的任何帮助。我不确定如何确定这一点,因为它在我们的应用程序的一个部分是断断续续的,而且我们的代码库非常大,无法确定其他文件中也可能导致此问题的代码的确切组合。

【问题讨论】:

  • &lt;svg&gt; 应该使用var svg = document.createElementNS('http://www.w3.org/2000/svg', "svg"); 创建,然后使用svg.setAttributeNS(...)。另一种方法是使用importNode()
  • 您是否尝试过将 svg 元素嵌入为 &lt;iframe&gt;&lt;object&gt;&lt;embed&gt;?另外,请尝试在 jsfiddle 页面中隔离此问题,以便您可以更好地诊断,其他人可以轻松地帮助测试/调试它。

标签: css internet-explorer svg internet-explorer-10 internet-explorer-11


【解决方案1】:

确保您的代码没有在 JavaScript(或其他语言)中设置值,甚至没有以下引号...

var a = ;//[var][space][a][space][=][space][;]

这将冻结 IE11(不确定 10 个副手)。

【讨论】:

    【解决方案2】:

    我最终解决此问题的方法是删除display:flex.chart 元素的使用。取而代之的是,我使用了固定高度和display:block。当将 SVG 和 flexbox 混合在一起时,看起来这最终是一个带有 IE 的错误。

    【讨论】:

      【解决方案3】:

      所描述的问题似乎是这个错误: 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

      在 cmets 中描述了一个至少对我们有用的解决方法: 您必须在使用元素上设置style="pointer-events: none;"。 或者简单地将其添加到您的 css 中:

      svg use { pointer-events:none; }
      

      但请注意,这也会禁用在 use 元素上触发的任何鼠标事件。

      【讨论】:

        【解决方案4】:

        经过多天的搜索,我决定解决这个问题:

        svg use { pointer-events:none; }
        

        【讨论】:

          猜你喜欢
          • 2016-10-23
          • 2021-08-18
          • 1970-01-01
          • 2016-03-10
          • 2020-09-24
          • 2017-04-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-09
          相关资源
          最近更新 更多