Ответ 1
Переход на position: fixed
, кажется, ускоряет работу.
Для моего проекта (см. BigPicture.bi или проект bigpicture.js GitHub), я должны иметь дело с потенциально очень, очень, очень большим контейнером <div>
.
Я знал, что существует риск плохой работы с простым подходом, который я использую, но я не ожидал, что он будет в основном присутствовать... Только 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
, кажется, ускоряет работу.
Используйте transform
вместо top/left
:
container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';
Но объединение ответов Teemu и geert3 - с использованием преобразования и положения: фиксированный, делает хром работает намного быстрее даже с большими шрифтами.
Максимальные размеры шрифта: http://jsfiddle.net/74w7yL0a/
firefox 34 - 2 000 px
chrome 39 - 1 000 000 px
safari 8 - 1 000 000 px
ie 8-11 - 1 431 700 px
В дополнение к ответу Teemu на использование перевода:
container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';
Для чего вы также должны использовать префиксы других поставщиков, вы можете просто исправить это, используя это на теле:
height: 100%;
width: 100%;
position: relative;
overflow: hidden;
и это на html:
height: 100%;
это, однако, отключит прокрутку. Итак, что бы я сделал, добавьте событие mousedown
в тело и примените эти стили, используя класс css всякий раз, когда срабатывает mousedown
, и удаляет этот класс на mouseup
.
@Teemus почти все делает.
Используйте transform
с translate3d
вместо top/left
.
translate3d
позволяет аппаратное ускорение.
container.style.transform = 'translate3d(' + container.x + 'px, ' + container.y + 'px, 0)';
Я проанализировал это, и я обнаружил, что исходная проблема, связанная с архитектурой отображения Chrome, и ее использование фоновых потоков для отображения страницы.
Если вы хотите иметь быструю визуализацию, перейдите в chrome: flags, выделите настройку Impl-side painting и установите "Disabled", затем перезапустите браузер - mousemove будет плавным.
То, что я обнаружил, - это то, что если вы включите счетчик FPS, сообщенный FPS в этом сценарии все еще очень высок, хотя фактическая производительность на экране очень низкая. Мое предварительное объяснение (не являющееся экспертом по архитектуре экрана Chrome) заключается в том, что если поток и отображение пользовательского интерфейса находятся в отдельных потоках, тогда в рендеринге div может возникнуть конфликт в случае, когда поток потоков и потока пользовательского интерфейса находится на тот же поток, поток пользовательского интерфейса не может отправлять сообщения быстрее, чем может отображаться поток пользовательского интерфейса.
Я бы предположил, что это должно быть зарегистрировано как ошибка Chrome.
Используйте display: table
и table-layout:fixed
в div, или таблицу, обернутую div. В HTML:
Модель таблицы HTML была разработана таким образом, чтобы при помощи автора пользовательские агенты могли визуализировать таблицы поэтапно (т.е. по мере поступления строк таблицы), а не ждать до всех данных до начала рендеринга.
Чтобы пользовательский агент мог форматировать таблицу за один проход, авторы должны сообщить агенту пользователя:
Число столбцов в таблице. Для получения подробной информации о том, как предоставить эту информацию, обратитесь к разделу, посвященному расчёту количества столбцов в таблице. Ширина этих столбцов. Подробные сведения о том, как предоставить эту информацию, можно найти в разделе, посвященном вычислению ширины столбцов.
Более точно, пользовательский агент может отображать таблицу за один проход, когда ширина столбца задается с использованием комбинации элементов COLGROUP и COL. Если какой-либо из столбцов указан в относительном или процентном выражении (см. Раздел о вычислении ширины столбцов), авторы должны также указать ширину самой таблицы.
Для инкрементного отображения браузеру требуется количество столбцов и их ширина. Ширина таблицы по умолчанию - это текущий размер окна (width = "100%" ). Это можно изменить, установив атрибут width элемента TABLE. По умолчанию все столбцы имеют одинаковую ширину, но вы можете указать ширину столбцов с одним или несколькими элементами COL до начала ввода данных таблицы.
Остальная проблема - количество столбцов. Некоторые люди предложили дождаться, пока не будет получена первая строка таблицы, но это может занять много времени, если в ячейках много контента. В целом имеет смысл, когда требуется инкрементное отображение, чтобы заставить авторов явно указывать количество столбцов в элементе TABLE.
Авторы по-прежнему нуждаются в способе сообщать пользовательским агентам, следует ли использовать инкрементный дисплей или автоматически сортировать таблицу, чтобы соответствовать содержимому ячейки. В режиме автоматического калибровки двух проходов количество столбцов определяется первым проходом. В инкрементном режиме количество столбцов должно быть указано спереди (с элементами COL или COLGROUP).
и CSS:
17.5.2.1 Фиксированный макет таблицы
С помощью этого (быстрого) алгоритма горизонтальная компоновка таблицы не зависит от содержимого ячеек; это зависит только от ширины таблицы, ширины столбцов и границ или расстояний между ячейками.
Ширина таблицы может быть явно указана с использованием свойства width. Значение "auto" (для "display: table" и "display: inline-table" ) означает использование автоматического алгоритма компоновки таблиц. Однако, если таблица представляет собой таблицу уровня блока ( "display: table" ) в обычном потоке, UA может (но не обязательно) использовать алгоритм 10.3.3 для вычисления ширины и применять фиксированный макет таблицы, даже если указанная ширина - "авто".
Ссылки