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

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



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

Сколько ядер имеет процессор компьютера или смартфона?


Все мы видели изображения процессоров, вроде того, что показано ниже.


Например, если вы работаете на Mac, вы можете щёлкнуть на значке яблока в верхнем левом углу рабочего стола, далее — выбрать пункт меню About This Mac, после чего вам будет показано нечто вроде Processor 3,2 GHz 8-Core Intel Xeon W.

У процессора iPhone имеется 6 ядер.

Короче говоря, в распоряжении каждого компьютера или смартфона имеется несколько процессорных ядер.

Это значит, что вы можете выполнять на этих ядрах, в параллельном режиме, несколько потоков.

Если бы вы создавали автомобиль — оснастили бы вы его двигателем, в котором имеется лишь один цилиндр?

Если ваш ответ будет звучать как «Конечно нет! Это будет очень медленный автомобиль!», тогда вам стоит внимательно читать эту статью.

Сколько процессорных ядер использует браузер?


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

Это значит, что ваше Angular- или React-приложение выглядит примерно так:


Чем больше JavaScript-задач выполняется в вашем приложении — тем медленнее оно будет работать. Самое худшее, что может случиться, выглядит как полное «подвисание» интерфейса, когда единственное доступное вам процессорное ядро оказывается полностью загруженным. А вот другие его ядра в это время, вполне возможно, будут совершенно ничем не заняты.

И это всё совершенно не масштабируется.

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

API Web Workers


Вот что пишут о веб-воркерах на MDN:
Web Workers это механизм, который позволяет скрипту выполняться в фоновом потоке, который отделен от основного потока веб-приложения. Преимущество заключается в том, что ресурсоёмкие вычисления могут выполняться в отдельном потоке, позволяя запустить основной (обычно пользовательский) поток без блокировки и замедления.
А вот что о них сказано в Википедии:
W3C и WHATWG представляют себе веб-воркеры в виде скриптов, выполняющихся длительное время, выполнение которых не прерывается скриптом, ответственным за обработку щелчков мышью или других механизмов взаимодействия пользователя с приложением. То, что работа подобных скриптов не может быть прервана действиями пользователя, должно способствовать тому, что веб-страницы остаются отзывчивыми в то же самое время, когда они выполняют длительные задачи в фоновом режиме.

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

Давайте вдумаемся в следующие слова:

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

Они ведут нас к вопросу: «Что является самой сложной вычислительной задачей?».

Ответ на этот вопрос очень прост: это выполнение кода самих UI-фреймворков или библиотек, а так же кода тех приложений, которые мы создаём с их использованием.

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

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

Эта идея ведёт нас к концепции, приведённой в заголовке следующего раздела.

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


Для того чтобы устранить вышеописанное узкое место в производительности веб-проектов, мы стремимся к тому, чтобы как можно меньше нагружать главный поток. Это позволяет ему уделить максимум внимания задачам рендеринга и динамического обновления DOM.


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

Возможно, наилучшее решение для одностраничных приложений (single page apps, SPA) выглядит так, как показано ниже.


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

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

В этом материале можно почитать о том, как сделать использование воркера необязательным.

Может ли воркер работать с DOM?


В глобальной области видимости воркера (WorkerGlobalScope) не определены переменные window и window.document.

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

В результате для организации работы с DOM из воркера у нас есть 2 варианта.

Первый — это воссоздание всего DOM API внутри воркера. Полагаю, что это — плохая идея. Воркеры не без причины отделены от DOM, с DOM связано огромное количество постоянно меняющейся логики. Операции по взаимодействию с DOM становятся асинхронными, и если вы последовательно выполняете множество таких операций, это приведёт к тому, что воркер будет отправлять множество сообщений создавшему его потоку, используя метод postMessage(). Единственное преимущество такого подхода заключается в том, что код приложений можно писать так же, как его писали раньше, а это — спорное преимущество. Позже я расскажу о более приемлемом варианте решения этой задачи.

На самом деле, существует проект, worker-dom, в рамках которого реализована именно такая схема работы.

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

Это делает совершенно обязательным использование виртуальной DOM.

