Дуже, дуже, дуже великий дів


109

Для мого проекту (див. Проект 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>

54
[OT] Розмір шрифту 600K. Має бути функцією доступності для людей із дуже поганим зором? ;-)
geert3

61
@ geert3 Я впевнений, що це веб-браузер на місячній орбіті
Девід Уілкінс

3
Демонстрація вашої версії в Chrome 41.0.2236.0 dev-m
Pier-Luc Gendreau

11
Я в канарі (41.0.2241.0 канарки) і все ще отримую відставання. Ви, хлопці, повинні спробувати його на ноутбуці замість ігрової установки, ви побачите це
markasoftware

3
Всупереч поширеній думці, IE насправді швидше, ніж Chrome для візуалізації більшості сторінок. Його двигун JavaScript трохи повільніше.
Фаланве

Відповіді:


62

Зміна, position: fixedздається, пришвидшує справи.


27
Це не пряма відповідь на його запитання, але це потенційне рішення його початкової проблеми (повільна відповідь у Chrome). Мислення поза коробкою слід заохочувати, ІМХО.
geert3

Тут, здається, працює чудово: gget.it/e0ubdh67/big-div-test_fixed.html . Ти знаєш чому ? :)
Basj

2
Я можу лише здогадуватися. fixedочевидно, менш складно викладати, і, можливо, вони можуть зробити більше оптимізацій. Але я не переглянув вихідний код двигуна візуалізації, якщо ви це маєте на увазі ;-)
geert3

1
Ця відповідь і одна, надана ViliusL, обидва мають однаковий коментар "залишити коментар" різних людей. Наскільки це круто?
Джо

2
@Joe - це набір стандартних відповідей, які надає StackOverflow для використання модераторами. Деякі потрібно помірніше помірно.
geert3

42

Використовуйте transformзамість top/left:

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

Демонстраційна демонстрація на jsFiddle .


