Для моего проекта (см. BigPictu.re или bigpicture.js проект GitHub ) мне приходится иметь дело с потенциально очень, очень, очень большим <div>
контейнером.
Я знал, что при использовании простого подхода есть риск снижения производительности, но я не ожидал, что он будет присутствовать в основном с ... только Chrome!
Если вы протестируете эту маленькую страницу (см. Код ниже), панорамирование (щелчок + перетаскивание) будет:
- Нормальный / гладкий в Firefox
- Нормально / плавно даже в Internet Explorer
- Очень медленно (почти вылетает) в Chrome!
Конечно, я мог бы добавить некоторый код (в свой проект), чтобы сделать это, когда вы сильно увеличите масштаб, текст с потенциально очень большим размером шрифта будет скрыт. Но все же, почему Firefox и Internet Explorer обрабатывают это правильно, а не Chrome?
Есть ли способ в JavaScript, HTML или CSS, чтобы браузер не пытался отображать всю страницу (которая здесь имеет ширину 10000 пикселей) для каждого действия? (визуализировать только текущий видовой экран!)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
html, body {
overflow: hidden;
min-height: 100%; }
#container {
position: absolute;
min-height: 100%;
min-width: 100%; }
.text {
font-family: "Arial";
position: absolute;
}
</style>
</head>
<body>
<div id="container">
<div class="text" style="font-size: 600px; left:100px; top:100px">Small text</div>
<div class="text" style="font-size: 600000px; left:10000px; top:10000px">Very big text</div>
</div>
<script>
var container = document.getElementById('container'), dragging = false, previousmouse;
container.x = 0; container.y = 0;
window.onmousedown = function(e) { dragging = true; previousmouse = {x: e.pageX, y: e.pageY}; }
window.onmouseup = function() { dragging = false; }
window.ondragstart = function(e) { e.preventDefault(); }
window.onmousemove = function(e) {
if (dragging) {
container.x += e.pageX - previousmouse.x; container.y += e.pageY - previousmouse.y;
container.style.left = container.x + 'px'; container.style.top = container.y + 'px';
previousmouse = {x: e.pageX, y: e.pageY};
}
}
</script>
</body>
</html>
Ответы:
Переход на ,
position: fixed
кажется, ускорить процесс .источник
fixed
очевидно, проще разложить и, возможно, они смогут сделать больше оптимизаций. Но я не смотрел исходный код движка рендеринга, если вы имеете в виду ;-)Используйте
transform
вместоtop/left
:Живая демонстрация на jsFiddle .
источник
fixed
выводит элемент из потока текста и избавляет от необходимости повторного рендеринга. В документацииtransform
MDN говорится: «... будет создан контекст наложения. В этом случае объект будет действовать как содержащий блок для элементов position: fixed, которые он содержит».<div style="position:relative;min-height: 900px;">Your's divs</div>
jsFiddle, так же как иposition:relative
вероятного, что похоже на ответНо объединение ответов Teemu и geert3 - использование transform и position: fixed - заставляет хром работать намного быстрее даже с большими шрифтами.
Максимальные размеры шрифта: http://jsfiddle.net/74w7yL0a/
источник
font-size
и это может быть причиной отсутствия медленности на FF. Но тогда на IE тоже должно было быть очень медленно, но это не ... Странно!В дополнение к ответу Теему об использовании перевода:
Которые вы также должны использовать префиксы других поставщиков. Вы можете просто исправить это, используя это в теле:
и это в html:
это, однако, отключит прокрутку. Итак, что я бы сделал, это добавить
mousedown
событие в тело и применить эти стили, используя класс css всякий раз, когдаmousedown
он запускается, и удалить этот классmouseup
.источник
style.transform
или с использованиемtransform
?). Кстати, спасибо за ответ @Prisoner!Ответ @Teemus делает почти все.
Используйте
transform
сtranslate3d
вместоtop/left
.translate3d
обеспечивает аппаратное ускорение.Живая демонстрация на jsFiddle .
источник
Я проанализировал это и обнаружил, что исходная проблема связана с архитектурой отображения Chrome и использованием фоновых потоков для визуализации страницы.
Если вы хотите иметь быстрый рендеринг, войдите в chrome: flags, прокрутите до параметра Impl-side painting и установите «Disabled», затем перезапустите браузер - движение мыши будет плавным.
Я обнаружил, что если вы включите счетчик FPS, заявленный FPS в этом сценарии все еще будет очень высоким, даже несмотря на то, что фактическая производительность на экране очень низкая. Мое предварительное объяснение (не являющееся экспертом по архитектуре отображения Chrome) заключается в том, что если поток пользовательского интерфейса и отображение находятся в разных потоках, тогда может возникнуть конфликт при рендеринге div - в случае, когда поток пользовательского интерфейса и поток рендеринга находятся в того же потока, поток пользовательского интерфейса не может отправлять сообщения быстрее, чем поток пользовательского интерфейса может отобразить.
Я бы посоветовал зарегистрировать это как ошибку Chrome.
источник
Используйте
display: table
иtable-layout:fixed
в div или таблицу, оборачивающую div. В HTML:и CSS:
Ссылки
источник