Javascript-форум (https://javascript.ru/forum/)
-   (X)HTML/CSS (https://javascript.ru/forum/xhtml-html-css/)
-   -   Подтормаживает вёрстка (https://javascript.ru/forum/xhtml-html-css/10564-podtormazhivaet-vjorstka.html)

DMH 09.07.2010 17:33

Подтормаживает вёрстка
 
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>

<style>
html,body {
	margin:0;
	padding:0;
	height:100%;
}
body {
	position:relative;
}
.page {
	min-height:100%;
}
#num {
	position:absolute;
	top:100px;
	left:200px;
	height:0;
	overflow:hidden;
	border:1px solid blue;
}
.xl {
	display:inline-block;
	vertical-align:top;
	width:200px;
	height:200px;
	border:1px solid red;
	/*float:left;*/
}
.header {
	padding-top:8px;
	display:table;
	width:100%;
	height:200px;
}


.leftside {
	width:170px;
	float:left;
}
.content {
	margin-left:178px;
}
</style>

<script>
function slide(el,i,j) {

	if (i!=j) {
		el.style.height=++j+'px';
		setTimeout(function() { slide(el,i,j) },0);
	}
}

</script>

</head>

<body>

<div class="page">

<div class="header">
<input type="button" value="Run" onclick="slide(document.getElementById('num'),180,0)">
</div>

<div class="leftside">texttexttexttexttext</div>

<div class="content">

<div id="num">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10</div>

<div class="xl">

</div><div class="xl">

</div><div class="xl">

</div><div class="xl">

</div><div class="xl">

</div><div class="xl">

</div><div class="xl">

</div><div class="xl">

</div><div class="xl">

</div>

</div>

</div>

</body>
</html>

Из-за такой вёрстки подтормаживает скрипт. Хорошо видно особенно в Chrome при обновлении и чуть похуже в Safari. Остальным браузерам нужно больше элементов, чтобы явно стали видны тормоза скрипта.
Скрипт, расширяющий элемент - показатель скорости. В хроме и сафаре данный код тормозит. Чтобы проверить без тормозов, нужно inline-block заменить на float-left, либо убрать min-height:100%. Каким образом inline-block влияет на скорость javascript и почему скрипт намного быстрее работает при float:left, пока загадка, но подозреваю, что виноваты в этом relative у body и min-height у page. При большом количестве элементов такая история начинается во всех браузерах, причём ошибка гуляет по всем стилям, бывает "margin:0" у тега <p> уберу и скрипты перестают тормозить, какова зависимость между этими событиями, тоже неизвестно. display:table у хедера остался, уже не стал проверять, влияет он на скорость или нет, как можно больше уменьшил весь код. Скрипт один единственный.

float 09.07.2010 23:42

Посмотрел у себя на хроме. Ничего не тормозит...
ЗЫ может лучше задержку поставить больше миллисекунд, а хеигхт увеличивать на большее кол-во пикселов?

float 09.07.2010 23:44

А не. скорость разная... Это вы имели ввиду под тормозами?

float 09.07.2010 23:46

Странно, как только открываю инструмент разработчика сразу ускоряется...

DMH 10.07.2010 06:07

Да, скорость разворачивания должна быть такая, как после открытия инструмента разработчика. Такая же скорость будет, если убрать к примеру min-height или inline-block заменить на float. Привёл в пример Chrome, так как в нём хорошо это видно, для остальных браузеров нужно наполнить блоки контентом и тогда при наполненном сайте начинаются уже конкретные тормоза. И убрать как бы ничего нельзя, всё нужно для макета и от этих тормозов скрипта нужно как-то избавиться, а точнее сначала найти причину, я думаю сами по себе отдельно inline-block или min-height не могут создать такую задержку скрипту.

DMH 10.07.2010 07:48

Проверил на основном коде, убрав body relative, ничего не изменилось. А вот после комментирования float:left, всё прекрасно заработало и в основном коде и в этом. Видимо выход из потока элемента и min-height родителя каким-то образом влияют на браузер.

subzey 10.07.2010 16:17

Очень странные реультаты.
По крайней мере, в опере используется приём с position: absolute: если элемент позиционирован абсолютно (или фиксированно), то ни он, ни его потомки, не влияют на внешний поток, поэтому можно делать только частичный reflow (перерисовывать только элемент и его содержимое), что очень сильно ускоряет отображение анимации.

В вебките, видимо, это не так.

DMH 10.07.2010 16:36

Пока левый сайдбар сделал с position:absolute, флоат у с него убрал. Chrome, Safari и FireFox на основном коде ожили, данный скрипт заработал в них с нормальной скоростью. Opera 9.64 еле заметно подтормаживает, а вот Opera 10.51 и Internet Explorer можно сказать ушли в транс (впрочем и до этого они там были), очень сильно тормозит в них скрипт. Занимаюсь поиском тормозящих стилей, пока натыкаюсь на те, на которые отражаются последствия ошибки, height, position и т.д., при их комментировании тормозить перестаёт, но ошибка изначально не в них. Есть подозрение на base64 и Оперу 10, но пока точно не ясно.

DMH 10.07.2010 16:55

.a_l {
	position:absolute;
	background:url(data:image/gif;base64,R0lGODlhAQABAIABAN/j5////yH5BAEKAAEALAAAAAABAAEAAAICRAEAOw==) repeat-y;
	top:96px;
	left:178px;
	bottom:51px;
	width:1px;
}
.a_r {
	position:absolute;
	background:url(data:image/gif;base64,R0lGODlhAQABAIABAN/j5////yH5BAEKAAEALAAAAAABAAEAAAICRAEAOw==) repeat-y;
	top:96px;
	right:0;
	bottom:51px;
	width:1px;
}
.a_b {
	position:absolute;
	background:url(data:image/gif;base64,R0lGODlhAQABAIABAN/j5////yH5BAEKAAEALAAAAAABAAEAAAICRAEAOw==) repeat-x;
	bottom:45px;
	left:184px;
	right:6px;
	height:1px;
}
.a_bl {
	position:absolute;
	background:url(data:image/gif;base64,R0lGODlhBgAGAOMNAN3h5d/j5t/j5+Xo6+rt7+zu8Ozv8e3v8fP19vT19vb3+Pz8/f3+/v///////////yH5BAEKAA8ALAAAAAAGAAYAAAQVELw5yaFvAUUbGsnUNEpQPGPDGEIEADs=) no-repeat;
	bottom:45px;
	left:178px;
	width:6px;
	height:6px;
}
.a_br {
	position:absolute;
	background:url(data:image/gif;base64,R0lGODlhBgAGAOMNAN3h5d/j5t/j5+Xo6+rt7+zu8Ozv8e3v8fP19vT19vb3+Pz8/f3+/v///////////yH5BAEKAA8ALAAAAAAGAAYAAAQU8EkJ5jtkKrBkGgjzFIHCMIJxnhEAOw==) no-repeat;
	bottom:45px;
	right:0;
	width:6px;
	height:6px;
}

Вот из-за этого фрагмента +вышеприведённый макет, скрипт в Opera начинает тормозить, и в девятой и в десятой.
Попробую уточнить из-за каких конкретно стилей.

DMH 10.07.2010 17:16

base64 отпадает.
Результаты:
Комментируем рисунки, background - скрипт продолжает тормозить.
Комментируем размеры, width, height - скрипт работает быстро.
Комментируем absolute - скрипт работает быстро.
Комментируем положение, top, left, bottom, right - скрипт работает быстро.

float 10.07.2010 18:05

А зачем вам inline-block?

float 10.07.2010 18:14

Да кстати:
vertival-align:top;
...

DMH 11.07.2010 05:49

inline-block нужен для заполнения блоками в цикле слева направо (хотя можно сделать и через float+хаки). vertival-align:top ошибся, печатаю в блокноте, заменил на vertiсal-align:top, вертикальный отступ пропал, всё как надо. Инлайн блоками пользуюсь, так как более предсказуема вёрстка, никаких overflow:hidden родительским элементам, clearfix и прочее в этом случае не нужно.

float 11.07.2010 12:12

(хотя можно сделать и через float+хаки)
Я переделал вёрстку блоками, и увеличил число xl до 15 где-то ничего не тормозило... Вообще!
Цитата:

так как более предсказуема вёрстка
Типичная отговорка начинающих верстальщиков...

float 11.07.2010 12:18

А вообще, по идее вёрстка может влиять на работу скрипта(по идее)
только в случае сложной дум структуры. CSS вообще как бы не в счёт...
Я пожалуй гляну пристальнее на ваш пример вечерком)

float 11.07.2010 13:23

Кароче.
Конфликт происходит вот из-за этого:
Цитата:

.xl {display: inline-block;...
.leftside {float:left;...
Я не знаком с алгоритмами webkid-a, но походу такой приём требует постоянных вычислений, при изменении стилей др элементов.
С этой штукой диспетчер задач в хроме показывает 90% загрузки моего CPU.
Если сделать нормальную вёрстку, загрузка не превышает и 20%...

DMH 11.07.2010 15:15

Правильная вёрстка та, в которой меньше всего хаков и прочей ерунды. float прежде всего обтекание и вырывание элемента из потока со всеми нехорошими последствиями, а мне этого не нужно. Для инлайнового отображения блочных элементов служит inline-block, при этом как я заметил выше, никаких схлопываний и прочих неожиданностей, устраняемых никому не нужными хаками, здесь не будет.
Уберите min-height и тормозить перестанет, уберите position:relative и тоже тормозить перестанет. С чего вы решили, что проблема в inline-block и float, а не в height или relative? Проблема до сих пор неясна, пока только предположения. И кстати, FireFox со своим движком тоже тормозит на этой вёрстке, просто при таком малом количестве данных это незаметно. Тут ошибка где-то на логическом уровне, которая перекидывается на остальные невиновные стили. Opera до сих пор тормозит, даже если убрать все inline-block и флоаты, так что вполне вероятно, что ошибка совсем не в них. Разберу Оперу, узнаю из-за чего там виснет и тогда будет побольше информации для размышления.

DMH 11.07.2010 15:42

Последняя информация (chrome) - inline-block и float убрал, скрипт всё равно подтормаживает, видимо с позиционированием что-то. Код ещё немного уменьшу и скину.

float 11.07.2010 16:26

О... я только заметил...
А не могли бы вы объяснить для чего на боди position: relative стоит?

float 11.07.2010 16:29

Цитата:

Правильная вёрстка та, в которой меньше всего хаков и прочей ерунды.
А я про хаки и ерунду не упоминал...
Для справки:
Дисплей табле и инлайн блок не используются, в силу того, что это решение не кроссбраузерно.
Если бы вы пришли к моему работодателю с такой вёрсткой он послал бы вас к бабушке...

float 11.07.2010 16:39

Да и ещё. Одинаковой работы скрипта в во всех браузерах вы всё равно не добъётесь.

DMH 11.07.2010 16:59

Рассскажите своему работодателю, что есть файлы с названиями ie6.css и ie7.css, которые позволяют достичь кроссбраузерности.
Кстати, inline-block в ie6 и ie7 по функциональности заменяется на display:inline; zoom1; Замена производится только в этих двух файлах, поэтому на остальные браузеры не влияет. В остальном свойство кроссбраузерно (про указание vertical-align:top и убирание пробелов между элементами наверое все знают).
Так, теперь насчёт кода. В Opera 10.51/9.64 скрипт тормозит только из-за стилей "a_l" (они закомментированы). Удаление position relative и прочее на Оперу особого влияния не произвело (скорость увеличилась на 0.1с), а вот Хром ведёт себя немного по другому. Удаление стилей "a_l" так же как и в Опере, сразу разгоняет скрипт (примерно на 1с), но также на ускорение влияет удаление position:relative либо min-height. Прикрутил заодно таймер, в миллисекундах, а то на глаз иногда неразличимо.
<!DOCTYPE HTML PUBLIC  "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<style>

html,body {
	margin:0;
	padding:0;
	height:100%;
}
body {
	background:aqua;
	position:relative;
}
.page {
	min-height:100%;
}

#num {
	position:absolute;
	top:100px;
	left:200px;
	height:0;
	overflow:hidden;
	border:1px solid blue;
}

/*

.a_l {
	position:absolute;
	background:red;
	top:96px;
	left:178px;
	bottom:51px;
	width:1px;
}
.a_r {
	position:absolute;
	background:red;
	top:96px;
	right:0;
	bottom:51px;
	width:1px;
}
.a_b {
	position:absolute;
	background:red;
	bottom:45px;
	left:184px;
	right:6px;
	height:1px;
}
.a_bl {
	position:absolute;
	background:red;
	bottom:45px;
	left:178px;
	width:6px;
	height:6px;
}
.a_br {
	position:absolute;
	background:red;
	bottom:45px;
	right:0;
	width:6px;
	height:6px;
}

*/

p {
	margin:0;
	padding:0;
}
</style>

<script>

xxx='';

function slide(el,i,j) {

	if (i!=j) {
		el.style.height=++j+'px';
		setTimeout(function() { slide(el,i,j) },0);
	}
	else end();
}
function begin() {
var date1=new Date();
xxx=date1.getTime();
slide(document.getElementById('num'),180,0)
}
function end() {
var date2=new Date();
alert(date2.getTime()-xxx);
}
</script>

</head>

<body>

<div class="page">

<input type="button" value="Run" onclick="begin()">

<div id="num">1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10</div>

<p class="a_l"></p><p class="a_r"></p><p class="a_b"></p>
<p class="a_bl"></p><p class="a_br"></p>

</div>

</body>
</html>

Если у "a_b" увеличить height до 2-х пикселей, то в Опере скрипт разгонится примерно на 50%, но неполностью, тоже странный факт.

float 11.07.2010 17:10

Ну если такой вариант вам кажется проще, прозрачнее и понятнее - флаг вам в руки...

DMH 11.07.2010 17:43

Появилась идея, что несоответствие идёт в (height, width) и (top, left, bottom, right), а точнее в их совместном использовании. Но проверку уже на завтра перенесу.
inline-block и float, как сами могли убедиться, могут иметь прямое отношение к торможению скрипта, а могут и косвеное, из-за торможения совсем других свойств, оказывающих на них влияние, причина пока неясна. Цель данной темы найти истинного виновника, а не просто заменить inline-block на флоаты и радоваться дальше. В будущем рано или поздно опять эта проблема всплывёт, хоть с флоатами, хоть с инлайн-блоками.

DMH 12.07.2010 08:34

Виновник всех бед в Opera 9 и Firefox найден - height:100% у html, body и page. В Chrome - тот же самый height. Остальные версии браузеров пока исследуются.
А с высотой, заданной в процентах, видимо при её вычислении, происходит нечто странное внутри движка браузеров, что приводит к подтормаживанию скриптов. Особенно, если контент уезжает вниз за границы экрана.
редактирование:
Вобщем убрал отовсюду height:100% и скрипты снова заработали с нормальной скоростью, даже в Опере 10. Есть конечно отклонения в 0.1-0.2 секунды при пустом и заполненном макете, но это мелочи по сравнению с предыдущими задержками в 3 раза. Теперь и inline-block и флоаты и position:relative уживаются вместе и при этом не притормаживают скрипты. Высота тормозила именно при процентном указании, при тех же 100px всё работало нормально. Проблема теперь другого плана, чем заменить все height:100%. Раз при пиксельном указании всё гладко, решил пока временно переделать задание высоты с помощью javascript.
Судя по скорости работы данного скрипта на пустой странице, Chrome на первом месте, далее, проигрывая с задержкой в два раза, идут Firefox и Opera, позади всех с задержкой в 3 раза идёт Internet Explorer. Что в Хроме происходит за 2 секунды, то в IE за 6, видимо для плавного кроссбраузерного разворачивания элементов нужно учитывать ещё и коэффициент тормознутости браузеров. Хотя может ну его, это разворачивание.
редактирование:
пришлось пожертвовать плавностью, привязать вызов функции ко времени (задержка 10мс, чтобы браузеры догнали друг друга) и соответственно увеличить прибавление высоты на +3px. Более-менее выровнялось, Хром правда чуть быстрее (на 0.3с), плавность на глаз нормальная. При дальнейшем увеличении параметров, браузеры полностью выравниваются, но начинается дёрганье при разворачивании/сворачивании. Пока золотой серединой будет 10мс и 3px, дальше после тестов может изменю.

рони 14.07.2010 00:24

если так важно время выполнения скрипта установи его сам )))
var rg = /(height.*?)(\d+)/i;

function slide(b, d, c, f) {
    var a = b.style.cssText;
    rg.test(a) || (a += "; height: " + c + "px;");
    var g = (new Date).getTime();
    setTimeout(function () {
        var e = ((new Date).getTime() - g) / f;
        a = a.replace(rg, "$1" + Math.floor((d - c) * e + c));
        b.style.cssText = a;
        if (e < 1) setTimeout(arguments.callee, 10);
        else {
            a = a.replace(rg, "$1" + d);
            b.style.cssText = a
        }
    }, 10)
};

b - элемент
d - конечный параметр высоты элемента
с - начальный параметр высоты элемента
f - время выполнения скрипта
для примера от 0 до 180px за 1 секунду
onclick="slide(document.getElementById('num'),180, 0,1000)"

subzey 14.07.2010 01:36

Я так понял, проблема в том, что абсолюты уезжают за край порта просмотра, появляются скроллбары, отжирают место у порта просмотра и заставляют рефловить всю страницу.
В таком случае достаточно поставить overflow:hidden для, скажем, body (или блока-обвертки), и этого происходить не будет.

DMH 14.07.2010 08:20

Это насчёт Оперы? Пока не проверял. На Хром overflow:hidden не принёс ожидаемых результатов и с полосами прокрутки и без оных.
По Хрому: тормоза появляются при height:100% у html, body, дива-обёртки (+ relative у обёртки в качестве нагрузки, всё остальное, включая inline-block элементы, убрано) и position:absolute у разворачиваемого элемента. Полос прокрутки нет. Если разворачиваемый элемент переместить в static, то тормоза исчезнут.

Решение - либо убирание height:100% и задания любой определённой высоты в пикселях (не процентах), либо перенос разворачиваемого элемента в static. Может тут где-то проблема?

DMH 14.07.2010 08:50

Цитата:

Сообщение от subzey (Сообщение 63613)
Я так понял, проблема в том, что абсолюты уезжают за край порта просмотра, появляются скроллбары, отжирают место у порта просмотра и заставляют рефловить всю страницу.
В таком случае достаточно поставить overflow:hidden для, скажем, body (или блока-обвертки), и этого происходить не будет.

Да, это вторая проблема, тормозившая Internet Explorer на 0.2-0.3с, нижние и боковые абсолютные бордеры выходили за пределы экрана и начиналось притормаживание, а там где не выходили, работало чуть быстрее. После убирания height:100%, скорость увеличилась в 3 раза, после применения overflow:hidden скорость увеличилась на 0.2-0.3с. Такими темпами скрипты скоро летать будут :)

Вторая причина впринципе объяснена вами, осталась теперь первая, про height:100%.

И статей то не встречал в интернете, как правильно верстать, чтобы не тормозили скрипты, непопулярная тема что ли.

p.s. overflow:hidden для обёртки, если для body, тогда полос прокрутки не будет. Я по правде говоря так до конца и не понял каким образом overflow:hidden повлиял на IE, полосы прокрутки естественно так и остались, но работать он стал заметно быстрее. На все остальные браузеры overflow:hidden для body и для обёртки с убиранием полос прокрутки не повлиял никак (Опера 10.51 повисла, но в этой опере баг), в остальных и не хуже и не лучше.

рони 14.07.2010 10:19

Цитата:

Сообщение от DMH
И статей то не встречал в интернете, как правильно верстать, чтобы не тормозили скрипты, непопулярная тема что ли

не скрипт тормозит а прорисовка и перерасчёт документа -- дай время браузерам на прорисовку setTimeout(function() { slide(el,i,j) },0);
а по теме посмотри http://webo.in/articles/all/2009/31-...flow-relayout/
http://webo.in/articles/all/2009/28-efficient-css/

subzey 14.07.2010 10:57

Кстати говоря, а правда, зачем нужна задержка меньше 35 миллисекунд?

Если у пользователя шустрый браузер, он увидит в среднем 28 FPS, что выше 24, необходимых для иллюзии плавного движения.

Если не сильно шустрый, чуток подёргается, но не будет дьявольски тормозить.

DMH 14.07.2010 12:40

Вложений: 3
Оно так и работает, моё сообщение выше -
Цитата:

Сообщение от DMH (Сообщение 63264)
...привязать вызов функции ко времени (задержка 10мс, чтобы браузеры догнали друг друга) и соответственно увеличить прибавление высоты на +3px. Более-менее выровнялось, Хром правда чуть быстрее (на 0.3с), плавность на глаз нормальная. При дальнейшем увеличении параметров, браузеры полностью выравниваются

Мне интересна причина этого явления. По ссылкам рони скачал Speed Tracer для хрома. На первом рисунке работа скрипта без height:100%, на втором разворачиваемый элемент static, а на третем с height:100%. На первых двух рисунках разница параметров мала, а на третем заметно увеличился Paint (The browser's rendering engine updated the screen). По каким-то причинам возросло время отрисовки.

DMH 15.07.2010 06:53

Причина возросшего времени отрисовки найдена. При height:100% и position:relative у обёртки, при раздвижении элемента перерисовывается вся страница, т.е. "1024 x высота_контента". Если эти свойства стилей убрать, то перерисовывается сам раздвигаемый элемент - "17 x кол-во_пикселей". Отсюда и такая задержка.

position:relative нужен для абсолютных бордеров, так как в этом случае смещение абсолютного бордера отсчитывается от обёртки (position:relative), а не от самого экрана, что позволяет прижать бордеры к контенту при прокрутке страницы. Остаётся вариант с избавлением от height:100% и указания величины в пикселях, тут видимо только javascript. Есть вариант третий, оставить всё как есть, скрипты раздвижения и так ко времени привязаны, тормозить не будут, а вот например замена рисунка при onmouseover и остальное в таком роде, видно как тормозит. Если есть предложения, пишите, пока остановлюсь на варианте с заданием высоты с помощью javascript.


Часовой пояс GMT +3, время: 15:36.