Активные пользователи Телеграма, особенно те, кто подписан на Павла Дурова, наверняка что-то слышали о том, что Телеграм проводил в этих ваших интернетах конкурс для iOS, Android и JavaScript разработчиков, а также для дизайнеров. Несмотря на то, что это было довольно эпичное событие с раздачей солидных призов (один из участников получил 50к долларов за первое место, написав самое быстрое и лёгкое приложение для Android), о нём как-то слабо писали, во всяком случае в Рунете. Своим дебютным постом попробую исправить ситуацию.


Коль скоро я являюсь фуллстек JavaScript-разработчиком (если совсем точно, то TypeScript-разработчиком), я решил испытать себя. Манил не только призовой фонд, но и сам формат: это не соревнования по программированию, где важны абстрактность и скорость мышления. Здесь было важно всё в комплексе: опыт, скорость разработки в среднесрочной перспективе, вкус в вопросах UI, знание computer science в целом, самокритичность. По условиям конкурса необходимо было разработать библиотеку для отображения графиков для одной из платформ: iOS, Android или Web.


Разработчики для разных платформ не конкурировали между собой, и у каждой платформы победители были свои. Основными критериями были: скорость работы (в том числе и на старых устройствах), соответствие дизайну, плавность анимации и минимальный размер приложения. Уже существующие решения и библиотеки использовать было нельзя, всё должно было быть написано с нуля.

До этого я участвовал в конкурсах для разработчиков, где на все задачи выделялось не более 5 часов, эти часы приходилось проводить в огромном напряжении. Несмотря на то, что выполнение задачи в конкурсе от Телеграма не требовало такого напряжения, это один из самых сложных конкурсов, в которых мне приходилось участвовать. С виду несложная задача оказалась настолько ёмкой, что если бы мне за это платили, я бы мог пилить эти «графики» месяцами, пытаясь найти компромисс между производительностью кода и архитектурной его стройностью. Выручало то, что на решение выделялось три (upd: две, спасибо vlad2711 за поправку) недели. Некоторые из соперников специально брали отпуск, чтобы уделить конкурсу больше времени, а я решил совмещать разработку для конкурса по вечерам и выходным с работой в "Онланте" в обычном режиме.

CANVAS versus SVG


Самый главный архитектурный вопрос, вставший перед всеми нами, был в выборе инструмента отрисовки графики. На текущий момент веб-стандарты предлагают нам два подхода: через генерацию «на лету» svg-графики и старый добрый canvas. Вот плюсы и минусы каждого из них.

Canvas


+ Абсолютная универсальность — имея возможность изменить цвет любого пикселя на полотне, можно нарисовать всё, что угодно.
+ [Потенциально] Высокая производительность — если уметь готовить canvas, он может показывать неплохую производительность. Было бы замечательно использовать webgl, но его поддержка на смартфонах оставляет желать лучшего.

- Все расчёты и вся отрисовка вручную — в отличие от SVG, где промежуточные точки ломаной можно задать единожды, а далее можно манипулировать viewbox-ом для перемещения «камеры» по участкам ломаной, с canvas всё сложнее: никаких «камер» тут нет, есть только координаты от левого верхнего угла; если нужно «переместить» текущую область просмотра графика, необходимо заново рассчитать все координаты всех его точек относительно новой позиции области просмотра. Другими словами viewbox, который в svg есть из коробки, в canvas нужно реализовывать вручную.
- Вся анимация вручную — исходя из предыдущего пункта, все возможные анимации реализуются посредством пересчёта координат, значений цвета и прозрачности и перерисовке всей сцены N-е количество раз в секунду, и чем большее количество раз удалось пересчитать и перерисовать сцену, тем плавнее анимация.

SVG