Мне встречались статьи, где часто проскакивает мысль о том, что виртуальная DOM — это плохо.

Но это попросту неправда. Ответ на вопрос о том, «хорошо» это или «плохо», сильно зависит от реализации виртуальной DOM.

Главными камнями преткновения в Angular и React являются шаблоны, основанные на XML или JSX. Их надо транспилировать, превращая в нечто такое, с чем мы можем работать.

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

Парсинг шаблонов — это настолько вычислительно сложная операция, что в наши дни снова стал популярным серверный рендеринг (server side rendering, SSR). Я занимался веб-разработкой 20 лет назад, создавая CMS, основанные на PHP, которые генерировали HTML-файлы на сервере.

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

Существуют ли исключительные ситуации, в которых воркер может получать доступ к DOM?


На самом деле — есть лишь одно исключение. Это — интерфейс OffscreenCanvas. Смысл тут в том, что воркер может получать контроль над узлами DOM, представляющими собой элементы canvas.

Этот механизм уже отлично работает в Chromium, в Safari (Webkit), а в Firefox идёт его активная реализация. Возможно, это займёт ещё месяцев шесть, в результате это — тема для публикаций 2022 года.

Возможно вы, на одной из предыдущих схем, заметили жёлтый блок с надписью Canvas Worker. Если тема работы с графикой за пределами главного потока вам интересна — взгляните на этот материал.

Каков разумный подход к созданию виртуальной DOM?


Хотя JavaScript — это и не лучший язык для разбора строк, он отлично показывает себя в деле работы с вложенными структурами, представленными объектами и массивами. У такого формата представления данных есть название, с которым вы, определённо, знакомы: JSON.

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

Это, определённо, аналогично прямой работе с тем, что получается после парсинга JSX-шаблонов.

Если при таком подходе всё организовано правильно — то в виртуальной DOM не будет ни переменных, ни выражений if/else, ни привязок, ни методов, ни циклов, ни какой-либо логики. И, если вспомнить Angular, вы никогда не столкнётесь с шаблонами, состоящими из более чем 1000 строк кода.

С применением программного подхода логика будет использоваться там, где ей и место: в JavaScript-коде. Например, при создании списка можно сначала построить скелет этого списка для виртуальной DOM, а после того, когда из хранилища поступят данные для этого списка, обойти записи, на ходу создавая узлы виртуальной DOM.

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

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

Много интересного на эту тему можно найти здесь и здесь.

И, хотя применение программного подхода имеет смысл для реализации низкоуровневых операций с виртуальной DOM, мы, определённо, предпочитаем, при создании программ, использоваться декларативным подходом.

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

Смысл тут в том, что работать с виртуальной DOM нужно будет лишь при создании классов компонентов. А при создании приложений можно просто пользоваться деревом компонентов.

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


Когда 5 или 8 лет назад стала популярной библиотека React, браузеры не лучшим образом показывали себя в деле поддержки самых свежих возможностей, описанных в стандарте ECMAScript.

Например — там не было поддержки классов (ES6) или JS-модулей.

В тот момент имело смысл перевести решение задач UI-разработки на платформу Node.js.

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

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

Если говорить о воркерах, то, например, в Chromium они хорошо поддерживают использование JS-модулей. Разработчики Webkit (Safari) завершают работу над аналогичной возможностью, но она пока доступна лишь в версии браузера Safari Technology Preview. Mozilla (Firefox) активно работает над этой технологией.

Можно с высокой долей уверенности предположить, что полная поддержка модулей в воркерах появится в 2022 году.

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

Такой подход имеет очевидные сильные стороны:

  1. JavaScript должен быть единственным языком программирования, который понимают движки браузеров.
  2. Написание JS-кода таким образом, что он оказывается непонятным браузеру, не считается чем-то нормальным.
  3. Перенеся UI-разработку обратно в браузер, мы можем отлаживать реальный код без применения сборщиков и транспиляторов, без использования карт кода.
  4. Нет нужды в замене механизмов работы с модулями.

В частности, написание и отладка кода снова станут приятными занятиями, так как мы будем уверены в том, что работаем именно со своим кодом, и что некие внешние факторы не являются источником ошибок.

