Pull to refresh

Comments 17

CSS и ничего больше

 


document.getElementsByTagName('head')[0].appendChild(style);

Это что-то вроде ничего_больше.js?

JavaScript был использован только для инициализации часов, создания начальных стилей. Сами часы идут только на основе CSS анимации.
Но если вас интересует только CSS+HTML часы — можно перенести создание CSS анимации на серверную часть, к примеру можно сгенерировать те же стили при помощи PHP, тогда на стороне клиента все будет работать даже если отключены скрипты.
Я кстати об этом упоминал в статье:
И так у нас два варианта, либо на стороне сервера рендерить CSS относительно времени запроса, либо использовать JavaScript. Конечно сервер рендеринг и без скриптовые часы это круто, но ради подтверждения концепта мы все же используем JavaScript.

Простите, что не уточнил сразу в статье.

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

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

На счет нагрузок уже отписывал, но все же
Я не знаю как себя поведет CSS при нагрузках процессора, я поэксперементирую с этим и сообщу вам результат. Но, хорошо сделанная страница не должна нагружать поток на столько, чтобы часы сильно отставали (больше 5 секунд разницы в час), а такими малыми отклонениями можно пренебречь.
Также, ради эксперимента оставлял вкладку с часами открытой, пока было запущено пару тяжелых процессов и еще 20 вкладок и часы за 2 часа так и не отстали.
В случае сна и гибернации — ничего не гарантирую. Но можно переопределять CSS классы при возвращении пользователя на страницу, много проблем это не вызовет.

Сама статья — это все лишь концепт, а не готовое решение.

средний fps 50 кадров

Если часы обновляются раз в секунду, откуда вообще может взяться 50 кадров в секунду?
Чтобы измерить быстроту отрисовки, нужно поставить постоянную перерисовку часов, например вот так:


// в setTimeVariables
setCustomProperty('seconds', time.getSeconds() + time.getMilliseconds() / 1000);

const start = () => {
    setTime()
    requestAnimationFrame(start)
}

start()

Тогда можно увидеть стабильные 60фпс (или сколько частота обновления на мониторе)
Также, если поставить стрелкам will-change: transform, то они не будет репайнта на каждый кадр.
Так что css-переменные тут вообще не причем.

Поддерживаю. В статье изложены неверные выводы. Переменные вообще никак к отрисовке не относятся и сами по себе ее не вызывают. Просто в одном варианте часов отдельный слой создается при каждом сдвиге стрелки, а во втором варианте слой существует постоянно.
Для плавности же можно просто добавить тех же стилей вроде `transition: 1s linear;`. В итоге код в статье сильно усложнился / запутался, а прибавилось только минусов. %)
Не совсем, не забывайте, что вы вызываете функцию каждую секунду, и если вам это кажется мелочью — придставте если их будет 10, а может и больше. И да, сами CSS переменные — прекрасный инструмент и никаких нагрузок не вызывают, но может все же не стоит переносить на CSS переменные и JS то, с чем сам по себе справляются CSS?

Также, как человек, который всегда на проектах имеет дело с IE 11 и старше, для меня очень важна поддержка старых браузеров и высокая производительность, чего собственно я и добивался в этой статье.
Ваше утверждение немного неверно. 60fps — этакий стандарт для браузера. Соответственно, 60 вызовов функции перерисовки внутри браузера. Но суть не в этом. Я пока отброшу второй абзац вашего ответа, так как, если основываться на нем, то переменных (пользовательских свойств) CSS вообще быть не может, так как нет поддержки. В оригинальной статье автор обновлял DOM не только с целью проброски CSS переменных, но и с целью обновления данных для доступности, чего у вас уже нет. Для глаз это погоды не делает, а вот для слуха очень даже (по сему поводу чистая теория, так как нет желания проверить). Идем дальше. Ваш код создает отдельный слой и крутит его. И этот слой висит постоянно из-за анимации и не объединяется с другими слоями (http://prntscr.com/ir5mc8), посему вы не видите перерисовки. Такая «магия» дается не бесплатно, на нее выделяется память, что, как бы, тоже ресурс системы. Выше вам уже писали про «волшебное» свойство `will-change`, которое может сделать тоже самое для решения из оригинальной статьи. Добавьте `transition` и увидите теже 60FPS (появится постоянная перерисовка). Ну а если учесть
Так как часы отсчитывают время CSS-ом, то если забить тред какими-то тяжёлыми заданиями — часы перестанут идти и когда страница освободится — будут отставать. Но все это можно поправить заново задав keyframe.
то получается, что нам нужно точно так же пробрасывать в DOM кучу стилей не реже, чем раз в секунду. Так в чем профит-то? IE11?

И про загадочные 50.2FPS все тоже просто и понятно. Если открыть счетчик FPS на оригинальных часах, то там будет 1FPS (логично же, 1 перерисовка всего, но, на самом-то деле, это тоже может варьироваться, так как процессор можно нагрузить так, что будет 0FPS). На вашем же скрине видно, что включена настройка отображения перерисовок (зеленый прямоугольник), которая сама по себе вызывает перерисовку, так как этот самый зеленый прямоугольник появляется / исчезает плавно. Вот и FPS проседает (а проседает ли? :)).
Соглашусь с вами. Коментарий ivan386 натолкнул меня на размышления, и я был совсем даже не прав в этой статье. И даже подумываю разгромить себя же в следующей. Скажу вам так — вы очень много где правы, но пользуясь только Chrome вы понемногу начинаете презирать другие браузеры. Chrome лучший не во всем, хотя и я сам в основном им пользуюсь.

