У меня было много проблем с плохой производительностью в IE (все версии, включая IE11) в виджете на базе HTML / SVG javascript, только когда виджет размещен на определенной странице.
После определения того, что основной причиной замедления были перерисовки слоя рисования / рендеринга и исчерпав информацию об этом, которую я мог получить из IE Developer Tools, я прибег к методам проб и ошибок, отключая классы предков по одному, пока производительность не улучшится; затем, при идентификации класса, отключение правил стиля по одному.
Вся моя проблема, кажется, сводится к одному правилу overflow: hidden;
для предка, находящегося на несколько делений вверх по дереву.
Разница невероятна: с overflow: hidden;
вверх по дереву простое взаимодействие с пользователем (выделение пути SVG, создание текстовой метки HTML, отображение метки и ее расположение относительно пути и контейнера SVG) максимально загружает процессор, сокращает время Частота кадров пользовательского интерфейса равна нулю, и все "замораживается" на время от 1000 до 4000 миллисекунд на каждое взаимодействие. Без overflow: hidden;
на предке он завершается за десятки миллисекунд, а частота кадров никогда не падает ниже половины (браузеры, отличные от IE, одинаковы независимо от overflow: hidden;
).
Вот профиль с
overflow: hidden;
на предке, профилирующий как включенные, так и выключенные взаимодействия, отфильтрованный для рисования событий:Вот профиль без
overflow: hidden;
на предке, профилирующий как включенные, так и выключенные взаимодействия, отфильтрованные для рисования событий. Единственное изменение заключалось в установке или снятии флажка рядом со стилемoverflow: hidden;
в инспекторе DOM, и не имеет значения, в каком порядке я выполняю тесты:
Я не хочу просто отвергать это overflow: hidden;
как липкий пластырь и говорить, что работа сделана, не понимая, как это происходит, и рискую, что проблема возникнет снова с другими, казалось бы, тривиальными изменениями CSS. Я бы предпочел понять, почему overflow: hidden;
имеет такое значение, и решить это надежным способом, который работает независимо от применяемого правила переполнения.
К сожалению, я не могу опубликовать полную демонстрацию, но вот краткое изложение соответствующей части структуры DOM с комментариями к стилям, связанным с макетом:
<div class="responsive-grid">
<!-- ...lots of nested divs that simply inherit styles, I can't change this aspect of the Drupal layout -->
<div id="panel-5" class="col-12"> <!-- width: 100%; float: left -->
<!-- this is the first element IE looks at for offsetWidth when doing the changes below -->
<!-- ...a few more nested divs without layout-changing styles -->
<div class="panel"> <!-- overflow: hidden; clear: both; border: 1px; -->
<!-- this is the element where removing the overflow: hidden changes everything -->
<!-- I'm not sure what clear:both is for here, since no siblings. Seems redundant -->
<!-- ...a few more nested divs with no style rules, some contain <p>s <h2>s etc... -->
<div class="container"> <!-- position: relative; -->
<div class="sub-column col-8"> <!-- width: 66%; display: inline-block -->
<div class="square"> <!-- width: 100%; padding-bottom: 100%; position: relative -->
<svg viewbox="0 0 500 500" preserveAspectRatio="XMinYMin meet" ...>
<!-- svg position: absolute; width:100%; height: 100% -->
Many paths here
<div class="label"> <!-- fixed width in pixels; position: absolute -->
Some text here
</div>
</div>
</div>
<div class="sub-column col-4"> <!-- width: 33%; display: inline-block -->
<div class="sidebar">
Many interactive controls here
<!-- .square, svg andd .sidebar contain the only elements that are updated -->
</div>
</div>
</div>
<!-- some more ordinary position: static text containers -->
</div>
</div>
</div>
Что может здесь происходить, и есть ли способ предотвратить это, не удаляя / запрещая overflow: hidden;
в элементе-предке?
Я видел Как избежать потери производительности при переполнении: скрыто?, но и вопросы, и ответы кажутся специфичными для таблиц HTML и старой ошибки Webkit, которая была исправлена.
Они также кажутся специфичными для случаев, когда содержимое, обрезанное переполнением, без нужды окрашивается; особенность моего случая заключается в том, что overflow: hidden;
на самом деле не сильно обрезает (если вообще что-либо) на этой странице (но я не могу просто удалить его, потому что он является частью шаблона, влияющего на сотни других страниц, где он действительно имеет эффект).
Обновление: сюжет сгущается. Мне удалось воспроизвести проблему с моим виджетом в более простой структуре HTML, и я обнаружил, что проблема возникает только в том случае, если оба overflow: hidden;
и border-radius
(в моем случае 3px) установлены в одном контейнере. С любым из них, но не с другим, проблема исчезает.