Инструменты вроде webpack, определённо, всё ещё нужны для создания продакшн-вариантов приложений. Но они будут представлять собой инструменты для сборки проектов, а не части сред выполнения кода.

Переход с Node.js на Deno ещё сильнее подстегнёт это движение. CommonJS исчезнет — скорее рано, чем поздно. А после того, как в Deno появится менеджер пакетов, всё больше и больше пакетов будут использовать синтаксис, который позволит им работать в браузерах (то есть — отказ от использования простых спецификаторов модулей, отсутствие импортов с путями, не поддерживаемыми браузерами, отсутствие расширений файлов).

Есть ли будущее у TypeScript?


Это, вероятно, самый спорный раздел данной статьи. Сообщество JS-разработчиков раскололось пополам: одним TS нравится, а другие и близко к нему не подходят. И я с нетерпением ожидаю появления новых аргументов в их споре.

Сам я думаю, что прямо сейчас, при использовании для разработки интерфейсов возможностей Node.js, и, в любом случае, не имея возможности обойтись без сборки или транспиляции проекта, пользоваться TS — это совершенно нормально.

Но ситуация коренным образом изменится после того, как разработка интерфейсов будет выполняться на основе браузеров.

Станете ли вы добавлять в рабочий процесс дополнительный шаг сборки проекта только ради использования TS?

В этот момент применение TS окажется слишком дорогим удовольствием.

Самое важное тут то, что TypeScript — это не веб-стандарт. И нет даже планов по реализации поддержки TS браузерами.

История, совершенно определённо, уже несколько раз показывала нам, что происходит с веб-технологиями, которые не основаны на веб-стандартах. А именно — такие технологии просто в определённый момент исчезают. Отличный пример этого — Microsoft Silverlight.

Проверка типов — это, в целом, хорошая вещь. Главная проблема заключается в том, что Angular и React попросту не используют комментарии, основанные на JSDoc, что позволяло бы IDE выдавать предупреждения в процессе написания кода.

Но, на самом деле, можно «обмануть» TS, пользуясь JSDoc-комментариями в обычных JS-файлах.

Это, определённо, интересная возможность, о которой можно и поговорить.

Если вам и правда очень нужна поддержка проверки типов в языке, которым вы пользуетесь, и шаг сборки проекта вас не особенно беспокоит, не окажется ли Dart 2 именно тем, что вам нужно?

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

Что не так с React?


Буду честен: ещё до того, как появилась библиотека React, существовала библиотека jQuery. Когда библиотека React стала популярной, это стало для веб-разработки большим шагом вперёд. Это была первая библиотека, которая открыла множеству разработчиков путь к применению виртуальной DOM.

Почему бы нам не использовать React в 2022 году? У этой библиотеки есть некоторые недостатки:

  1. Код React выполняется в главном потоке.
  2. Кодовая база React основана на CommonJS, в результате код этой библиотеки не может выполняться в браузере без предварительной сборки React-проекта.
  3. Отсутствие поддержки JSDoc-комментариев.
  4. Парсинг JSX-шаблонов весьма ресурсозатратен. Есть даже компиляторы, вроде Svelte, направленные на то, чтобы переложить решение этой задачи на сервер.
  5. React не даёт доступа к механизмам своего ядра. Всё в нём, непонятно почему, выглядит как расширение Component.
  6. Управление состоянием приложений устроено, без всякой на то причины, слишком сложно.
  7. Метод render() весьма неоднозначен.

Хочу подробнее остановиться на последнем пункте этого списка. А именно, речь идёт о том, что сложно сделать так, чтобы изменения состояния не вызывали бы render(). Если React-компонент содержит дочерние компоненты (собственные теги в render()), то, если недостаточно разумно пользоваться keys, будут создаваться новые экземпляры компонентов.

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

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

React — это всего лишь библиотека, а не фреймворк. То есть — Component — это, в общем-то, всё, что даёт нам React. Тут нет логических иерархических связей наподобие следующей:

core.Base -> component.Base -> button.Base -> tab.header.Button