Вы очень не правы тут:
Соответственно, 60 вызовов функции перерисовки внутри браузера.

И даже тут:
Так в чем профит-то? IE11?
Каждый браузер важен на столько, на сколько им пользуются именно ваши посетители ресурса.

И я был не прав тут:
Так как часы отсчитывают время CSS-ом, то если забить тред какими-то тяжёлыми заданиями — часы перестанут идти и когда страница освободится — будут отставать.
Хотя зависит от реализации keyframe в браузере. Но многим такие вещи не по чем.

Скажу вам больше, мы все очень много не знаем про браузеры. Лично меня комментарии к этой статье заставили усомниться в своем понимании роботы браузеров, и даже в том что нам про них (не)говорят разработчики.
Мои доводы касались тех проблем, решение которых описывалось в статье. Речь шла о производительности, а не о поддержке IE. Если бы все описывалось в контексте обратной совместимости, то мне это было бы неинтересно, так как, благо, под IE уже давно не пишу.

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

60 вызовов — это к тому, что штуки вроде `requestAnimationFrame`, CSS animation / transisition.., как раз и ограничиваются этими 60-ю кадрами, то бишь 60-ю перерисовками. Если transform отправляет что-то на GPU, а инструменты разработчика Chrome'а не показывают перерисовки, то это вовсе не означает, что ничего не происходит. Картинка-то на экране меняется. Вот как раз с потолком в 60FPS и меняется. А Paint flashing (зеленый прямоугольник) этого и не покажет.
Здравствуйте, рекомендуймый FPS для страницы, не зависимо от контента — 60. И к сожалению, так с ходу, я не могу вам сказать почему в данном случае он 50, но факт остается факто — мы пишем в DOM с помощью JS каждую секунду и это нагружает главный поток. Кроме того наше переопределение CSS переменных вызывает перерасчет некоторых CSS аттрибутов, что нагружает главный поток опять.
Интереса ради я просто попробовал изменять CSS переменные каждую секунду в пустой странице, и даже так у меня появлялись странный просадки FPS, хотя не так частые. Я не утверждаю что не стоит вообще не использовать CSS переменные, просто возможно не стоит только ради часов нагружать главный поток.

На счет вашей функции сверху — она покажет FPS на основе только одного кадра, что не говорит ни о чем. Чтобы узнать точное FPS нужно считать среднее значение хотя бы 100 кадров. А так, это как говорить, что все люди выше 2 метров на основании роста Шакила О'Нила. Потому, простите, по Хром тут точно лучше обчистил FPS.
Да, это вполне очевидное решение, тоже вначале подумал об этом.
Но, смутило как-раз то, о чём вы упомянули. Лаги могут появиться не только от загруженности страницы, но и от загрузки проца.
И ещё мне не понравилось то, что атрибут datetime не будет меняться. Т.е. не факт, конечно, что это нужно. Но могут быть случаи, когда текстовая составляющая также важна, как и визуальная. Я имею в виду скринридеры.
Если это не столь важно, то, конечно, такой способ приоритетней.
Спасибо.
Я очень сомневаюсь что хоть одна читалка будет рада ежесекундному изменению времени. Я работал пару раз с читалками и для них достаточно важно не изменять контент без надобности. Да и представте себе — читалка еще не успела прочитать время, а вы уже его поменяли 5 раз.
Я бы сказал, что для читалок лучше спрятать такой элемент (aria-hidden=«true») и создать скрытый элемент где мы меняем время раз в минуту.

На счет нагрузок — да. Я не знаю как себя поведет CSS при нагрузках процессора, я поэксперементирую с этим и сообщу вам результат. Но, хорошо сделанная страница не должна нагружать поток на столько, чтобы часы сильно отставали (больше 5 секунд разницы в час), а такими малыми отклонениями можно пренебречь.
Также, ради эксперимента оставлял вкладку с часами открытой, пока было запущено пару тяжелых процессов и еще 20 вкладок и часы за 2 часа так и не отстали.
В случае сна и гибернации — ничего не гарантирую. Но можно переопределять CSS классы при возвращении пользователя на страницу, много проблем это не вызовет.

Сама статья — это все лишь концепт, а не готовое решение.
Очень интересная статья, спасибо автору. Была подобная идея, но до реализации руки не дошли.

Очень странно что не смотря на то что картинка очевидно меняется хром и firefox не подсвечивают перерисованную область. Но график fps в хроме при этом активно двигается показывая постоянную перерисовку.


В недавней статье "Этот SVG всегда показывает сегодняшнюю дату" в комментариях разместили часы в SVG. Они работают как секундомер на странице.


Анимация в SVG работает даже если вставить его в тег IMG. Но тогда начинает перерисовываться полностью всё изображение. И этот секундомер не хило нагружает процессор.


Я поэкспериментировал и сделал свой SVG секундомер в котором анимация включается каждую секунду на 0.001 секунды.
image


Думаю fps при этом маленький не потому что нагрузка большая а потому что рисовать нечего. Каждую секунду рисуется новый пик и график останавливается до следующего шага(если не включена подсветка прорисованной области).


Если включить подсветку прорисованной области то можно увидеть что картинка обновляется раз в секунду.

Sign up to leave a comment.

Articles