Pull to refresh

Comments 53

11. То, о чём все забывают. Производительность.
Каждый веб-компонент, будучи создаваем с помощью JS, затрачивает много больше процессорного времени, чем построение обычного, стандартного элемента DOM.

UFO just landed and posted this here
тормоза лейаута после ресайза

если у вас лейаут считается в js-e, то это будет тормозить на любом фреймворке.

В платформу надо добавлять лишь то, что невозможно реализовать на уровне библиотек. Fibers, например.

Как с помощью библиотек реализовать элемент с изолированным css и не торчащими наружу кишками (ShadowDOM)?

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


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

Насчёт кишок я не понял о чём вы

я про внутренний dom компонента, зачем он мне торчащий наружу.


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

хуже, глобальные стили протекают внутрь компонента.


Представь ситуацию: крупная компания, количество фронтенд-команд перевалило за десяток, каждая сама выбирает удобный ей фреймворк и базовый набор стилей. Можно, конечно, определить корпоративный стандарт, но это существенно усложнит поиск новых разработчиков. Кроме того проекты достаточно долгоживущие, фреймворки отмирают быстрее. При этом компания хочет свой корпоративный стиль, свои компоненты, отличающиеся от стандартных, часто не только цветом. Что делать? Разрабатывать и поддерживать библиотеки компонентов под каждый используемый фреймворк? Дороговато выходит.
Или другая ситуация: ты работаешь в компании A и разрабытываешь библиотеку компонент на фреймворке X. А потом либо меняется компания A и в компании B используется фреймворк Y, либо фреймворк X отмирает и все хотят Y. Куча работы вылетает в трубу, а ведь класный набор компонентов получился, хотелось бы дальше применять.
Веб-компоненты тут идеальное решение, ShadowDOM спрячет лишний внутренний dom, который теперь не будет мешать фреймворкам, глобальные стили не будут заставлять компонент расползаться, но, в то же время, есть хитрые css-селекторы позволяющие при необходимости что-то поменять внутри. Другими словами, получающиеся компоненты полностью автономны, так же как и уже встроенные в браузер input, select, video и тд. Из коробки веб-компоненты не очень удобны, но большинство существующих проблем решается легковесной обёрткой, опять же никак не мешающей существующим фреймворкам.

я про внутренний dom компонента, зачем он мне торчащий наружу.

Где? Речь про вкладку Elements в девтулзах? Когда всё приложение построено на shadow-dow — вам всё равно придётся открывать кучу веток этих самых кишок. Только ещё и путаться без конца будете между этими деревьями.


базовый набор стилей

Не надо так.


усложнит поиск новых разработчиков

Не усложнит.


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

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


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

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


класный набор компонентов получился, хотелось бы дальше применять

Так применяйте, какие проблемы?


есть хитрые css-селекторы позволяющие при необходимости что-то поменять внутри

Это какие? Когда я последний раз смотрел — их все задепрекейтили.


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

Ну конечно, и ленивый реактивный рендеринг к ним легко прикрутить?

вам всё равно придётся открывать кучу веток этих самых кишок

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


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

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


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

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


Ну конечно, и ленивый реактивный рендеринг к ним легко прикрутить?

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


Не усложнит.

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


Это какие? Когда я последний раз смотрел — их все задепрекейтили.

ну видимо когда-то предложат что-то на замену или достаточно того, что осталось, я сейчас больше про общую идею, а не про текущую её реализацию, которая пока да, не идеальна. Сам я из веб-компонентов использую только CustomElements и HTMLTemplates. ShadowDOM полноценно не полифилится, а существующие недополифилы сильно жрут производительность. Поэтому я не особо в курсе что там с селекторами. Использую привычный БЭМ.


о чём вы

применяйте

я себя лет на 20 старше чувствую)). Зачем вообще на хабре все выкают? В офисах и на конференциях все на ты, а здесь ощущение, как будто сплошные доктора наук собрались).

не нужно обычные въюхи в ShadowDOM запихивать

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


не выглядит как совмещение единорога с китом

Использование html для композиции компонент и костыли с аттрибутами/свойствами/слотами — это уже совмещение единорога с китом.


ждать когда он отомрёт

Ничего с ним не случится, если выбирать/создавать фреймворк исходя из потребностей, а не по принципу "что там сейчас в моде?". Если гнаться за модой, то сначала выбираются одни кривые технологии, а через пару лет они меняются на другие, не менее кривые.