После того, как разработчик справился с безумием render(), он может выбрать наиболее подходящий базовый класс для того, что хочет создать. Например, у класса Container есть объект vdom, который содержит ссылки на объекты виртуальной DOM своих дочерних элементов. Это позволяет менять виртуальную DOM дочерних компонентов, не пересоздавая их экземпляры, описанные средствами JS.

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

Многооконные приложения


Если поменять вышеописанную архитектуру приложений, использующих воркеры, и добавить в неё воркер, который может работать с различными вкладками или окнами браузера (Shared App Worker), это ещё сильнее расширит наши возможности.


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

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

При таком подходе, например, можно перетаскивать объекты между разными окнами.

Если вам это интересно — существуют публикации на эту тему, которые вы можете найти самостоятельно.

Нужно ли самостоятельно создавать вышеописанную архитектуру приложения, основанную на воркерах?


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

Но если вам интересен этот подход — знайте, что самим вам всё это реализовывать не придётся. Вы вполне можете воспользоваться моими наработками, представленными проектом neo.mjs. В него уже сделано более 12000 коммитов, он выпущен под лицензией MIT.

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

Во фреймворке neo.mjs имеется уже множество компонентов, контроллеров, представлений и различных вспомогательных классов.

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

Тут, кроме того, очень просто устроено управление состоянием (с использованием классов).

Вот страница, на которой собраны примеры neo.mjs-приложений и публикации об этом фреймворке.

Для этого фреймворка созданы инструменты командной строки, с помощью которых, например, можно создать новый проект (рабочее пространство), выполнив одну простую команду: npx neo-app. Neo.mjs поддерживает объединение фрагментов приложений, что ведёт к тому, что при размещении нескольких приложений на одной странице практически не создаётся дополнительная нагрузка на систему.

Итоги


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

Правда, к сожалению, многие разработчики всё ещё даже не знают о существовании проекта neo.mjs.

И да, я буду рад, если кто-то попытается разубедить меня в правильности всего того, о чём я тут рассказал. Для того чтобы это сделать, вам нужно будет создать своё первое neo.mjs-приложение, на котором вы сможете проверить мои идеи. Я, в таком случае, с удовольствием проведу код-ревью вашего проекта. В заключение хочу сказать, что neo.mjs — это самое быстрое из существующих средств, позволяющих манипулировать DOM во время работы кода. Особенно — если речь идёт о больших и сложных приложениях.