2
Дуже дивне справа: в вашому jsFiddle, він швидко з Chrome дійсно. Я зробив саме ту модифікацію, яку ви пропонуєте в моєму оригінальному коді тут: gget.it/1owxq8kr/big-div-test_transform.html , і остання посилання є повільною на Chrome :( Як це можливо? Це виглядає так само, як і ваш jsFiddle ! [Примітка: дивом, відповіді geert3, здається, працюють, я не знаю, але це працює: gget.it/e0ubdh67/big-div-test_fixed.html]
Basj

@Basj Можливо, це залежить від версії, мій Chrome (39.0.2171.71 м) розміщує сторінку, пов’язану у вашому коментарі, так само гладко і швидко, як і FF. У будь-якому випадку, встановлення позиції для fixedвиведення елемента з потоку тексту та економить багато рендерінга. У документації transformMDN сказано: "... буде створений контекст укладання. У цьому випадку об'єкт буде виконувати роль блоку, що містить позицію: нерухомі елементи, які він містить."
Теему

2
Дивно, але у мене Chrome 39.0.2171.71 м ... і gget.it/1owxq8kr/big-div-test_transform.html каструлі повільні, такі ж повільні, як і в моїй оригінальній версії (у самому питанні). Ооо, можливо, це залежить від апаратного прискорення: у мене, мабуть, немає апаратного прискорення, тому що у мене ноутбук з поганою графічною чіп ...
Basj

1
@Basj додайте обгортку <div style="position:relative;min-height: 900px;">Your's divs</div>jsFiddle так
Альфонсо Рубалкава

1
@AlfonsoRubalcava Ой добре ... Це пояснює, чому jsfiddle гладка, а пряме посилання не є рівним (Chrome): gget.it/1owxq8kr/big-div-test_transform.html ! Дякую! Тож поліпшення продуктивності відбувається завдяки position:relativeймовірному, що схоже на відповідь
geert3

22
  1. Відповідь на перший квест "чому". Однією з проблем є розмір шрифту . у вас розмір шрифту 600000px, більшість веб-переглядачів вважає його занадто високим і робить меншим, а хром намагається надати оригінальний розмір. Схоже, що хром не може перефарбувати такі великі літери з потрібними стилями дуже швидко.

Але поєднання відповідей Teemu та geert3 - використання перетворення та позиції: фіксований, робить хром працювати набагато швидше навіть із великими шрифтами.

  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

6
Насправді це і є. ОП задає два запитання, на перше з яких відповідає: "чому FF, IE це правильно, а не Chrome?"
Ганс Рердінкхолдер

Цікаво. Чи є у вас якісь елементи, які показують, що Firefox зупиняється на 10 к і Chrome намагається надати оригінальний розмір? (Це було б цікаво для подальшого ознайомлення). Заздалегідь дякую @ViliusL!
Бась

1
@Basj додав максимальні розміри шрифту для кожного браузера (протестовано сьогодні), і це 2k для firefox.
ViliusL

Велике спасибі @ViliusL! Дійсно, ФФ обмежує font-sizeі це може бути причиною неповоротки на ФФ. Але тоді це повинно було бути дуже повільним і на IE, але це не ... Дивно!
Бась

4

Окрім відповіді Теему про використання перекладу:

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.


Я спробував додати те, що ви тут згадали: gget.it/0ufheqmt/big-div-test_prisonersolution.html , це ви мали на увазі? Тут все ще повільно перетягувати Chrome. Те ж саме для вас? (PS: Я не зрозумів: ви пропонуєте зробити ці CSS модифікації замість використання style.transformабо з використанням transform?). Дякуємо до речі за вашу відповідь @Prisoner!
Basj


1

Я проаналізував це і виявив, що оригінальна проблема пов'язана з архітектурою дисплея Chrome та його використанням фонових ниток для візуалізації сторінки.

Якщо ви хочете отримати швидку візуалізацію, перейдіть до chrome: прапорів, перейдіть до налаштування фарбування на базі Impl та встановіть "Disabled", після чого перезапустіть браузер - рух миші буде плавним.

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

Я б запропонував, щоб це було подано як помилку Chrome.


1

Використовуйте display: tableі table-layout:fixedна діві, або на таблиці, що загортає діл. В HTML:

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

Для того, щоб агент користувача форматував таблицю за один прохід, автори повинні сказати агенту користувача:

Кількість стовпців у таблиці. Будь ласка, зверніться до розділу щодо обчислення кількості стовпців у таблиці, щоб отримати детальну інформацію про те, як надати цю інформацію. Ширина цих стовпців. Будь ласка, ознайомтеся з розділом щодо обчислення ширини стовпців, щоб дізнатися, як надати цю інформацію.

Точніше, агент користувача може рендерувати таблицю в один прохід, коли задані ширини стовпців, використовуючи комбінацію елементів COLGROUP і COL. Якщо будь-який із стовпців вказаний у відносному чи процентному відношенні (див. Розділ щодо обчислення ширини стовпців), автори також повинні вказати ширину самої таблиці.

Для додаткового відображення браузеру потрібна кількість стовпців та їх ширина. Ширина таблиці за замовчуванням - це поточний розмір вікна (width = "100%"). Це можна змінити, встановивши атрибут ширини елемента TABLE. За замовчуванням всі стовпці мають однакову ширину, але ви можете вказати ширину стовпців з одним або декількома елементами COL перед початком даних таблиці.

Залишилося питання - кількість стовпців. Деякі люди пропонують почекати, поки не буде отримано перший рядок таблиці, але це може зайняти багато часу, якщо клітини мають багато вмісту. В цілому має більше сенсу, коли потрібен інкрементальний показ, щоб автори чітко вказали кількість стовпців в елементі TABLE.

Автори все ще потребують способу сказати користувачам агентам, чи використовувати інкрементальний дисплей або автоматично розміряти таблицю, щоб відповідати вмісту комірки. У режимі автоматичного розміру двох проходів кількість стовпців визначається першим проходом. У інкрементальному режимі кількість стовпців має бути вказана вперед (з елементами COL або COLGROUP).

і CSS:

17.5.2.1 Фіксований макет таблиці

При такому (швидкому) алгоритмі горизонтальне розташування таблиці не залежить від вмісту комірок; це залежить лише від ширини таблиці, ширини стовпців, меж або міжряддя.

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

Список літератури

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.