Подобное нужно реализовывать на уровне конкретного компонента

Зачем что-то делать, если можно это не делать, а оставшееся время потратить на что-то более полезное?


найти разработчика на какой-то конкретный фреймворк

Не надо "искать на фреймворк". Толковый разработчик быстро освоит любой фреймворк. Бестолковый же и на своём любимом такого накреативит, что будете плакать кровавыми слезами.


Например, насколько легко находить разработчиков на mol?

Элементарно. Подойдёт любой знакомый с тайпскриптом. Пара недель и он уже контрибьютит во фреймворк. Прецеденты были.

В общем, я свою точку зрения высказал, принимать что-то или нет — дело твоё. Дальше препираться смысла не вижу, по моему опыту это не приводит ни к чему кроме потери времени. Удачи!

Раз уж на то пошло, а какую уникальную функциональность добавляют Fibers, которую не заменит async/await?

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

Не вижу здесь ничего такого, что невозможно реализовать в userland. Так что Fibers не вписываются под те же критерии, что вы применяете для ShadowDOM в треде выше.

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

как извне остановить асинхронную функцию

AbortController. Его можно не только с fetch использовать, но и для своего асинхронного кода


Как в обработчике, например, события click сделать асинхронный вызов после чего решить отменять ли дефолтное поведение

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

AbortController.

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


Интерфейс будет заблокирован, ожидая ответа на событие.

В том-то и дело, что нет.

только специально подготовленной.

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


Интерфейс будет заблокирован, ожидая ответа на событие.

В том-то и дело, что нет.

Мы навесили обработчик submit на форму, синхронно его не прервали, запрос ушел на сервер. В чем смысл его потом отменять, поздно же?

код завершился

С файберами он не "завершается", а приостанавливается.


запрос ушел на сервер

Не ушёл, так как событие ещё не доплыло до корня документа.

function* myFiber() {
        console.log('делаю работу')
        yield* subFiber1('декомпозирую работу')
        yield subPromise2('жду работу')
        yield [ subPromise4('параллелю работу'), subPromise5('параллелю работу') ]
        console.log('могу остановиться когда угодно')
}

async function fibersManager() {
        const myFiberInstance = myFiber()
        let result
        let param
        do {
                result = myFiberInstance.next(param)
                param = await (Array.isArray(result.value)
                    ? Promise.all(result.value)
                    : Promise.resolve(result.value)) // TODO: support subFibers
                if (нужно_прерваться) return;
        } while(!result.done) 
}

fibersManager()

В JS файберы уже давно есть, только их генераторами назвали.

То, что в JS — это stackless coroutines. А файберы — это stackfull coroutines. Попробуйте на генераторах реализовать это:


ondragstart = event => {
    if( servers.some( server => server.loadData().isAvailable ) ) {
        event.preventDefault()
    }
}
UFO just landed and posted this here

Да-да, отличная идея — делать запрос на сервер для того, чтобы определить можно ли перетаскивать элемент… А браузеру в это время что пользователю показывать-то?

Песочные часики возле курсора.

Так сам элемент-то при этом должен двигаться или нет? Ответ на этот вопрос должен быть дан независимо от формы курсора.

Да в принципе без разницы. Имейте ввиду, что сервер может быть локальным. А запрос может быть не только к серверу, но и, например, в воркер. Вы бы не к конкретному примеру докапывались, а смотрели бы шире на проблему — половина апи синхронные, половина асинхронные. И то и дело появляется необходимость вызывать асинхронные из синхронных.

Если "в принципе без разницы" — то делаем вот так и никакой проблемы нет:


ondragstart = event => {
    servers.some( server => server.loadData().isAvailable );
}

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

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

Так вы же пишете, что без разницы что там таскается?


На самом деле, проблема тут в том, что нельзя заменить перетаскиваемый объект посреди операции перетаскивания. Но это уже ограничение системного API: программе-получателю нужно знать, что именно ей перетащили, в момент отпускания кнопки мыши (а лучше еще раньше). Нет способа сказать графической оболочке: "тут пользователь объект потащил, но я пока не знаю что это такое".

function* ondragstart(event) {
    if(servers.some(yield server => server.loadData().isAvailable))
        event.preventDefault()
}

Вы это имели ввиду?

Вы это браузеру скормить попробуйте.

Промазал илдом, простите, с телефона набирал. Но я уверен, что вы поняли суть :).

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

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

preventDefault, dataTransfer и другие обработчики выше по дому вас ждать не будут.