Планируете ли вы попробовать neo.mjs?

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


  1. anonymous
    00.00.0000 00:00


  1. flancer
    13.10.2021 17:22
    -1

    История, совершенно определённо, уже несколько раз показывала нам, что происходит с веб-технологиями, которые не основаны на веб-стандартах. А именно — такие технологии просто в определённый момент исчезают. Отличный пример этого — Microsoft Silverlight.

    Главная проблема заключается в том, что ... попросту не используют комментарии, основанные на JSDoc, что позволяло бы IDE выдавать предупреждения в процессе написания кода.

    Ну вот, я не один такой, кто считает, что ES6 + JSDoc ничуть не хуже TS, а в чём-то даже и лучше (например, не завязаны на одну корпорацию, пусть даже и очень большую).


  1. anonymous
    00.00.0000 00:00


  1. flancer
    14.10.2021 07:01

    С удовольствием перейду на TS как только он начнёт работать в Chrome и Safari напрямую, без транспиляции. Можно без FireFox'а. Нет, даже ещё раньше - как только разрабы движков Blink и WebKit заявят о своих намерениях реализовать нативную поддержку TS. Вот прямо на следующий день и начну кодить на TS, обещаю!

    Это к вопросу о том, какие web-технологии считать web-стандартами (которые, кстати, тоже не самые глупые люди утверждают).


    1. Kuch
      14.10.2021 08:17
      +3

      Как я понимаю, сейчас вы используете только ту функциональность js и css, которая поддерживается всеми этими браузерами и не используете Бабель для транспиляции?


      1. flancer
        14.10.2021 08:26

        именно так.


        1. mr_molodoy
          22.10.2021 14:48

          Можно поинтересоваться чем это обусловлено? (не сарказм)

          Полагаю что ответ кроется в том что вы просто на клиенте js используете что бы производить простые манипуляции с DOM?

          Т.к. в случае работы над большими приложениями обойтись без более серьезных инструментов (вроде vue, react и т.д.) просто не получится (а с ними в ваш проект приходит и использование babel).

          А к вопросу по typescript - он ведь приносит не только синтаксический сахар (который сейчас конечно и в es6 завезли), но и хоть какую-то типизацию.
          Когда в вашем приложении очень много структур различных типов данных - вам нужно их как-то описывать (typescript как раз с этим очень неплохо выручает).

          Если же все ваши задачи на клиенте сводятся к тому что бы императивным способом обновить часть DOM на странице, то разумеется тянуть в приложеие все описанное выше будет overhead.
          Но не стоит же в таком случае говорить что "что ES6 + JSDoc ничуть не хуже TS" т.к. TS дает все же больше чем Вам от него требуется и он просто конкретно Вам не нужен, для решения конкретно Ваших задач.
          По этому не стоит приводить личный в виде объективной оценки. Для разных задач - требуются разные инструменты.


          1. flancer
            22.10.2021 16:26

            Можно поинтересоваться чем это обусловлено? (не сарказм)

            Я просто считаю транспиляцию лишней.

            Т.к. в случае работы над большими приложениями обойтись без более серьезных инструментов (вроде vue, react и т.д.) просто не получится (а с ними в ваш проект приходит и использование babel).

            Нет, можно с vue работать и без babel'я. Вот TODO-демо, в котором используется Vue 3 & Quasar UI и не используется транспиляция. Зайдите во вкладку Sources панели Dev Tools в Chrome и сами увидите.

            Когда в вашем приложении очень много структур различных типов данных - вам нужно их как-то описывать

            JSDoc

            Для разных задач - требуются разные инструменты.

            Абсолютно верно

            По этому не стоит приводить личный в виде объективной оценки.

            Объективности не существует, это всего лишь сумма субъективностей. Я полагаюсь на свой личный опыт, потому что я стараюсь по максимуму не лгать самому себе. Буду только рад, если все в мире будут поступать так же. И это... я нигде в этой публикации не говорил, что мой личный опыт - это объективно (сделайте поиск по ключу "объектив"). Я действительно высказываю свою личную точку зрения, а считать её субъективной или объективной - это уже ваш выбор. В любом случае, спасибо за этот совет - я постараюсь и далее не делать того, чего не делал ранее.


    1. Integrus
      14.10.2021 11:32
      +6

      Я думаю TS никогда нативно не будет работать в браузере, потому что type check занимает много времени и не нужно вне разработки.


      1. flancer
        14.10.2021 17:53

        Вот в том-то и дело - два движка поддерживать смысла нет, а полезные фичи из TS в JS потихонечку мигрируют. И если смотреть в перспективу чуть подальше, то вопрос только один - когда?


  1. anonymous
    00.00.0000 00:00


  1. anonymous
    00.00.0000 00:00


    1. Alexandroppolus
      13.10.2021 17:33
      +5

      В статье сильно преувеличено число "отрицателей тайпскрипта", и делается неуместное сравнение с сильверлайтом, который изначально был какой-то посторонней нашлепкой на браузер. TS, во первых, максимально возможно совместимый с JS (сравните с КофеСкриптом, который из-за дурацкого синтаксиса закономерно оказался на помойке), во вторых, компилится в сборке и ничего не требует в рантайме.

      Полагаю, говорить о "победе Тайпскрипта" следует как о свершившемся факте.


      1. RiverFlow
        14.10.2021 10:41

        Тайпскрипт не нужен!

        "Победа" кого над чем? Если ТС над ЖС то по статистике жс кода без ТС за год написано в шесть раз больше.

        "По ела" если и есть то в фантазиях конечных ООПщиков так и не понявших что они уже не в розовом вакууме джавы а в реале веба


        1. Alexandroppolus
          14.10.2021 16:41

          Код, который пишется на js - это в основном сопровождение старых проектов, которые (пока) не протипизированы. Новое почти всегда на Машинописи.

          А каким образом это обсуждение связано с ООП? И чем "розовый вакуум джавы" отличается от "реала веба"?


          1. Artima
            15.10.2021 09:01

            Множество стандартных библиотек тоже не типизировано. Что с этим делать? Ждать лет 10 ещё, когда можно будет перестать использовать any?


            1. Alexandroppolus
              15.10.2021 10:03
              +1

              Сейчас довольно сложно найти более-менее известную библиотеку без встроенной типизации, к которой не было бы пакета "@types/nnn"


            1. faiwer
              18.10.2021 11:55

              Множество стандартных библиотек тоже не типизировано

              Если брать не количественно, а по популярности\частотности их использования, то почти всё типизировано. Это как сказать что большая часть интернета до сих пор на HTTP, что отчасти правда, если считать число сайтов. Но если учесть долю на рынке, то всё наоборот (посмотрите среди открытых вкладок сколько из них не HTTPS). Такая же ситуация и с типами.


              Проблема типов "стандартных" библиотек не в том, что типов нет, а в том что часто они посредственного качества. Скажем не все методы описаны, не все объекты полны, местами стоят any и т.д..


              можно будет перестать использовать any

              Его и сейчас нет необходимости использовать. В тех редких случаях когда типов нет вообще, они пишутся руками в d.ts файлах в кратчайшие сроки, т.к. не требуется покрывать всю библиотеку. Достаточно только того API что вы используете в своём проекте.


    1. Drag13
      13.10.2021 17:36
      +4

      Это до тех пор пока вы не используете преобразование типов, когда один тип выводится из другого.

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

      const user = { name: 'testName', age: 25 };
      
      const validations: { [key in keyof typeof user]: (v: any) => boolean } = {
      
          name: () => true, //OK 
      
          age: () => true, //OK
      
          birthday: () => true // Not OK birthday not exists in the given type
      
      }

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


      1. RiverFlow
        14.10.2021 10:46
        -1

        Нет не подсказывает , а ещё хуже что подсказывает но далеко не всегда, посмотри Климова!

        И вот когда он не подсказывает, де-факто тупо не выполняет рефакторинг там, где обещает, случается полный звиздец от исчезновения куска дом до разрушения БД.

        Но тайпскриптщики в каментах знаете что говорят? Правильно, "тестить надо!" И "глаза разуть"

        Тогда нахрена мне ваш тайпскрипт, чтобы "разувать глаза" на ещё один язык ?

        Вам говорят что нафиг бы ваши "типы" вообще, и приводить нечего будет!

        А вы в ответ: так ведь же приведение типов !?


        1. Drag13
          14.10.2021 11:09
          +3

          Простите, что? Я привел конкретный кусок кода. Он:

          1. Подсказывает

          2. Всегда

          Если у вас есть пример на котором этот код сломается - несите в студию, будем смотреть.

          Да, TS не идеален. И не панацея. Иногда он не может вывести типы самостоятельно и тогда мы получаем неявное any, которое и может привести к ошибкам с рефакторингом. Иногда сами разработчики сами пишут any, а потом удивляются что "что-то пошло не так". Бывает что написать сложный тип может быть не просто, это занимает время и в итоге вылазит боком, т.к. тип слишком сложный. Поверьте за почти 5 лет работы с тайпскриптом, ответами на стековерфлоу я все это знаю и прочувстовал своими пальцами.

          И тем не менее я все равно за тайпскрипт по очень простой причине - когда я возвращаюсь к своему проекту через несколько месяцев, он:

          • Намного проще читается

          • Позволяет включиться быстрее

          • Да еще и ловит часть ошибок при написании и! ловит будущие ошибки, например с обработкой enum или литеральных типов.


          1. i360u
            15.10.2021 12:25
            +1

            Вы же в курсе, что статический анализ из TypeScript поддерживает JsDoc аннотации? В VS Code, к примеру, даже устанавливать ничего не нужно, достаточно добавить // @ts-check в файл. И у вас все будет: вывод типов, сигнатуры функций, дженерики... Для совместной работы можно поставить хук с проверкой на коммиты и на сборку. И при этом, ваш код будет нормально работать в браузерах без сорсмапов и ваши модули можно будет свободно использовать в JS и TS проектах. А проблемы в TS возникают вовсе не из-за any, а чаще из-за того, что он до сих пор не умеет нормально компилить в ESM, выводить типы для сгенерированных классов и много чего еще.


        1. dopusteam
          17.10.2021 09:15
          +2

          до разрушения БД

          Если у Вас БД ломается от изменения ts, то у Вас проблемы с архитектурой


        1. faiwer
          18.10.2021 12:02

          посмотри Климова

          Не стоит. Он в своей нелюбви к Typescript давно уже перестал быть объективным. Его категоричность давно перешла грань здравого смысла. Особенно когда в одном видео он топит за то что типы не нужны, пишите на JS + тесты, а в другом давайте писать на sound re-script, ибо "всё или ничего". Либо язык без типов, либо сразу sound. Климов — просто TS хейтер. TS есть за что ругать, но Климов воюет не туда.


          Лично я с ним только в одном согласен — писать на TS хорошо могут немногие. Язык богат на возможности, но задействовать их с пользой бывает весьма нетривиально. Уровень входа в язык высокий.


  1. anonymous
    00.00.0000 00:00


    1. Heniker
      14.10.2021 11:32
      +4

      JSDoc вам не даст даже трети того, что умеет TypeScript.


  1. fransua
    13.10.2021 17:59
    +1

    Давно используем подобную схему (main window + worker + OffscreenCanvas), в нашем случае это почти что необходимость, т.к. много работы с графикой и обработки данных на клиенте. Для облегчения работы с воркером написали обертку, которая позволяет вызывать апи домена как обычный метод. Обертка заворачивает аргументы и путь к функции в json и отправляет в воркер, получает ответ и возвращает promise. Заодно сериализует параллельные запросы к воркеру в последовательные, так что внутри домена в 1 момент только один экшен выполняется. Довольно удобно вышло. Есть на гитхабе, но почти без комментариев и документации, руки еще не добрались(

    По поводу статьи есть несколько замечаний: OffscreenCanvas хорошо работает в FireFox (с включенным флагом, как говорит MDN, но я не уверен что это актуально) и никак не работает в Safari, в нем приходится рендерить в обычном canvas/svg, что получается значительно дольше, да и отзывчивость страдает. SharedWorker не работает с OffscreenCanvas, но его можно прокидывать через window.opener в обычный воркер.

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


  1. i360u
    14.10.2021 07:51
    +6

    Каким бы быстрым не был ваш Virtual DOM, вы не можете обойтись без этапа синхронизации его с реальным DOM, и тут все преимущества теряются а недостатки остаются. Вы, конечно, можете выиграть на обработке синтаксиса шаблона, но все равно не сделаете кастомный парсинг на js быстрее старого доброго innerHTML. Ну и кастомный синтаксис, если он у вас есть - это ваш "выстрел в ногу", без него легко можно обойтись используя стандартный DOM API внутри DocumentFragment на этапе создания экземпляра компонента. Помимо этого, вынос кода в воркер делает ваше решение глубоко асинхронным, со всеми вытекающими. В общем, в рассуждениях автора, имеются довольно слабые места, хотя настрой, в целом, верный.


  1. SergeiMinaev
    14.10.2021 14:28
    +1

    А вот другие его ядра в это время, вполне возможно, будут совершенно ничем не заняты.

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


  1. timikys
    15.10.2021 12:08

    Очень детальная и толковая статься, спасибо!


  1. whiteand
    17.10.2021 14:33

    Что вы подразумеваете под "парсингJSX шаблонов на клиенте"?


  1. faiwer
    18.10.2021 12:07
    +1

    Ожидал от статьи какой-то конкретики. Ведь все итак знают, что можно вынести часть логики в worker-ы, но потом встаёт проблема коммуникации между основным thread-ом и worker-ом. И вот тут дилемма — а как организовать это всё так, чтобы потери на обмен не превышали выгоды от выноса логики в worker-ы. Вот это было бы интересно почитать. А в статье имеем много-много воды и красивых диаграмм. Ух.