+ Простая отрисовка — достаточно один раз добавить в SVG необходимые линии, фигуры и далее можно, манипулируя viewport, параметрами цвета и прозрачности, обеспечить навигацию по графикам.
+ Простая реализация анимаций — опять же, исходя из предыдущего пункта, достаточно N-e количество раз в секунду указать новые значения для viewbox, цвета и прозрачности, а изображение перерисуется само, об этом позаботится браузер. Кроме того, не стоит забывать, что фигуры и примитивы в SVG можно стилизовать в CSS, поэтому их можно анимировать с помощью CSS3-анимаций, что открывает широчайшие возможности для получения крутых анимаций с минимальными усилиями.
+ Неплохая производительность по умолчанию — если с canvas можно легко, что называется «в лоб», накодить что-то медленное и жрущее сотни ресурсов, то результат, основанный на SVG всегда будет выглядеть вполне легковесным, приличным и плавным. 

Но есть и обратная сторона медали.

- Скромные возможности для оптимизации — поскольку svg рисуем не мы, а браузер, то и контролировать этот процесс невозможно — если хочется увеличить производительность, например, за счёт кэширования уже отдельных отрисованных элементов, сделать это нельзя никак. Скорее всего это уже делает браузер, но мы не можем быть уверены до конца.
- Ограниченность инструментария — в SVG мы уже не контролируем каждый пиксель полотна, а думаем и кодим в рамках векторных примитивов. Впрочем, для этой задачи это несущественный минус, накладывающий некоторые, опять же несущественные ограничения в контексте задачи конкурса.

Выбором инструмента мучиться мне не приходилось никогда, поскольку у меня есть отвратительная черта характера — я максималист и привык использовать в работе только любимый инструмент. Так получилось, что еще со студенческих времён, когда я забавлялся с DirectDraw, любимым моим инструментом всегда было полотно, на котором «делай что хочешь». И canvas для решения конкурсной задачи действительно оказался хорош, но по-настоящему сыграл мне на руку лишь один его плюс: широчайшие возможности для оптимизаций, поскольку основным критерием была всё-таки производительность приложения.

Хороший код нехороший


Задача ясна: нужно рисовать точки на полотне в нужном месте и в нужное время. Осталось написать код. Снова нужно было выбирать, на этот раз между написанием производительного компактного кода одной «портянкой» в процедурном стиле или не очень производительного и уж тем более некомпактного в моём любимом объектно-ориентированном. Наверное, вы уже догадались, что я выбрал второй вариант, приправив его ещё одним моим любимцем — TypeScript.

И этот выбор оказался не очень правильным. Из-за использования абстракций и инкапсулирования не везде получается сохранять, передавать и повторно использовать промежуточные результаты вычислений, что плохо сказывается на производительности. А из-за повсеместного использования this, без которого ООП в JS невозможен, код плохо минифицируется, тогда как размер тоже имел значение.

Настало время дать ссылку на гитхаб: github.com/native-elements/telechart. Если интересно, рекомендую обратить внимание на историю коммитов, она хранит память об оптимизационных мытарствах и небезуспешных попытках выжать пару лишних кадров отрисовки в секунду.

Ну а в конкурсе я не занял призового места. И проблема, как это часто с нами-программистами бывает, оказалась не в недостаточном опыте, сообразительности или скорости, а в недостаточной самокритичности: сам факт того, что у меня получилось сделать, оно работает и выглядит как на картинке, меня порадовал, а по поводу тормозов отрисовки я думал, что я сделал всё, что мог, у остальных наверняка так же. Стыдно об этом говорить, но я был уверен, что займу первое-второе место. На деле же оказалось, что я написал тормозную и глючную программу, не самую плохую, но и далеко не самую хорошую. Когда я увидел работы других разработчиков, понял что у меня нет шансов и оставалось только кусать локти. Будь я беспристрастен к своему труду, я бы занялся производительностью, самой важной частью конкурсного задания.

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

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


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


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

Дёрганая анимация

Даже если вам хватает мощностей, чтобы выдавать 60 кадров в секунду, анимация не будет плавной, если положение элемента или его прозрачность не детерминированы временем, прошедшим с начала анимации. Это обусловлено неравными промежутками времени между тиками: например, один тик сработал через 10 мс, а второй — через 40, в то время как и за первый, и за второй тики объект переместился влево на 1 пиксель — то есть скорость его перемещения постоянно плавает, визуально это выглядит как «подёргивание». Иными словами, нужно делать не так:

let left = 10, interval = setInterval(() => {
  left += 1	
  if (left >= 90) {	
    clearInterval(interval)
  }
}, 10)

А так:

let left = 10, startLeft = 10, targetLeft = 90, startTime = Date.now(), duration = 1000, interval = setInterval(() => {
  left = startLeft + (targetLeft - startLeft) * (Date.now() - startTime) / duration	
  if (left >= targetLeft) {	
    left = targetLeft
    clearInterval(interval)
  }
})

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

let left = Telemation.create(10, 90, 1000)
…
drawVerticalLine(left.value) // В любое время здесь будет нужное, детерминированное значение.

Дальше в игру вступает правило 60 fps. ПК-геймеры меня поймут: чтобы анимация выглядела идеально, она должна отрисовываться со скоростью не менее 60 fps. Соответственно, каждая отрисовка кадра должна занимать не более 1/60 секунды. Для этого нужно мощное железо и хороший код.

Дальнейшие изыскания показали, что

Прорисовка canvas тормозит, если над canvas есть html-элементы.

Изначально я использовал «пустые» html-элементы для того, чтобы реализовать управление текущей областью просмотра:


Эти элементы располагались поверх canvas, и несмотря на то, что у них не было никакого контента, они использовались только для отслеживания событий мыши, в результате экспериментов выяснилось, что само их наличие снижает производительность отрисовки. Убрав их и немного усложнив логику определения событий управления областью просмотра, я увеличил скорость отрисовки кадра.

Оставалось выдернуть последний гвоздь из крышки гроба производительности: я сделал

Кэширование миникарты

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

Дальше что?


Было ещё много успешных и не очень драк за производительность: попытки кэшировать результаты вычислений координат, эксперименты с параметрами lineJoin у CanvasRenderingContext2D (miter быстрее), но они не так интересны, так как не давали заметного выигрыша в производительности либо не давали его вообще.

Из восьми дней пять я потратил на ускорение кода и только три — на допиливание новой функциональности. Да, мне хватило всего три дня, чтобы добавить новые типы графиков, и тут весьма кстати оказался ООП, с ним кодовая база увеличилась незначительно. Мне не хватило времени, чтобы выполнить бонусное задание (ещё +5 дополнительных графиков). Полагаю, что те пять дней, которые я потратил на устранение последствий моей уверенности в себе, я мог потратить на решение бонусной задачи.

Тем не менее мои труды дали результат: 4-е место и «утешительный» приз в одну тысячу долларов:


Кстати, конкурс продолжился дальше, но уже без меня.

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

Кроме того, эту библиотеку я использовал в разработке нашего корпоративного таймтрекера, о котором тоже планирую рассказать на Хабре в ближайшее время.

Для обсуждения предлагаю такой вопрос: зачем Телеграму это всё нужно? Я считаю, что за адекватные деньги Телеграм получит самую лучшую в мире библиотеку для отображения графиков: лучший результат из сотен попыток сделать лучше, чем у других. Соревновательный принцип позволяет получить настолько высокий уровень качества, который на заказ не способен сделать никто и ни за какие деньги.

И немного ссылок:


Комментарии (46)


  1. psFitz
    06.08.2019 12:59
    +1

    Эти элементы располагались поверх canvas, и несмотря на то, что у них не было никакого контента, они использовались только для отслеживания событий мыши, в результате экспериментов выяснилось, что само их наличие снижает производительность отрисовки. Убрав их и немного усложнив логику определения событий управления областью просмотра, я увеличил скорость отрисовки кадра.

    Странно, у победителя конкурса ползунки — это html над canvas)


    1. ShibaOn Автор
      06.08.2019 14:31
      +2

      Описаная проблема возникает из-за того, что перерисовка канваса вызывает необходимость перерисовать и html-элементы, находящиеся над ним, вместе со сглаживанием и полупрозрачностью. Когда нужно перерисовать canvas 60 раз в секунду (например, при перемещении ползунков), издержки, связанные с перерисовкой html-элементов над canvas становятся заметными.

      У автора jschart.usercontent.dev/entry81 отдельный канвас для миникарты и он не перерисовывается при перемещении ползунков, потому что сами ползунки сделаны на css. Соответственно, и проблема не актуальна. В целом, такой подход и производительнее и проще в реализации — нужно стараться отрисовывать canvas как можно реже, по-возможности перекладывая рендеринг на html-движок.


      1. psFitz
        06.08.2019 15:02
        +1

        Спасибо за подробный и полезный ответ)


  1. riv2
    06.08.2019 14:13
    +2

    Спасибо — есть моменты которые подчеркнул для себя.


  1. iago
    06.08.2019 16:15
    +2

    Поздно я узнал об этом конкурсе. Автор, вы молодец, и слог очень понравился как пишете, все понятно и по полочкам. Единственное, не понял к чему в конце список каких-то вакансий, в свободное от хакатонов время HR-ом подрабатываете?


    1. ShibaOn Автор
      06.08.2019 16:29
      +1

      Спасибо за отзыв :-) Заметка опубликована в блоге компании ГК ЛАНИТ, где я имею счастье работать ка краб на галерах уже джва года, поэтому коллеги из отдела HR не упустили возможность «попиарить» горячие вакансии.

      P.S. Если что, нам, а точнее мне в команду, так же ОЧЕНЬ нужен Fullstack JavaScript разработчик.


      1. iago
        06.08.2019 16:52
        +2

        Понятно, не обратил внимание что блог корпоративный, сильный блог для корпоративного сегмента! Я, к сожалению или к счастью, iOS developer :)


  1. TheGodfather
    06.08.2019 16:24
    +5

    >Я считаю, что за адекватные деньги Телеграм получит самую лучшую в мире библиотеку для отображения графиков: лучший результат из сотен попыток сделать лучше, чем у других. Соревновательный принцип позволяет получить настолько высокий уровень качества, который на заказ не способен сделать никто и ни за какие деньги.

    Вы же знаете про вечный баланс олимпиадников-рокстаров и инженеров-середнячков. Вы не получите «высокий уровень качества» и «лучший результат». Точнее, результат может хорошо работать и быть производительным, но очень маловероятно, что он будет maintainable и production-quality.


    1. ShibaOn Автор
      06.08.2019 16:48
      +1

      Я сам считаю, что из «олимпиадников» боевые единицы для разработки прикладного ПО так себе — возможно это просто моя зависть, потому что я на олимпиадах показывал средние, если не сказать плохие, результаты :-)

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

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


      1. SemenPV
        06.08.2019 20:05

        По условиям конкурса Телеграм имеет право использовать любой код который к ним был послан? Мне казалось что подобное не должно быть возможным, может конечно в Саудовской Аравии это ок, но думаю что это черевато судебными исками. Зачем им это надо, если они могут любую профессионально написанную библиотеку подтянуть?


        1. ShibaOn Автор
          06.08.2019 22:05

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


    1. iago
      06.08.2019 16:56
      +1

      Подпишусь под каждым словом, более того, копая исходники open source либ, я всегда видел почему сделан тот или иной костыль. И любой совершенный изначально код обрастает костылями.

      То же и про производительность. Помню, вышел Chrome году в 2009-м, о боже как он быстро работал, все сразу стали на него переходить. А потом, когда его функциональность сравнялась с тем же фаерфоксом, разрыв стал уже далеко не таким впечатляющим.

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


      1. Kwisatz
        06.08.2019 21:41

        Ах еслиб еще можно было открутить, цены бы решений этим небыло. Но у некоторых либ приходиться с мясом вырывать эти костыли


        1. karabas_b
          07.08.2019 04:53

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


          1. Cerberuser
            07.08.2019 07:24

            А если речь о библиотеках, которыми пользуются разработчики, а не о программах для конечных юзеров?


            1. JSmitty
              07.08.2019 09:23

              Разработчики тоже обычно не любители пространных конфигов. Популярность Parcel тому примером.


              1. Cerberuser
                07.08.2019 10:16

                То есть, сделать грамотный конфиг единственно возможным — это нормально и правильно, а сделать тот же самый конфиг конфигом по умолчанию, но дать возможность его менять, — это уже сложно, страшно и всех распугает?


  1. ReklatsMasters
    06.08.2019 19:03

    Уже существующие решения и библиотеки использовать было нельзя, всё должно было быть написано с нуля.

    Вот этот бред в головах дуровых идёт с самого вк. Вместо существующих решений постоянно какие-то низкокачественные велосипеды. Тот же вк миру веб разработки не дал НИЧЕГО несмотря на то, что у них было всё своё. При этом дуров гордо рапортовал, что нанимает самых лучших разработчиков. И пофиг, что весь вк того времени был монолит, а js был ужаснейшим лапшекодом с глобальными переменными.


    1. psFitz
      06.08.2019 19:44

      а что он должен был вам дать? Хоть там был и лапшекод, но он работал очень быстро, особенно на фоне фейсбука, который дал миру react


      1. ReklatsMasters
        07.08.2019 00:05

        Сравнивать вк и фб не очень корректно из-за размера аудитории, объёма доходов и т.д. Реакт очень сильно помог снизить затраты фб на поддержку и увеличить скорость внедрения фич. По вк такой инфы нет, но я могу судить по себе: входить входить в крупный монолитный проект с кучей глобальных переменных и стейтов очень сложно.


        1. psFitz
          07.08.2019 09:30
          +1

          при чем тут размер аудитории? Я сравниваю по тому, как быстро работает фронтенд, это никак не относится к размеру аудитории. Да фб зарабатывает больше денег, но это обусловлено 2 факторами:


          1. Контакт заточен под снг, а фб под весь мир
          2. На фб интерфейс построен таким образом, что-бы для простого действия надо было больше экранов видеть, для показа рекламы на этих экранах


    1. mad_god
      07.08.2019 10:45

      эмм,

      В конце мая, перед началом сезона отпусков, суточная посещаемость ВКонтакте достигла очередного рекорда — почти 50 млн. пользователей. Именно тогда мы завершили перевод всего кода ВКонтакте на компилируемый язык программирования, который разрабатывали более года, — KPHP. В результате практически все страницы сайта стали грузиться более чем 2 раза быстрее.


    1. TheGodfather
      07.08.2019 11:19

      Тем не менее, в итоге все-таки ВК работает на порядок шустрее и приятнее ФБ. Вполне возможно, что говнокод от олимпиадников, который не очень поддерживаемый, но при этом работает :) Мне как пользователю важнее, что сайт работает быстро, нежели что говнокод внутри. Баланс такой баланс…


    1. RomanArzumanyan
      07.08.2019 11:54

      Vk — это коммерческая компания, целью которой является получение прибыли.
      Они её таки получали. Разработка программного продукта была средством получения, а не целью.

      Уже существующие решения и библиотеки использовать было нельзя, всё должно было быть написано с нуля

      Это совершенно здоровый подход в случае замкнутой на саму себя экосистемы. Используется в геймдеве под консоли повсеместно.
      Vk был новой предметной областью для применения существующих подходов.


  1. anatoliy841993
    06.08.2019 20:21
    +4

    Почему используете setInterval когда для плавных анимаций есть requestAnimationaframe?


    1. ShibaOn Автор
      06.08.2019 21:57

      requestAnimationFrame для рендеринга, поскольку в примерах рендеринга нет, решил не усложнять.


      1. anatoliy841993
        07.08.2019 12:43
        +1

        не совсем с вами согласен, это может быть полезно не только с рендерингом, React давно использует raf, вот пример из RN
        facebook.github.io/react-native/docs/performance#my-touchablex-view-isn-t-very-responsive


        1. ShibaOn Автор
          07.08.2019 12:54

          Вероятно, я в данном вопросе проявляю некоторую архаичность, поэтому мне стоит присмотреться к requestAnimationFrame, так что спасибо за ссылку :-)


          1. webschik
            07.08.2019 15:05
            +1

            Вот еще одна хорошая демонстрация того, где можно испрользовать raf не только для анимаций github.com/wilsonpage/fastdom


  1. Barbaresk
    06.08.2019 21:19

    А есть где-то инфа по распределениям Canvas/SVG по местам победителей? После информации о велосипедостроении и js в full-стеке, был уверен, что автор выберет Canvas, но интересно, что выбрали другие.


    1. ShibaOn Автор
      06.08.2019 22:02

      Статистики такой нет, при желании можно её собрать вручную, но в телеграмм-чатеге конкурсантов на первом этапе конкурса обсуждался исход участников с SVG в сторону Canvas из-за неудовлетворительной производительности. Хотя мне тогда казалось, что SVG всё-таки пошустрее. Субъективно, среди лидеров конкурса Canvas преобладает.


  1. Kwisatz
    06.08.2019 21:40
    +2

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


  1. altmind
    06.08.2019 23:12

    Участники могут публиковать исходники? Я бы посмотрел на организацию кода в разных вариантах.


    1. Finesse
      07.08.2019 09:12
      +1

      Отправка решения в виде необфусцированного кода — одно из условий второго тура. Решения и соответствующий код можно посмотреть здесь: https://contest.dev/chart-js


  1. MTonly
    06.08.2019 23:38

    Как я не занял первое место
    Где вы сейчас не снимаетесь?


  1. where-is-s
    07.08.2019 07:46
    +2

    Я занял в том же конкурсе два вторых места среди разработчиков на Андроиде, в первом туре и во втором. Ask me anything.
    Тут опубликовал исходники, если кому будет интересно: github.com/where-is-s/telegram-chart-contest


    1. ShibaOn Автор
      07.08.2019 12:39
      +1

      Искренне поздравляю и по-доброму вам завидую! )


  1. Finesse
    07.08.2019 09:10
    +2

    Перед реализацией графиков я провёл сравнение производительности canvas и SVG на примере, имитирующем нагрузку графиков из задания, и выяснил, что SVG намного медленнее на Android. А реализации на WebGL не получили награду выше 3-го места.


    1. ShibaOn Автор
      07.08.2019 10:56
      +1

      Спасибо, очень полезная инфа!


  1. Tsumibit0
    07.08.2019 10:56
    -1

    Про ускорение кода)) Проблема как всегда в базовых знаниях смежных областей. Пока афтор не разберется что такое 60fps и чем это отличается например от 50fps или 25fps — дела не будет. Можно бесконечно биться об стену головой, но если там гвоздь — в голове выйдет дырка. И дело не в коде, а в подходе))


    1. ShibaOn Автор
      07.08.2019 11:00

      Вы говорите о знании про микротремор сетчатки глаза? :-)


  1. test1901
    07.08.2019 12:55

    Зарегался тут специально чтобы оставить этот коммент. Будет сумбурно, но, как говорится, нет времени объяснять.

    1. Это самый несправедливый конкурс, в котором мне когда-либо приходилось принимать участие. Просто не хватает матов, чтобы изложить, что я думаю об жюри этого конкурса. Как можно призовать работы, в которых не реализован ключевой с инженерной точки зрения функционал второго этапа конкурса? я говорю о возможности зумить график.
    1.1. объективно лучшая работа в конкурсе contest.dev/chart-js/entry150. но заняла 3 место.

    2. Автор, вот вы пишите о перформансах свг, канваса, тайпскрипта, о 10 лет опыта. ну зачем вы обманываете себя насчет своих скиллов? делать анимацию через интервал при наличии requestanimationframe — ну это просто фейспалм. по-моему в 21 веке уже любой школьник знает, что ключевой аспект браузерного перформанса — это рендеринг. а так как рендеринг и скриптовые вычисления происходят в одном потоке, то только с помощью requestanimationframe их можно условно разделить и добиться высокого фпс. ну хотя бы контролировать этот процесс. и интервалом вы никогда не добьетесь того фпс, о котором мечтаете (деля 1000 на 16). все ваши итерации будут выстраиваться в очередь, не важно сколько времени будет занимать реальная отработка каждого цикла. и реальный фпс с вашим мнимым никогда не сойдутся, даже на примитивных задачах. не говоря уже о задаче конкурса. на старых мобилках гоняли свои графики?

    3. моя работа тут contest.dev/chart-js/entry163
    выиграла никакое место. замеченные ошибки описаны в ссылке. есть зум 2 графиков и плавнейший скроллинг. планировал успеть сделать остальные 3 за день-два с зумом. но времени не хватило. сделать 5 графиков без зума можно за два дня, если участвовал в первой части конкурса.

    p.s. что качается справедливости оценки работ. да, согласен, это мероприятие частной компании, со своим блекджеком, и, следовательно — как хотим, так и судим, если что — идите на… Но камон, если главный устроитель конкурса из каждого ящика осуждает российское мракобесие, то имеет ли он моральное право устраивать конкурсы и судить как захочется? именно из-за репутации Дурова я решил принять участие. но, спасибо, больше не надо.

    p.s.s в школе участвовал в олимпиадах по математике, физики, химии. и во всех олимпиадах принцип был такой. если суть задачи (ее ключевая фишка, заковырка) конкурсантом уловлена, а принцип, которым можно задачу решить, установлен, то даже если вычисления не верны или даже если не успел их провести, то всё равно хоть какой балл за задачу да получишь. причем если задача реально сложная, то только за метод решения (без решения) можно получить баллов больше чем за простую задачу, решенную полностью.

    и это справедливо.

    тут же предложили задачу на 2 недели, которую по-хорошему нужно делать месяца 2 и оценивают кто сколько графиков сверстал и кому друзья больше лайков на странице поставили. при этом еще главное продлевают на 3ий этап, т.к. никто на первое место не потянул.

    заб… ла вся эта иррациональщина и упрямство. что автор, что устроитель конкурса, что гос. верховоды — одна ху… ня


    1. ShibaOn Автор
      07.08.2019 13:00

      Спасибо за отзыв, мне очень интересна ваша точка зрения по поводу конкурса, жаль что есть мат, хоть и «запиканый», как бы не прилетело НЛО и не удалило комментарий.

      Мне есть что вам ответить по поводу requestanimationframe, я его использовал именно для рендеринга, а в примерах setInterval привёл потому, что в них рендеринга нет, а усложнять примеры не хотелось.

      В остальном, я вас хорошо понимаю, хотя и не со всем согласен.


    1. bakhirev
      07.08.2019 14:53

      Согласен. Писал свое решение на WebGl (несколько типов графиков с зумом, возможностью выделить диапазон данных и т.п.). Производительность был сумашедшая. Видел, другие работы на WebGL. Они были лучше. Думал, что выйграет что-то подобное.

      Когда увидел код победителя (первый этап, лапша на SVG) задумался о качестве кода в тележке и вк. Желание когда либо ещё участвовать в подобном конкурсе отпало.


  1. DmitryKazakov8
    07.08.2019 18:01
    +1

    Благодарю за статью и хорошо структурированный код. Сам незримо участвовал для получения опыта — за пару дней собрал рабочий прототип (тоже canvas), определил моменты в которых был слаб и точечно прокачал. Отдавая себе отчет, что первое-второе место для javascript-разработчика (а участвовало их много) взять будет неоправданно сложно, а поощрительные призы экономически невыгодны, дальше дорабатывать не стал. А пара дней на то, чтобы расшевелить мозг новыми задачами — это удовольствие.


    1. ShibaOn Автор
      07.08.2019 18:41

      Спасибо! Я тоже люблю соревнования и конкурсы именно за возможность подумать над нехарактерными для будничной рутины задачами — как вы правильно заметили, мозг начинает шевелиться :-)