Очень, очень, очень большой div



для моего проекта (см. BigPictu.re или bigpicture.проект на JS на GitHub), Я должен иметь дело с потенциально очень, очень, очень большой <div> контейнер.



Я знал, что существует риск плохой работы с простым подходом, который я использую, но я не ожидал, что он будет в основном присутствовать ... Только хром!



Если вы тест эта небольшая страница (см. код ниже), панорамирование (нажмите + перетащите) будет:




  • нормальный / гладкий на 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>
569   7  

7 ответов:

изменение position: fixed кажется, чтобы ускорить вещи.

использовать transform вместо top/left:

container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';

демо в jsFiddle.

  1. ответ на первый квест "почему". Одна из проблем размер шрифта. у вас есть размер шрифта 600000px, большинство браузеров увидят его слишком высоким и уменьшат, в то время как chrome пытается отобразить исходный размер. Похоже, chrome не может перекрасить такие большие буквы с запрошенными стилями очень быстро.

но объединение ответов Teemu и geert3 - использование transform и position:fixed, делает chrome работает намного быстрее даже с большими шрифтами.

  1. ответ на 2-й вопрос: "есть способ ... не пытаться отобразить всю страницу" - вы можете попробовать применить действие мыши для элементов в контейнере, а не для всего контейнера.

максимальные размеры шрифта: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 на использование translate:

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)';

демо в jsFiddle.

Я проанализировал это и обнаружил, что исходная проблема связана с архитектурой отображения Chrome и ее использованием фоновых потоков для визуализации страницы.

Если вы хотите иметь быстрый рендеринг, перейдите в chrome: flags, прокрутите до настройки Impl-side painting и установите "Disabled", затем перезапустите браузер - mousemove будет плавным.

Я обнаружил, что если вы включите счетчик FPS, сообщенный FPS в этом сценарии все еще очень высок, даже если фактическая производительность на экране очень низкая. Мое предварительное объяснение (не будучи экспертом по архитектуре отображения Chrome) заключается в том, что если поток пользовательского интерфейса и отображение находятся в разных потоках, то в рендеринге div может возникнуть конфликт - в случае, когда поток пользовательского интерфейса и поток рендеринга находятся в одном потоке, поток пользовательского интерфейса не может отправлять сообщения быстрее, чем поток пользовательского интерфейса может отображать.

Я бы предложил, чтобы это было подано как ошибка Chrome.

использовать display: table и table-layout:fixed на div или таблице, обертывающей div. В HTML:

модель таблиц HTML была разработана таким образом, что с помощью автора агенты пользователей могут отображать таблицы постепенно (т. е. по мере поступления строк таблицы), а не ждать всех данных перед началом визуализации.

для того, чтобы пользовательский агент отформатировал таблицу за один проход, авторы должны сообщить пользовательскому агенту:

количество столбцов в таблице стол. Пожалуйста, обратитесь к разделу расчета количества столбцов в таблице для получения подробной информации о том, как предоставить эту информацию. Ширина этих колонн. Пожалуйста, обратитесь к разделу по расчету ширины столбцов для сведения о том, как предоставить эту информацию.

более точно, агент пользователя может отображать таблицу за один проход, когда ширина столбцов задается с использованием комбинации элементов COLGROUP и COL. Если какой-либо из столбцов указан в поле относительный или процентные условия (см. раздел по расчету ширины столбцов), авторы также должны указать ширину самой таблицы.

для инкрементного отображения браузеру требуется количество столбцов и их ширина. По умолчанию ширина таблицы текущий размер окна (ширина="100%"). Это можно изменить, установив атрибут width элемента таблицы. По умолчанию все столбцы имеют одинаковую ширину, но вы можете указать ширину столбцов с одним или несколькими элементами COL до этого данные таблицы начинаются.

остальная проблема-это количество столбцов. Некоторые люди предложили подождать, пока не будет получена первая строка таблицы, но это может занять много времени, если ячейки имеют много содержимого. В целом, когда требуется инкрементное отображение, имеет смысл заставить авторов явно указать количество столбцов в элементе таблицы.

авторам по-прежнему нужен способ сообщить агентам пользователей, следует ли использовать инкрементные отображение или автоматическое изменение размера таблицы в соответствии с содержимым ячейки. В двухпроходном режиме автоматической калибровки количество столбцов определяется первым проходом. В инкрементном режиме количество столбцов должно быть указано заранее (с элементами COL или COLGROUP).

и CSS:

17.5.2.1 фиксированный макет таблицы

С помощью этого (быстрого) алгоритма горизонтальная компоновка таблицы не зависит от содержимого ячеек; это только зависит от ширины таблицы, ширины столбцов и границ или интервала между ячейками.

ширина таблицы может быть задана явно с помощью свойства 'width'. Значение ' auto '(как для' display: table', так и для' display: inline-table') означает использование алгоритма автоматической компоновки таблиц. Однако, если таблица является таблицей уровня блока ('display: table') в нормальном потоке, UA может (но не должен) использовать алгоритм 10.3.3 для вычисления ширины и применения фиксированной компоновки таблицы, даже если заданная ширина- "авто".

ссылки

Comments

    Ничего не найдено.