Да, как вам написали выше, это сделано не зря. Делать корутиновый DOM не стали по разумным причинам. Но вы из своей любви к корутинам вполне можете написать обёртку и для ДОМа, организовав асинхронный рендеринг. Я к тому, что в ЖС для этого есть ВСЁ. Но асинхронно зажигать люминофор в пикселях никому не нужно, после всех хитрых изменений модели, когда вы уже будете готовы к самовыражению, ДОМ примет вас, синхронно отрисовав всю вашу сложнейшим асинхронным образом построенную модельку :). Поэтому DOM синхронный, так удобнее программировать. (Во всех мне известных графических операционных системах GUI-поток — единственный, никто не пытается переключать пиксели из двух потоков, с этим справится и один, а остальные потоки пусть только рассказывают ему, что изменилось в данных.)
Не слышал, почитал, спасибо. Не очень понял, что вы пытаетесь этим сказать :). Вам уже и обёртку почти написали, получается, оборачивать генераторы проще простого :).

Думаю и не поймёте, пока не попрограммируете на языке с поддержкой файберов.

Да понимаю, корутины — действительно, очень мощная и универсальная идея, я и сам кооперативной многозадачностью «болею», пытаясь нивелировать издержки менеджера вытесняющей многозадачности :). Я наколеночный язык даж пилю на досуге, в котором корутины пишутся без синтаксического мусора (мне для микроконтроллера нужно, но пока синтаксис отрабатываю на учебном транспиляторе в ЖС :)).

Но нужно понимать, что любая универсальная идея всегда пытается стать богом, захватить мозг и заставить вас думать, что ВСЁ является проекцией этой идеи :). Корутины — мощный инструмент, но ему вовсе не нужно быть абсолютно глобальным, есть принципиально синхронные вещи, над которыми корутины и надстраиваются.
Без JS? В 2019 году? Вам не жалко своих пользователей, у которых не будет валидации форм, навигации без перезагрузки страницы и других давно привычных вещей?
не будет валидации форм

Будет, есть же встроенная валидация через html-атрибуты


навигации без перезагрузки страницы

Если страница мало весит и быстро загружается с сервера, то в чем проблема? Зачем чинить то что не сломано?

Будет, есть же встроенная валидация через html-атрибуты
А в Safari оно уже работает?

Да. Сейчас сам проверил, валидация вызывается.

UFO just landed and posted this here
У моего банка клиент сделан на генерируемых сервером страницах, поэтому когда я в 5й раз открываю страницу со списком шаблонов платежей, я должен ждать несколько секунд пока сервер сгенерирует мне эту несчастную страницу, так что лучше уж JS и рендеринг страниц на стороне клиента с кешированием списков данных.
UFO just landed and posted this here
Фронт и бэк пишут разные люди.
Да, с текущими реактами и «модными» технологиями в нем, фронт будет тоже тормозить.
Но! Я уже не буду 5 секунд ждать пока бэк сгенерирует несчастную страницу со списком.

Ну да, теперь вы будете ждать 10 секунд пока эту страницу вам сгенерирует фронт...

UFO just landed and posted this here

Что мешает сделать валидацию и навигацию без перезагрузки страницы опциональной плюшкой сбоку, которая при включенном JS будет работать, а при отключенном JS «изящно деградировать» в «классический» сайт?

Я не знаю насколько здесь можно прикладывать картинки. Но по моему Backend за Svelte будет все равно сильно больше.
На всякий случай приложил код создания компонента в RiotJS 3ей версии, потому что в 4 они там начудили не по детски. сам Riot с компилятором тянет дополнительно 36кб.
компоненты разбиваются на файлы, можно скомпилировать на сервере и будет уже только .js подтягиваться. Я возможно офтоплю сильно и сравнение не слишком корректно, но просто я думаю что у RiotJS тоже компонентная архитектура, по крайней мере я ее себе так представляю.
<myform>
            <input type="number" ref="a" oninput={change}>
            <input type="number" ref="b" oninput={change}>

            <p>{opts.result}</p>

            var self = this;
            change = function() {
                var a = isNaN(parseInt(self.refs.a.value)) ? 0 : parseInt(self.refs.a.value);
                var b = isNaN(parseInt(self.refs.b.value)) ? 0 : parseInt(self.refs.b.value);

                opts.result = a + b;
                self.update();
            }
        </myform>

image
Sign up to leave a comment.

Articles