Comments 35
Пользователь наводит курсор на ссылку/кнопку — а она подсвечивается активной только через 0.1 сек. Пользователь щёлкает по кнопке — и всё замирает на полсекунды, после чего отрабатывается анимация нажатой кнопки. Пользователь набирает текст — а символы появляются не одновременно с нажатием клавиш, а с ощутимой задержкой.
А теперь плохие новости: если вы используете навороченные фреймворки, всякие там ангуляры с реактами, то избавиться от таких «тормозов» вам будет очень и очень сложно. Потому что для этого придётся нанимать не индусов с почасовым рейтом $2, кодящих путём копипасты со stackoverflow, а настоящих профи, которые встречаются довольно редко и стоят дорого.
Сильно (зачастую на порядки) экономить на разработке за счёт удобства пользователя — это современный тренд, который вряд ли удастся переломить в ближайшие лет 10.
изоморфный рендеринг
и прочее перекладывание рендеринга на клиента
взаимоисключающие параграфы
Я вообще считаю, что любой сайт должен быть доступен с отключёнными скриптами, пусть и не со всем функционалом.
Почему? Нет, я так тоже раньше считал, в основном по причине производительности, но я никогда не формулировал, что этого не должно быть никогда. Если это будет работать быстро — ок, никакой проблемы в этом не вижу. Клиент зачастую действительно простаивает.
> Клиент зачастую действительно простаивает.
Вот именно, что зачастую. Но зачастую — не означает всегда. Вот я, например, люблю открыть сразу 10-20 вкладок, а потом по очереди их читать.
Не забывайте, что у пользователя может быть очень слабый интернет (мобильный, WiFi в метро и т.д.). В случае статики клиент увидит страницу за один запрос. В случае скриптов это будет уже три запроса (получить HTML, получить файл с JS-скриптом, затем получить данные).
Не видел ни 1 сайта в котором все данные в одном html. Причем даже когда на ADSL сидел.
Вот именно, что зачастую. Но зачастую — не означает всегда. Вот я, например, люблю открыть сразу 10-20 вкладок, а потом по очереди их читать.
Сложных вычислений на клиенте быть не должно. А т.к. большинство вычислений будут при активном взаимодействии, то это не проблема. Надеюсь, вы не скроллируете сразу в 10-20 вкладках.
Я люблю статику, но только потому, что современный HTTP хорошо с ним работает: стандартизирован механизм кэширования, браузер совершает меньше запросов, ну и на сервере есть всякие механизмы кэширования динамических страниц. Но это не непреложная истина, веб не обязан быть таким, и если браузер научится кэшировать JS-based сайты я буду только за. Отключение JS для меня не отличается от отключения CSS — можно конечно, но зачем? Стили-то браузер тоже считает, время тратит. Любая работа — это вычисления. С этим придется смириться. У интерактивных JS-интерфейсов есть преимущество как раз в том, что НЕ совершается запросов на сервер. Если вы заходите на один раз почитать анекдот, и грузите ради этого все скрипты — это не особо эффективно. Но если вы сидите на нем ощутимое количество времени, то вместо полной перезагрузки страницы браузер бросается легковесными XHR, а то и по вебсокету мгновенно обменивается. И это дает намного более приятный UX. Не считая про вышеупомянутые техники «сменить состояние кнопки, дождаться ответа, в случае ошибки откатить его на предыдущее и выдать сообщение об ошибки». В 99% случаев с сервера придет подтверждение. Ровно то же самое, что branch prediction в CPU :) Никто ж не говорит, что он обманывает, просто спекулирует, и как правило оказывается прав. Полезная штука.
Либо можно взять фреймворк, написанный профи и даже у индусов с его помощью будет всё летать. Например… $mol, основной целью разработки которого было обеспечение максимальной отзывчивости по умолчанию.
Разница лишь в том, надо ли ему специально постараться, чтобы сделать медленно, или специально постараться, чтобы сделать быстро. В случае $mol, чтобы сделать медленно нужно приложить дополнительные усилия, что не свойственно качественному индусу.
Если вы про http://toys.hyoo.ru то аналогичная намеренно тривиальная реализация на любом другом фреймворке грузилась бы целую вечность.
А у вас тормозит сайт при любом перемещении скрола, даже вверх! Просто потому что вы делаете слишком много вычислений внутрях обработчика события scroll.
тормозить там будет только подгрузка новых картинок при достижении конца списка.
Это потенциальному индусу ещё нужно осилить "дорендеринг". Если же он в лучших традициях напишет аналогичный код:
toy_cards() {
return this.toys_sorted().map( toy => this.Toy_card( toy.id() ) )
}
То он сразу же отрендерит вообще все карточки, что может занять не один десяток секунд только лишь на открытие страницы. Да, дальше скроллинг будет шустрый, если на девайсе достаточно памяти, конечно.
А у вас тормозит сайт при любом перемещении скрола, даже вверх!
Типичный кейс использования каталога — последовательная промотка списка, а не теребоньканье скролла вверх-вниз. Сколько можно спекулировать на эту тему?
Великолепный перевод! А статья очень полезная и интересная. Сам для себя начал замечать то как именно скрыто время загрузки приложений и веб-страниц. Я отключил анимации на своём смартфоне и такой: "О ужас! Что с ним произошло? Почему он стал медленнее?" А потому что нет анимации, во время которой приложение прогружалось.
Нас все время обманывают, но обман во благо приятного пользования продукта — хороший обман
События, которые заканчиваются быстрее чем за 80 миллисекунд, проходят незамеченными для сознания
Киберспортсменам это скажите, особенно которые в файтингах соревнуются. Для них очень отличаются условные «меньше 50мс» и «больше 50мс» в различных latency. Или что, из каждого правила есть исключения? Все люди разные?..
События, которые заканчиваются быстрее чем за 80 миллисекунд, проходят незамеченными для сознания. Бьющий в бейсболе взмахивает битой по мячу прежде чем осознал, что питчер бросил его.
Есть разница для игрока, даже если она не осознаётся как прямая задержка
Для них очень отличаются условные «меньше 50мс» и «больше 50мс» в различных latency.Что отлично согласуется с тем, что написано в статье. Про двойную буфферизацию не забыли?
Или что, из каждого правила есть исключения? Все люди разные?..Да, разные. Где-то 10-15% физиологичесткие отличия в скорости реакции могут быть. Но, скажем, фальшстарт регистрируется если спортсмен реагирует быстрее, чем за 100мс…
В этой статье куча ошибок, касающихся тайминга, не уверен что автор копал достаточно глубоко. Вообще полное время реакции, от нового события до действия по визуальному тракту у лучших спортсменов не меньше 300ms. 60ms требуется глазу для ступенчатого трекинга движущегося объекта, если траектория уже предсказана.
А вы попробуйте сбейте тарелочку выстрелом от бедра (само движение кстати занимает лишь 50ms а первые 250ms ничего не происходит у лучших спортсменов). Потом рассказывайте мне про 150ms.
А в вашем примере про 150-250ms речь идет только о триггере для готовой энграммы (в котором я вам и 10ms сделаю в некотором проценте, если сигнал окрашен), а ни о каком «НОВОМ СОБЫТИИ». В этом примере достижимы скорости порядка 100ms для этого и был пример известного факта из психофизических опытов про 60ms для трекинга по предсказанной траектории.
Проблема всей этой псевдо-ускоряющей лжи в том, что рано или поздно она вскрывается. Причем когда пользователь ложь обнаружил, он уже не может развидеть ее назад. Хуже того, создание иллюзии быстрой работы само по себе требует ресурсов. В результате пользователь будет ненавидеть вас дважды — за то что вы, вместо того чтобы взять и оптимизировать свое приложение, обмазали его прокрутками, анимациями и прочими прогресс-барами, а во-вторых за то, что все эти перделки сделали приложение ЕЩЕ МЕДЛЕННЕЕ, чем если бы всего этого не было.
Кнопка «Сохранить» лишь переименовывала готовый временный файл.
Но появилась другая жалоба, «Я уже два раза нажал но ничего не происходит.»
После этого пришлось добавить секундное отображение часиков вместо курсора, после нажатия кнопки.
Секундная задержка символизирующая сохранение результатов труда пользователя всех устроила.
Кому в здравом уме придет в голову! ввести задержку! — представления не имею…
Не удивительно, что у нас всё тормозит…
Пользователь не осознал действие? Сообщение показать? Ну нафиг. Задержка!
Приложение крашится, потому что в декструкторе поток еще не завершился? Wait? Не, не слышал! Sleep(1000);
Приложение крашится при закрытии, потому что не всё корректно завершилось? Есть решение! Sleep(10000);
И кстати, эти претензии «Я уже два раза нажал но ничего не происходит.» в основном происходят в силу исторически сложившихся обстоятельств, стереотипов. Например, если пользователь работал в какой-то программе на древнем компе, и кнопка «сохранить» приводила к интенсивной нагрузке, скажем, на диск; а потом диск сменили на SSD, и вместо 10 секунд задержка стала 0,1с — конечно, это не будет соответствовать ожиданиям пользователя (даже если стало лучше). Однако, если пользователь изначально работал в таких условиях, то такое поведение сочтёт в порядке вещей.
1) Нажал на кнопку «Сохранить».
2) Начался процесс сохранения, кнопка поменяла статус (например, появилось колесико). Интерфейс, естественно, не заморожен.
3) Процесс закончился. Кнопка поменяла статус (например, появилась галочка)
Мне кажется, ленивое вычисление всего чего только можно — это лучший путь. К обратному лучше прибегать только в действительно критических секциях.
2) Начался процесс сохранения, кнопка поменяла статус (например, появилось колесико). Интерфейс, естественно, не заморожен.Если «интерфейс, естественно, не заморожен», то это значит что фоновое сохранение в программе уже есть — только теперь оно запускается по запросу… но… зачем? Почему бы его в этом случае не производить «в фоне»? Во многих современных IDE кнопки «сохранить» вообще нет — и проблемы нет, сохранение занимает доли секунды и случается автоматически, так зачем вам ещё и кнопка какая-то?
Иллюзия скорости