Комментарий @demimurych на видеоролик «youtubecom/watch?v=DQJXlih0voI» (ролик носит строго отрицательный характер и не рекомендуется в качестве обучающего материала)
Часть 1
Автор видео совершенно не разбирается в том, каким именно образом работают flex layout
Цифры используемые в видео, представляют собой частный (упрощенный) случай, расчета размеров флекс элементов, в рамках которого, большинство ключевых значений формулы расчета их размеров - сокращаются.
Совершенно неправильно говорить о том, что flex-basis это некий идеальный размер. Суть свойства flex-basis совершенно в другом.
Равно как и flex-grow (для случая заполнения свободного пространства и flex-shrink для сокращения) это не пропорциональные увеличения одного блока в отношения других блоков, так как получилось у автора видео.
Если у автора видео, будут попытки оправдать себя, я ему предлагаю решить простую (для тех кто понимает как работает flex layout) задачу:
Дано: блок шириной 500px. Блок содержит три элемента.
Каждому элементу задано свойство flex-basis: 20px;.
Каждому элементу задано свойство flex-grow: 1;
Первый блок из трех, содержит контент, для отображения которого требуется растянуть блок до 170px.
Вопрос - на сколько будут растянуты блоки 2 и 3. И почему оказались именно такие цифры.
Которые естественно совершенно не соответствуют тому, что описывает автор видео
После попытки посчитать эти цифры сразу становиться очевидным, что все то, что говорит автор видео является форменной чепухой, которая получила подтверждение в цифрах только благодаря тому, каким образом были выбраны начальные условия
ИГОГО.
Удалите это видео и не позорьтесь. А так же дайте себе труд познакомиться с настоящим алгоритмом расчета размера flex элементов и не множьте невежество.
Как на самом деле.
flex-basis - это не какой-то идеальный размер. Это набор базовых величин блоков, относительно которых начинается расчет для случаев, когда блоки должны быть увеличены или уменьшены. Более того, существует целый ряд пограничных случаев, когда контент блока, который заставил блок увеличиться в размерах больше чем flex-basis + flex-grow приводит к запуску расчета величины элементов, без подобного блока.
Базовый алгоритм, расчета того, каким образом заполняется свободное пространство (или уменьшается в случае потребности) выглядит следующим образом:
Размер свободного пространства = Размер контейнера - Сумма размеров содержащих им блоков.
При этом, в случае если flex-basis отличается от значения по умолчанию - то берется его значение в качестве размера блока, даже в том случае, если контент блока выходит за рамки flex-basis в этом суть flex-basis
После чего, берется сумма всех css свойств flex-grow. Если у нас три блока и каждый имеет flex-grow равный 1, то сумма будет три.
Если какой-то из блоков будет иметь отличный flex-grow - соотвественно и сумма измениться.
Далее размер свободного пространства делится на сумму учавствующих в расчете flex-grow. В нашем примере это три.
Полученная цифра в пикселях, будет являтся коэфициентом, который будет использован для увеличения блока, на величину flex-grow помноженное на рассчитанный коэффициент. Подчеркиваю - размер блока будет не выровнен по величине, но получит плюс к своему размеру.
То есть происходит очень простой подсчет, когда доступное свободное пространство, пропорционально делиться между всей суммой flex-grow для flex элементов. По этой причине, совершенно неважно, написали мы для трех элементов grow равным 1, или равным 100.
@AsForJavaScript
Часть 1
Автор видео совершенно не разбирается в том, каким именно образом работают flex layout
Цифры используемые в видео, представляют собой частный (упрощенный) случай, расчета размеров флекс элементов, в рамках которого, большинство ключевых значений формулы расчета их размеров - сокращаются.
Совершенно неправильно говорить о том, что flex-basis это некий идеальный размер. Суть свойства flex-basis совершенно в другом.
Равно как и flex-grow (для случая заполнения свободного пространства и flex-shrink для сокращения) это не пропорциональные увеличения одного блока в отношения других блоков, так как получилось у автора видео.
Если у автора видео, будут попытки оправдать себя, я ему предлагаю решить простую (для тех кто понимает как работает flex layout) задачу:
Дано: блок шириной 500px. Блок содержит три элемента.
Каждому элементу задано свойство flex-basis: 20px;.
Каждому элементу задано свойство flex-grow: 1;
Первый блок из трех, содержит контент, для отображения которого требуется растянуть блок до 170px.
Вопрос - на сколько будут растянуты блоки 2 и 3. И почему оказались именно такие цифры.
Которые естественно совершенно не соответствуют тому, что описывает автор видео
После попытки посчитать эти цифры сразу становиться очевидным, что все то, что говорит автор видео является форменной чепухой, которая получила подтверждение в цифрах только благодаря тому, каким образом были выбраны начальные условия
ИГОГО.
Удалите это видео и не позорьтесь. А так же дайте себе труд познакомиться с настоящим алгоритмом расчета размера flex элементов и не множьте невежество.
Как на самом деле.
flex-basis - это не какой-то идеальный размер. Это набор базовых величин блоков, относительно которых начинается расчет для случаев, когда блоки должны быть увеличены или уменьшены. Более того, существует целый ряд пограничных случаев, когда контент блока, который заставил блок увеличиться в размерах больше чем flex-basis + flex-grow приводит к запуску расчета величины элементов, без подобного блока.
Базовый алгоритм, расчета того, каким образом заполняется свободное пространство (или уменьшается в случае потребности) выглядит следующим образом:
Размер свободного пространства = Размер контейнера - Сумма размеров содержащих им блоков.
При этом, в случае если flex-basis отличается от значения по умолчанию - то берется его значение в качестве размера блока, даже в том случае, если контент блока выходит за рамки flex-basis в этом суть flex-basis
После чего, берется сумма всех css свойств flex-grow. Если у нас три блока и каждый имеет flex-grow равный 1, то сумма будет три.
Если какой-то из блоков будет иметь отличный flex-grow - соотвественно и сумма измениться.
Далее размер свободного пространства делится на сумму учавствующих в расчете flex-grow. В нашем примере это три.
Полученная цифра в пикселях, будет являтся коэфициентом, который будет использован для увеличения блока, на величину flex-grow помноженное на рассчитанный коэффициент. Подчеркиваю - размер блока будет не выровнен по величине, но получит плюс к своему размеру.
То есть происходит очень простой подсчет, когда доступное свободное пространство, пропорционально делиться между всей суммой flex-grow для flex элементов. По этой причине, совершенно неважно, написали мы для трех элементов grow равным 1, или равным 100.
@AsForJavaScript
🔥1
Комментарий @demimurych на видеоролик «youtubecom/watch?v=DQJXlih0voI» (ролик носит строго отрицательный характер и не рекомендуется в качестве обучающего материала)
Часть 2
Пример расчета.
Пусть ширина контейнера равна 400px
Пусть у нас будет три блока с свойствами:
Ширина блока 1 flex-basis = 100px (flex-grow:100) (flex-shrink=500)
Ширина блока 2 flex-basis = 50px (flex-grow:100) (flex-shrink=500)
Ширина блока 3 flex-basis = 70px (flex-grow:100) (flex-shrink=500)
То есть общая ширина трех блоков равна 100 + 50 + 70 и составит 220px
Тогда свободного пространства у нас осталось 400 — 220 = 180 px
Для каждого блока который имеет flex-grow выполнится следущая процедура:
180 (оставшееся место) / 300 (сумма значений всех flex-grow grow потока) * flex-grow элемента
Результат 60px
То есть, к каждому блоку добавится ровно 60 px вне зависимости от того, какого размера они были до этого.
И, наоборот, если размер контейнера у нас был 100px а размер элементов тот же,
выходит что 100 — 220 = — 120 не хватает для того чтобы разместить все блоки потока.
120 / 1500 (сумма значений flex-shrink всех элементов потока) * flex-shrink 500( в нашем случае он одинаковый для всех = 40
Поскольку у нас все блоки имеют одинаковое значение shrink то каждый блок уменьшиться ровно на 40 px
Блок 1 = 60
Блок 2 = 10
Блок 3 = 40
Так, я думаю, понятнее.
А ситуацию когда flex-basis вместе с flex-grow вышел за пределы расчетной длины - оставляю в качесстве домашнего задания. Потому как нужно учиться читать спецификацию. И если давать себе право учить людей - то учить людей тому что написано в спецификации, а не своим фантазиям.
Позорище.
@AsForJavaScript
Часть 2
Пример расчета.
Пусть ширина контейнера равна 400px
Пусть у нас будет три блока с свойствами:
Ширина блока 1 flex-basis = 100px (flex-grow:100) (flex-shrink=500)
Ширина блока 2 flex-basis = 50px (flex-grow:100) (flex-shrink=500)
Ширина блока 3 flex-basis = 70px (flex-grow:100) (flex-shrink=500)
То есть общая ширина трех блоков равна 100 + 50 + 70 и составит 220px
Тогда свободного пространства у нас осталось 400 — 220 = 180 px
Для каждого блока который имеет flex-grow выполнится следущая процедура:
180 (оставшееся место) / 300 (сумма значений всех flex-grow grow потока) * flex-grow элемента
Результат 60px
То есть, к каждому блоку добавится ровно 60 px вне зависимости от того, какого размера они были до этого.
И, наоборот, если размер контейнера у нас был 100px а размер элементов тот же,
выходит что 100 — 220 = — 120 не хватает для того чтобы разместить все блоки потока.
120 / 1500 (сумма значений flex-shrink всех элементов потока) * flex-shrink 500( в нашем случае он одинаковый для всех = 40
Поскольку у нас все блоки имеют одинаковое значение shrink то каждый блок уменьшиться ровно на 40 px
Блок 1 = 60
Блок 2 = 10
Блок 3 = 40
Так, я думаю, понятнее.
А ситуацию когда flex-basis вместе с flex-grow вышел за пределы расчетной длины - оставляю в качесстве домашнего задания. Потому как нужно учиться читать спецификацию. И если давать себе право учить людей - то учить людей тому что написано в спецификации, а не своим фантазиям.
Позорище.
@AsForJavaScript
Друзья, планируем трансляцию.
Находимся в режиме ожидания.
Как будет что-то конкретное, сразу отпишемся.
Находимся в режиме ожидания.
Как будет что-то конкретное, сразу отпишемся.
👍8
Друзья.
В 21:00 по МСК (20:00 по Киеву) планируем трансляцию с @demimurych.
Ждём всех желающих.)
Надеемся что в этот раз все получится.
В 21:00 по МСК (20:00 по Киеву) планируем трансляцию с @demimurych.
Ждём всех желающих.)
Надеемся что в этот раз все получится.
❤5👍2👀1
Позднее может выложим видео или будем выкладывать в YouTube.
Думаю там будет удобнее.
Просто пока у нас пробные попытки, но это уже, наверное, 5 пробная попытка)
Думаю там будет удобнее.
Просто пока у нас пробные попытки, но это уже, наверное, 5 пробная попытка)
As For JS
As For JS – Новая попытка.
Аудио, это отдельная часть. —
Начало общения.
Потом включили запись видеотрансляции.
Начало общения.
Потом включили запись видеотрансляции.
👍5
As For JavaScript Coalesce Expression - Nullish coalescing operator - ??
Abstract
О том, почему coalesce expression является идиотизмом притянутым в спецификацию идиотами не понимающими архитектуру языка, а так же о том как разработчики V8 реализовали эту парашу именно как парашу.
Что это такое ваше за Coalesce Expression - я забыл - напомни мне - я упырь
не волноваться, я тоже упырь и совершенно не понимаю как придумывают эти названия.
Потому вот документация и примеры:
Официальная спецификация ECMA
MDN
пример:
В чем проблема проверять и на null и на undefined одной конструкцией
Эта разница принципиальна для runtime. На основе этой информации RunTime может предпринимать совершенно разные шаги каким образом можно работать с нашим кодом. Очевидно, что идентификатор связанный с
По этой причине, Coalesce expression бесполезно так как включает в себя два пограничных случая, которые не пересекаются. Иными словами, если в Вашей программе Вы вынуждены проверять идентификатор на то может ли он быть связан в одной и той же ситуации с
Конечно если в Ваши задачи входит писать эффективный код. То есть код, который претендует на максимальную производительность.
Посмотрите на официальные API - если API должно вернуть обьект, но при этом что-то произошло, что не позволяет это сделать, то API всегда вернет null. Чем прямо сообщает RunTime - да я должен был вернуть обьект, но что-то пошло не так.
Байт код от V8 для Coalesce expression
Именно ради этого раздела я и затеял все это словоблудие.
JavaScript код:
Ldar - это загрузка содержимого регистра в регистр аккумулятора.
Регистр аккумулятора - это особенный уникальный регистр,
который существует в единственном числе в V8. Через него делаются практически все операции. */
на языке байткода V8 звучит как - если в регистре аккумулятора находится что-то
что является undefined или null то сделать переход к метке label1 */
Abstract
О том, почему coalesce expression является идиотизмом притянутым в спецификацию идиотами не понимающими архитектуру языка, а так же о том как разработчики V8 реализовали эту парашу именно как парашу.
Что это такое ваше за Coalesce Expression - я забыл - напомни мне - я упырь
не волноваться, я тоже упырь и совершенно не понимаю как придумывают эти названия.
Потому вот документация и примеры:
Официальная спецификация ECMA
MDN
пример:
var theThing;"
(theThing ?? "Yo");
// Если theThing связан с undefined или null результат вычисления выражения будет "Yo
В чем проблема проверять и на null и на undefined одной конструкцией
undefined - это primitive value которое устанавливается для идентификаторов созданных при помощи variable statement.null- это primitive value которое связывают с идентификатором который в прошлом или в будущем был/будет связан с обьектом, но в его текущем состоянии обьект не определен. То есть null - это обьект с нулевой структурой. Не путать с указателями из других языков.
Эта разница принципиальна для runtime. На основе этой информации RunTime может предпринимать совершенно разные шаги каким образом можно работать с нашим кодом. Очевидно, что идентификатор связанный с
undefined - это идентификатор поведение которого в будущем предсказать невозможно. Идентификатор связанный с null - в будущем будет обьектом или ранее использовался как обьект. По этой причине, Coalesce expression бесполезно так как включает в себя два пограничных случая, которые не пересекаются. Иными словами, если в Вашей программе Вы вынуждены проверять идентификатор на то может ли он быть связан в одной и той же ситуации с
null или undefined - то у Вас проблемы с вашим кодом, его архитектурой. Так как если Вы знаете что Ваш идентификатор будет связан с обьектом в будущем - он обязан быть про инициализирован как null, а не undefined. Конечно если в Ваши задачи входит писать эффективный код. То есть код, который претендует на максимальную производительность.
Посмотрите на официальные API - если API должно вернуть обьект, но при этом что-то произошло, что не позволяет это сделать, то API всегда вернет null. Чем прямо сообщает RunTime - да я должен был вернуть обьект, но что-то пошло не так.
Байт код от V8 для Coalesce expression
Именно ради этого раздела я и затеял все это словоблудие.
JavaScript код:
var theThing;byteCode V8:
(theThing ?? "Yo");
Ldar r0/* Регистр r0 это наш идентификатор theThing.
Ldar - это загрузка содержимого регистра в регистр аккумулятора.
Регистр аккумулятора - это особенный уникальный регистр,
который существует в единственном числе в V8. Через него делаются практически все операции. */
JumpIfUndefinedOrNull "label1"/* Это непосредственно операция ??,
на языке байткода V8 звучит как - если в регистре аккумулятора находится что-то
что является undefined или null то сделать переход к метке label1 */
Jump "label2"// безусловный переход к метке label2
label1:// метка label1 к которой происходит переход
LdaConstant [0]// загрузить в аккумулятор подготовленную константу. В нашем случае это будет ссылка на "Yo"
label2:// метка label2 к которой происходит переход
Этот же код без комментариев:
// Other code
Ldar r0Ничего не покоробило в логике этого кода?
JumpIfUndefinedOrNull "label1"
Jump "label2"
label1:
LdaConstant [0]
label2:
🔥3
Для того, чтобы наглядно показать о чем я говорю, я приведу еще один код, на этот раз для JavaScript кода, где вместо
Совершенно верно - в реализации для ?? (Coalesce) используется два перехода (
Что естественно отражается на производительности:
Напомню, что в текущих условиях, получить оптимизацию от turboFan вам нужно повторить выполнения одного и того же кода не менее
А как правильно
Правильно и наиболее эффективно, в случае V8 использовать максимально специфичные конструкции для ситуаций когда нам нужно что-то делать с логикой в зависимости от
Например, для ситуации когда мы хотим проверить произошла ли инициализация идентификатора или он все еще undefined:
Аналогичная история с
Всегда следует помнить о том, сколько стоят подобные оптимизации. Всегда следует отдавать отчет себе в том, что слова: вот
?? будем использовать &&:var theThing;
(theThing && "Yo");
а теперь тот же код в byteCode V8: Ldar r0
JumpIfToBooleanFalse "label1" // Это непосредственно операция && LdaConstant [0]
label1:
Теперь видна разница между реализацией ?? и &&? Совершенно верно - в реализации для ?? (Coalesce) используется два перехода (
JumpIfUndefinedOrNull и Jump "label2") , в отличии от && где использован только один переход. Что естественно отражается на производительности:
&& или || в среднем на 7% выполняется быстрее для кода, который не был оптимизирован TurboFan. В оптимизированном случае разницы нет.Напомню, что в текущих условиях, получить оптимизацию от turboFan вам нужно повторить выполнения одного и того же кода не менее
1200 раз, а в некоторых случаях гораздо больше. То есть в современных реализиях, большая часть нашего кода не оптимизируется вообще. В следствии чего те самые 7% уже не кажутся такими несущественными.А как правильно
Правильно и наиболее эффективно, в случае V8 использовать максимально специфичные конструкции для ситуаций когда нам нужно что-то делать с логикой в зависимости от
null или undefined Например, для ситуации когда мы хотим проверить произошла ли инициализация идентификатора или он все еще undefined:
var theThing;
theThing === undefined && "Yo";
Да, синтаксис содержит слишком много букаф. Но посмотрите какой вкусный код генерирует для этого V8: Ldar r0
TestUndefined
JumpIfFalse "label1" LdaConstant [0]
label1:
V8 в своем bytcode имеет особую инструкцию проверки именно на undefined - TestUndefined и соответственно мы видим только один переход.Аналогичная история с
null
var theThing;
theThing === null && "Yo";
V8 код: Ldar r0
TestNull
JumpIfFalse "label1" LdaConstant [0]
label1:
Или так:vat theThing;
theThing ||= 1; // но следует четко отдавать себе отчет в том, с чем именно связано это условие
Вместо ИГОГО:Всегда следует помнить о том, сколько стоят подобные оптимизации. Всегда следует отдавать отчет себе в том, что слова: вот
|| на 7% быстрее чем ?? говорит именно о 7% выигрыше в затратах на реализацию именно этих конструкций, которые на фоне прочих проблем программы могут оказаться ничтожными. То есть настолько бесполезными, что не будет существенной разницы - хорошую вы выбрали конструкцию или плохую, но фоне прочих проблем кода, выигрыш не будет ощутим.🔥5💯2👍1
Обьявление:
В комментариях к этому сообщению, можно задать вопрос - а что будет быстрее это или это?
Например: Что быстрее var let или const?
Или
А как влияет на производительность создание идентификаторов? Если я создаю сотни промежуточных идентификаторов - это плохо или ничего страшного?
Или
любой другой вопрос относящийся к JavaScript или смежным темам.
Я прочитаю вопрос и если смогу на него ответить - то обязательно дам развернутый ответ.
Мне это нужно для того, чтобы нагружать голову, поскольку я сейчас очень много лежу и у меня появилось много времени для того, чтобы что-то обдумать. А без темы, я скатываюсь в сторону текущих проблем о которых пока думать бессмысленно.
В комментариях к этому сообщению, можно задать вопрос - а что будет быстрее это или это?
Например: Что быстрее var let или const?
Или
А как влияет на производительность создание идентификаторов? Если я создаю сотни промежуточных идентификаторов - это плохо или ничего страшного?
Или
любой другой вопрос относящийся к JavaScript или смежным темам.
Я прочитаю вопрос и если смогу на него ответить - то обязательно дам развернутый ответ.
Мне это нужно для того, чтобы нагружать голову, поскольку я сейчас очень много лежу и у меня появилось много времени для того, чтобы что-то обдумать. А без темы, я скатываюсь в сторону текущих проблем о которых пока думать бессмысленно.
👍2👀1