Какой цикл в JS самый быстрый
Из серии занятного. Наткнулся на занятную статью, где описывается какой цикл в JS самый быстрый. Если коротко, то обычный for.
Было уже много бенчмарков на тему того такой цикл быстрее чего-то вроде
А всё почему? Потому чтомы постоянно обращаемся к arr.length, что по своей сути — геттер, а геттеры всегда работают медленнее обычного обращения к переменной. Тогда можно прибегнуть к хаку, когда длина массива вычисляется заранее и присваивается к переменной лишь единожды:
Но вот что автор не упоминает, так это то, что можно избежать такой записи и использовать просто обратный цикл:
Таким образом мы обратимся к длине массива только единожды и максимально выиграем время.
Если честно, не могу придумать практического примера, где это было бы реально полезно, но если вы безудержно гоняетесь за скоростью выполнения кода где-нибудь на литкоде, то может быть интересно. На практике я такие конструкции обычно не вижу, так как разница не значительная, но шутка ли, такой вопрос реально спрашивали на собесе у одного из моих менти.
Спасибо за прочтение, это важно для меня ❤️
#theory #javascript
Из серии занятного. Наткнулся на занятную статью, где описывается какой цикл в JS самый быстрый. Если коротко, то обычный for.
Было уже много бенчмарков на тему того такой цикл быстрее чего-то вроде
forEach
или for..in
и for..of
, так что это мы возьмем за данное. А вот что действительно интересно, так это то, что стандартный вариант записи цикла for
не является самым эффективным:for (let i = 0; i < arr.length; i++) {
// какой-то код
}
А всё почему? Потому что
const arrLength = arr.length;
for (let i = 0; i < arrLength ; i++) {
// какой-то код
}
Но вот что автор не упоминает, так это то, что можно избежать такой записи и использовать просто обратный цикл:
for (let i = arr.length - 1; i >= 0 ; i--) {
// какой-то код
}
Таким образом мы обратимся к длине массива только единожды и максимально выиграем время.
Если честно, не могу придумать практического примера, где это было бы реально полезно, но если вы безудержно гоняетесь за скоростью выполнения кода где-нибудь на литкоде, то может быть интересно. На практике я такие конструкции обычно не вижу, так как разница не значительная, но шутка ли, такой вопрос реально спрашивали на собесе у одного из моих менти.
Спасибо за прочтение, это важно для меня ❤️
#theory #javascript
👍62❤16🔥12🐳2✍1
This media is not supported in your browser
VIEW IN TELEGRAM
Что такое префиксные свойства и зачем они нужны?
Префиксные свойства — это особые свойства CSS, которые дублируют некоторые стандартные CSS свойства для обеспечения совместимости с различными браузерами.
Изначально префиксные свойства были придуманы для одной простой вещи — кроссбраузерной вёрстки. Но в последнее время идет активное обсуждение отказа от этого подхода и выравнивания названия свойств между браузерами, поэтому это уже не так актуально.
Что интереснее, префиксные свойства позволяют работать с экспериментальными фичами браузера, например изменять скроллбары:
Также есть специальные инструменты, которые называются автопрефиксерами. Такие утилиты автоматически добавляют все необходимые префиксные свойства к вашему CSS коду, поэтому многие даже не задумываются о том, что префиксные свойства в целом существуют, так как эти инструменты уже давно входят в стандартную поставку многих шаблонов и фреймворков.
В целом, префиксные свойства в современном мире — это экспериментальная экзотика. Работать с ними так, как предполагалось изначально, вы уже вряд ли будете, так как все вопросы кроссбраузерности стилей уже давно решаются автоматически.
Спасибо за прочтение, это важно для меня ❤️
Пример с кастомными скроллбарами
#web #theory #web #design
Префиксные свойства — это особые свойства CSS, которые дублируют некоторые стандартные CSS свойства для обеспечения совместимости с различными браузерами.
Изначально префиксные свойства были придуманы для одной простой вещи — кроссбраузерной вёрстки. Но в последнее время идет активное обсуждение отказа от этого подхода и выравнивания названия свойств между браузерами, поэтому это уже не так актуально.
Что интереснее, префиксные свойства позволяют работать с экспериментальными фичами браузера, например изменять скроллбары:
/* ширина скроллбара */
::-webkit-scrollbar {
width: 10px;
}
/* задний фон */
::-webkit-scrollbar-track {
background: #f1f1f1;
}
/* ползунок */
::-webkit-scrollbar-thumb {
background: #888;
}
/* ползунок при наведении */
::-webkit-scrollbar-thumb:hover {
background: #555;
}
Также есть специальные инструменты, которые называются автопрефиксерами. Такие утилиты автоматически добавляют все необходимые префиксные свойства к вашему CSS коду, поэтому многие даже не задумываются о том, что префиксные свойства в целом существуют, так как эти инструменты уже давно входят в стандартную поставку многих шаблонов и фреймворков.
В целом, префиксные свойства в современном мире — это экспериментальная экзотика. Работать с ними так, как предполагалось изначально, вы уже вряд ли будете, так как все вопросы кроссбраузерности стилей уже давно решаются автоматически.
Спасибо за прочтение, это важно для меня ❤️
Пример с кастомными скроллбарами
#web #theory #web #design
🔥20👍11❤5🐳3🤓1
Ссылочные типы и типы значений в JavaScript
Перед прочтением я рекомендую пробежаться по ещё одному посту из канала о том, какие типы данных есть в JavaScript.
В языке JavaScript, типы данных можно разделить на две большие группы:
Типы значений — примитивы — данные, что языком воспринимаются по конкретному значению. Например, строка
Ссылочные типы — типы данных, которые интерпретатор языка воспринимает по ссылке. Переменная больше не хранит в себе конкретное значение, зато сохраняет ссылку на место в памяти, где это самое значение хранится.
К ссылочным типам данных относятся:
— объекты
— массивы
— функции
Казалось бы, а какая разница? Но разница заключается в способе хранения и передачи этих самых данных через переменные, а так же в способе взаимодействия с ними.
Типы значений потому и называются примитивами, так как максимально просты и предсказуемы в этом плане. Такие переменные, по сути, представляют собой просто некоторую последовательность байт. При сравнении таких переменных, всё, что нужно сделать языку — посимвольно сравнить цепочки байт и выдать результат.
Ссылочные же типы, в свою очередь, могут вызвать много проблем при работе с ними. Переменная сохраняет под собой не конкретную последовательность байт, а, как и говорилось выше, лишь некоторую ссылку на ячейку памяти, в которой нужная для нас информация (байты) и записаны. Из ключевых особенностей таких типов данных сразу же приходит на ум их копирование, с чем часто возникают проблемы у новичков и не только.
Например, в этом случае мы получаем не ожидаемый для многих вывод в консоль:
Связано это со спецификой работы
Более подробно о понятии глубокого копирования я расскажу в отдельном посте. Он будет одним из следующих.
#javascript #data #theory #useful
Перед прочтением я рекомендую пробежаться по ещё одному посту из канала о том, какие типы данных есть в JavaScript.
В языке JavaScript, типы данных можно разделить на две большие группы:
Типы значений — примитивы — данные, что языком воспринимаются по конкретному значению. Например, строка
"Hello, World!"
или число 5
.Ссылочные типы — типы данных, которые интерпретатор языка воспринимает по ссылке. Переменная больше не хранит в себе конкретное значение, зато сохраняет ссылку на место в памяти, где это самое значение хранится.
К ссылочным типам данных относятся:
— объекты
— массивы
— функции
Казалось бы, а какая разница? Но разница заключается в способе хранения и передачи этих самых данных через переменные, а так же в способе взаимодействия с ними.
Типы значений потому и называются примитивами, так как максимально просты и предсказуемы в этом плане. Такие переменные, по сути, представляют собой просто некоторую последовательность байт. При сравнении таких переменных, всё, что нужно сделать языку — посимвольно сравнить цепочки байт и выдать результат.
Ссылочные же типы, в свою очередь, могут вызвать много проблем при работе с ними. Переменная сохраняет под собой не конкретную последовательность байт, а, как и говорилось выше, лишь некоторую ссылку на ячейку памяти, в которой нужная для нас информация (байты) и записаны. Из ключевых особенностей таких типов данных сразу же приходит на ум их копирование, с чем часто возникают проблемы у новичков и не только.
Например, в этом случае мы получаем не ожидаемый для многих вывод в консоль:
const obj = {
name: "Denis",
address: {
street: 'Lenina',
apartment: 10
}
}
const clone = Object.assign({}, obj)
obj.address.street = 'Pushkina'
console.log(clone.address.street) // Pushkina
Связано это со спецификой работы
Object.assign
и особенностями копирования вложенных объектов. В этом случае копирование считается неглубоким, поэтому скопированный объект также изменяется.Более подробно о понятии глубокого копирования я расскажу в отдельном посте. Он будет одним из следующих.
#javascript #data #theory #useful
🔥20👍11❤4🐳2
Понятие глубокого копирования
В JavaScript’e, да и в других языках, часто встречаются ссылочные типы данных, вокруг которых строится одновременно много самых различных полезных хаков и не очень полезных проблем.
Понятие глубокого копирования, на самом-то деле, достаточно простое. Рассмотрим код:
В данном случае мы получим не ожидаемый для многих вывод в консоль. Связано это с тем, что
На данный момент в памяти у нас есть три объекта:
И, на самом деле,
Для решения этой проблемы можно воспользоваться рекурсивными алгоритмами на основе того же
Тут вывод уже будет ожидаемым, поскольку мы вручную пересоздали ссылку на объект в поле
Подобные проблемы и решения также можно увидеть и в контексте массивов.
#javascript #theory #data
В JavaScript’e, да и в других языках, часто встречаются ссылочные типы данных, вокруг которых строится одновременно много самых различных полезных хаков и не очень полезных проблем.
Понятие глубокого копирования, на самом-то деле, достаточно простое. Рассмотрим код:
const obj = {
name: "Denis",
address: {
street: 'Lenina',
apartment: 10
}
}
const clone = Object.assign({}, obj)
obj.address.street = 'Pushkina'
console.log(clone.address.street) // Pushkina
В данном случае мы получим не ожидаемый для многих вывод в консоль. Связано это с тем, что
Object.assign
не осуществляет глубокое копирование.На данный момент в памяти у нас есть три объекта:
— obj
— clone
— obj.address
И, на самом деле,
obj.address === clone.address
. Этот вложенный объект для obj
и clone
на самом деле — один и тот же объект в памяти, поскольку Object.assign
полностью скопировал только примитивы, а поле address
просто перенёс по ссылке. Для решения этой проблемы можно воспользоваться рекурсивными алгоритмами на основе того же
Object.assign
для глубокого копирования объекта. Или же, если мы точно знаем какие поля будут в нашем объекте, можем воспользоваться следующим синтаксисом через spread
оператор:const obj = {
name: "Denis",
address: {
street: "Lenina",
apartment: 10
}
};
const clone = {
...obj,
address: {
...obj.address
}
};
obj.address.street = "Pushkina";
console.log(clone.address.street); // Lenina
Тут вывод уже будет ожидаемым, поскольку мы вручную пересоздали ссылку на объект в поле
address
и заполнили его значениями из исходного объекта. Однако стоит быть осторожным при копировании объектов таким способом и помнить, что spread
оператор не копирует геттеры и сеттеры, как и Object.assign
.Подобные проблемы и решения также можно увидеть и в контексте массивов.
#javascript #theory #data
🔥20👍11❤3🤯3🐳2🤔1
Способы клонирования объектов
В JavaScript объекты являются ссылочным типом данных, из-за чего есть много приколов, но и проблем не меньше. Перед прочтением этого поста лучше прочитать о понятии нечистого объекта. И в этом посте мы разберёмся с тем как всё таки скопировать объект.
Итак, начать стоит с того, что нечистый объект невозможно скопировать. Именно поэтому это понятие так важно в теме копирования.
И переходя к способам, можно сказать, что их несколько основных:
1. Использование синтаксиса Spread оператора
3. Через методы глобального объекта
4. Библиотека Lodash
Начать можно с конца, потому что изобретать велосипед не всегда есть смысл. В библиотеке Lodash есть несколько функций для копирования объектов, полностью протестированных и хорошо оптимизированных.
Но так же можно и использовать глобальный объект
Нюанс заключается лишь в том, что этот способ подходит только для самых примитивных объектов. Такой способ скопирует только примитивы, пропуская типа данных типа
Более интересным вариантом является относительно новый синтаксис
Тут интересным нюансом является так же то, что
И финальным, зато самым стабильным, как мне кажется, способом, является использование
Не забывайте, что способы с использованием
Ну и, конечно же, каждый из способов можно использовать в зависимости от места и задачи, поэтому полезно знать про особенности каждого из них. Хотя в большинстве случаев уже классического
#javascript #data #theory
В JavaScript объекты являются ссылочным типом данных, из-за чего есть много приколов, но и проблем не меньше. Перед прочтением этого поста лучше прочитать о понятии нечистого объекта. И в этом посте мы разберёмся с тем как всё таки скопировать объект.
Итак, начать стоит с того, что нечистый объект невозможно скопировать. Именно поэтому это понятие так важно в теме копирования.
И переходя к способам, можно сказать, что их несколько основных:
1. Использование синтаксиса Spread оператора
2. Object.assign
3. Через методы глобального объекта
JSON
4. Библиотека Lodash
Начать можно с конца, потому что изобретать велосипед не всегда есть смысл. В библиотеке Lodash есть несколько функций для копирования объектов, полностью протестированных и хорошо оптимизированных.
Но так же можно и использовать глобальный объект
JSON
, а конкретно его методы stringify
и parse
. Логика такая, что первый метод переводит объект в JSON
строку, а второй полностью воссоздаёт его из JSON
строки:const obj = {
name: "Denis"
}
const clone = JSON.parse(JSON.stringify(obj))
Нюанс заключается лишь в том, что этот способ подходит только для самых примитивных объектов. Такой способ скопирует только примитивы, пропуская типа данных типа
Symbol
, геттеры, сеттеры, методы и всё, что сложнее строки, числа или boolean
. Но для некоторых случаев такого способа более чем достаточно.Более интересным вариантом является относительно новый синтаксис
spread
оператора, который копирует объект примерно так же как и вышеописанный способ. Spread оператор работает только с итерабельными объектами и процесс копирования тогда выглядит вот так:const obj = {
name: "Denis"
}
const clone = { ...obj }
Тут интересным нюансом является так же то, что
spread
оператор не копирует геттеры и сеттеры, а также осуществляет лишь поверхностное копирование. Но всё же этот способ прекрасно подойдет для плоских объектов без лишней вложенности.И финальным, зато самым стабильным, как мне кажется, способом, является использование
Object.assign
. Это метод объекта, который доставляет свойства из одного объекта в другой. Так же, как и при использовании spread
оператора, геттеры и сеттеры перенесены не будут. Выглядеть это может, например, так: const obj = {
name: "Denis"
}
const clone = Object.assign({}, obj)
Не забывайте, что способы с использованием
spread
оператора и Object.assign
не производят глубокого копирования. Это очень важно, ведь вложенные объекты не будут по настоящему скопированы, а лишь перенесутся по ссылке. Из-за этого вы можете по ошибке мутировать какие-то данные, что в перспективе приведет к непредвиденным ошибкам.Ну и, конечно же, каждый из способов можно использовать в зависимости от места и задачи, поэтому полезно знать про особенности каждого из них. Хотя в большинстве случаев уже классического
spread
оператора будет вполне достаточно.#javascript #data #theory
👍25🔥6❤2🐳2✍1💯1
Чем border отличается от outline?
Оба эти свойства отвечают за стилизацию контура элемента, но у них есть много различий:
1. Свойство
2. Разные возможности стилизации —
3. Семантическая разница —
Не смотря на то, что обводку и тем и другим способом можно создать визуально одинаковой, всё же используются свойства совсем для разных задач.
Спасибо за прочтение, это важно для меня ❤️
#theory #web
Оба эти свойства отвечают за стилизацию контура элемента, но у них есть много различий:
1. Свойство
border
являются частью блочной модели элемента. Это значит, что изменение толщины border
будет влиять и на размеры самого элемента, которому принадлежит обводка. outline
, в свою очередь, никак не влияет на расположение и размеры элементов в вёрстке.2. Разные возможности стилизации —
border
является составным (обобщающим) свойством, то есть представляет собой короткую запись для свойств border-top
, border-left
и других. outline
же нельзя задать индивидуальным для каждой из 4-х сторон.3. Семантическая разница —
border
обычно используется для создания постоянной видимой границы элемента, в то время как outline
используется для выделения элемента без влияния на верстку с целью повышения доступности.Не смотря на то, что обводку и тем и другим способом можно создать визуально одинаковой, всё же используются свойства совсем для разных задач.
Спасибо за прочтение, это важно для меня ❤️
#theory #web
❤32👍10🔥3🐳2
Что такое всплытие
Чтобы понять что такое всплытие (hoisting), необходимо хотя бы на пальцах понять как интерпретируется код JavaScript.
Можно воспринимать это так, что интерпретация происходит в два шага:
1. Интерпретатор пробегает по всему файлу не выполняя его, а лишь проверяя на синтаксические ошибки, инициализируя все переменные.
2. Интерпретатор проходит по коду и выполняет его.
Рассмотрим конкретный пример:
В коде выше мы объявляем две примитивные функции и пытаемся получить к ним доступ ещё до объявления. Функция
Связано это в первую очередь со способом объявления этих функций.
Функция
Всплытие, по сути — это процесс, в котором интерпретатор JavaScript позволяет некоторым переменным «всплывать» в начало области видимости. Это означает, что доступны они будут ещё до фактического объявления в коде во всей области видимости.
Работает это не только с функциями, вот ещё один пример:
Переменная
Переменная
Из этого кода должно быть понятно. Тот случай, когда проще показать, чем объяснить.
Спасибо за прочтение, это важно для меня
#javascript #theory #web
Чтобы понять что такое всплытие (hoisting), необходимо хотя бы на пальцах понять как интерпретируется код JavaScript.
Можно воспринимать это так, что интерпретация происходит в два шага:
1. Интерпретатор пробегает по всему файлу не выполняя его, а лишь проверяя на синтаксические ошибки, инициализируя все переменные.
2. Интерпретатор проходит по коду и выполняет его.
Рассмотрим конкретный пример:
sum(2, 5); // 7
substract(5, 4); // ReferenceError
function sum(a, b) {
return a + b;
}
const substract = function(a, b) {
return a - b;
}
В коде выше мы объявляем две примитивные функции и пытаемся получить к ним доступ ещё до объявления. Функция
sum
возвращает ожидаемый результат, несмотря на то, что вызвана она до того, как объявлена. Вызов же функции substract
выбрасывает ошибку. Связано это в первую очередь со способом объявления этих функций.
sum
объявлена через Function declaration, именно поэтому вызов функции до её объявления работает корректно.Функция
substract
объявлена через Function expression, а такие функции не всплывают.Всплытие, по сути — это процесс, в котором интерпретатор JavaScript позволяет некоторым переменным «всплывать» в начало области видимости. Это означает, что доступны они будут ещё до фактического объявления в коде во всей области видимости.
Работает это не только с функциями, вот ещё один пример:
console.log(name); // undefined
var name = 'Denis';
console.log(name); // Denis
console.log(channel); // ReferenceError
const channel = 'progway';
console.log(channel); // progway
Переменная
channel
не всплыла, из-за чего мы получили ошибку при обращении до объявления. Всплывают только переменные, объявленые через ключевое слово var
. Подробнее о ключевых словах для объявления переменной я писал тут.Переменная
name
всплыла, из-за чего ещё на первой строчке мы смоги получить к ней доступ без ошибки. Тут есть нюанс: мы получили undefined
. Чтобы понять почему, рассмотрим как примерно выглядит этот код после первой стадии интерпретации:// инициализировали значение
// но значение еще не записали
var name;
// получаем доступ
console.log(name);
// присваиваем значение
name = 'Denis';
Из этого кода должно быть понятно. Тот случай, когда проще показать, чем объяснить.
Спасибо за прочтение, это важно для меня
#javascript #theory #web
👍43❤7🔥7🐳3
Стрелочные функции или обычные?
У меня уже было несколько постов о сравнении разных способов создания функций, но сегодня я хочу их окончательно сравнить.
Итак, ещё раз: Чем отличается стрелочная функция от функции, объявленной ключевым словом
— Синтаксис
— У стрелочных функций нет своего контекста this
— Стрелочные функции не всплывают, в отличии от Function Declaration
— У стрелочных функций нет доступа к псевдомассиву arguments
— Со стрелочными функциями нельзя использовать оператор new
— В стрелочных функциях нет возможности дублировать названия переменных
И, по сути, кажется, что стрелочная функция — просто более упрощенная версия обычной функции. Вам не кажется, так и есть)
Обычные функции более обширны в своём применении, но чем они платят за это?
1. Как минимум — скоростью обработки, ведь стрелочные функции создаются в среднем в 10 раз быстрее, что в случае с нагруженными проектами на слабых устройствах может вам экономить драгоценные миллисекунды JavaScript рантайма
2. Также стоит учитывать, что стрелочные функции максимально упрощены по отношению к обычным функциям, не имеют замкнутого контекста и прочих фишек, а, следовательно, и памяти также занимают на порядки меньше
3. Синтаксис субъективно более быстрый и удобный к написанию. Стрелочные функции можно красиво использовать в качестве callback-ов, а визуальная простота такого кода упрощает его чтение и понимание.
4. Более удобная типизация в случае использования отдельных типов:
В совокупности, все эти факты делают меня большим любителем стрелочных функций. Я их использую абсолютно везде, где это только возможно. Для меня крайне важен параметр производительности в разработке UI, и я, кажется, пытаюсь вытащить лишние миллисекунды уже откуда угодно.
Правда, касательно производительности стоит понимать, что какой-то значимый эффект мы можем получить только на большой выборке. Если речь идет о создании порядка сотни или даже тысячи функций, то никакой разницы по производительности вы не заметите. Нужны уже более экзотичные кейсы, например, когда мы динамически создаём много уникальных callback-ов для отрисовки большого списка в React.
Спасибо за прочтение, это важно для меня ❤️
#web #theory
У меня уже было несколько постов о сравнении разных способов создания функций, но сегодня я хочу их окончательно сравнить.
Итак, ещё раз: Чем отличается стрелочная функция от функции, объявленной ключевым словом
function
?— Синтаксис
— У стрелочных функций нет своего контекста this
— Стрелочные функции не всплывают, в отличии от Function Declaration
— У стрелочных функций нет доступа к псевдомассиву arguments
— Со стрелочными функциями нельзя использовать оператор new
— В стрелочных функциях нет возможности дублировать названия переменных
И, по сути, кажется, что стрелочная функция — просто более упрощенная версия обычной функции. Вам не кажется, так и есть)
Обычные функции более обширны в своём применении, но чем они платят за это?
1. Как минимум — скоростью обработки, ведь стрелочные функции создаются в среднем в 10 раз быстрее, что в случае с нагруженными проектами на слабых устройствах может вам экономить драгоценные миллисекунды JavaScript рантайма
2. Также стоит учитывать, что стрелочные функции максимально упрощены по отношению к обычным функциям, не имеют замкнутого контекста и прочих фишек, а, следовательно, и памяти также занимают на порядки меньше
3. Синтаксис субъективно более быстрый и удобный к написанию. Стрелочные функции можно красиво использовать в качестве callback-ов, а визуальная простота такого кода упрощает его чтение и понимание.
4. Более удобная типизация в случае использования отдельных типов:
const foo: FooFunc = () => {}
В совокупности, все эти факты делают меня большим любителем стрелочных функций. Я их использую абсолютно везде, где это только возможно. Для меня крайне важен параметр производительности в разработке UI, и я, кажется, пытаюсь вытащить лишние миллисекунды уже откуда угодно.
Правда, касательно производительности стоит понимать, что какой-то значимый эффект мы можем получить только на большой выборке. Если речь идет о создании порядка сотни или даже тысячи функций, то никакой разницы по производительности вы не заметите. Нужны уже более экзотичные кейсы, например, когда мы динамически создаём много уникальных callback-ов для отрисовки большого списка в React.
Спасибо за прочтение, это важно для меня ❤️
#web #theory
👍49❤12🔥4🐳4🤬1
Селектор по атрибуту
Помимо обычных селекторов по классу, элементу, идентификатору, в CSS есть ещё много способов написать более конкретный селектор. Мне очень нравятся варианты селекторов по атрибуту.
Селектор по атрибуту — это дополнительная часть селектора, которая смотрит на любой атрибут тега. Для примера рассмотрим вёрстку:
Как выбрать все кнопки типа
Или же
В нашем случае, записи идентичны. Подобным же образом можно выбрать, например, все пустые ссылки на странице:
Ну и, соответсвенно, этот селектор может быть составным с другими селекторами:
Этот селектор выберет ссылку на нашей импровизированной странице.
Также важно сказать, что можно написать селектор не только по полному совпадению значения. Можно также найти, например, подстроку в строке, да и вообще там достаточно много операторов. Например в вёрстке:
Можно выбрать ссылку следующим селектором:
Обратите внимание на то, что вместо обычного равенства я использовал запись с тильдой:
Этот оператор находит слово внутри строки, где слова разделены пробелами.
Подробнее обо всех таких операторах можно прочитать на доке, там очень интересно и наглядно, советую.
#web #theory #useful
Помимо обычных селекторов по классу, элементу, идентификатору, в CSS есть ещё много способов написать более конкретный селектор. Мне очень нравятся варианты селекторов по атрибуту.
Селектор по атрибуту — это дополнительная часть селектора, которая смотрит на любой атрибут тега. Для примера рассмотрим вёрстку:
<main class="content">
<button type="submit">Отправить форму</button>
<a href="#">Пустая строка</a>
</main>
Как выбрать все кнопки типа
submit
на странице? Всё просто, нужно использовать специальный селектор по атрибуту. Выглядеть он будет так:button[type=submit]
Или же
button[type="submit"]
В нашем случае, записи идентичны. Подобным же образом можно выбрать, например, все пустые ссылки на странице:
a[href="#"]
Ну и, соответсвенно, этот селектор может быть составным с другими селекторами:
.content button[type="submit"] ~ a[href="#"]
Этот селектор выберет ссылку на нашей импровизированной странице.
Также важно сказать, что можно написать селектор не только по полному совпадению значения. Можно также найти, например, подстроку в строке, да и вообще там достаточно много операторов. Например в вёрстке:
<main class="content">
<a href="#" rel="noopener noreferrer">Защищённая ссылка</a>
</main>
Можно выбрать ссылку следующим селектором:
a[rel~="noreferrer"]
Обратите внимание на то, что вместо обычного равенства я использовал запись с тильдой:
~=
.Этот оператор находит слово внутри строки, где слова разделены пробелами.
Подробнее обо всех таких операторах можно прочитать на доке, там очень интересно и наглядно, советую.
#web #theory #useful
👍24❤4🔥4🐳3
Преобразование унарным плюсом
Является ли преобразование унарным плюсом самым быстрым способом преобразования строки в число?
Если коротко давать ответ: да, является. Но не всё так однозначно.
Преобразование унарным плюсом, то есть записью
действительно является сравнительно более быстрым способом преобразования строки в число, чем при использовании глобальных функций
Кроме того, мы не всегда можем получить ожидаемый результат в, казалось бы, самых простых кейсах, например:
В этом случае, то, каким образом работает
Использование унарным плюсом зачастую можно считать плохой практикой и сделать выбор в пользу глобальных функций, не смотря на то, что унарный плюс работает действительно быстрее. Правда, с оговоркой, что быстрее, но не значительно. Разницу в производительности можно заметить только на невероятно больших данных.
Использование же
Кстати, ещё можно преобразовать строку к числу при использовании глобального конструктора числа
Но такой способ будет работать дольше, чем
В своей практике, я использую только глобальные функции для преобразования строки к числу. И вам советую.
#web #javascript #data
Является ли преобразование унарным плюсом самым быстрым способом преобразования строки в число?
Если коротко давать ответ: да, является. Но не всё так однозначно.
Преобразование унарным плюсом, то есть записью
const string = '5'
const number = +string // 5
действительно является сравнительно более быстрым способом преобразования строки в число, чем при использовании глобальных функций
parseInt
или parseFloat
, но стоит помнить, что такая запись может привести к неожиданным результатам, если строка содержит некорректные символы. Кроме того, мы не всегда можем получить ожидаемый результат в, казалось бы, самых простых кейсах, например:
const string = ""
+string // 0
parseInt(string) // NaN
В этом случае, то, каким образом работает
parseInt
, мне кажется более ожидаемым и правильным.Использование унарным плюсом зачастую можно считать плохой практикой и сделать выбор в пользу глобальных функций, не смотря на то, что унарный плюс работает действительно быстрее. Правда, с оговоркой, что быстрее, но не значительно. Разницу в производительности можно заметить только на невероятно больших данных.
Использование же
parseInt
и parseFloat
даёт более ожидаемый результат и более наглядно. При беглом просмотре кода унарный плюс можно и вовсе не заметить, чего не скажешь о вызове полноценной функции.Кстати, ещё можно преобразовать строку к числу при использовании глобального конструктора числа
Number
:const string = "123"
const number = Number(string) // 123
Но такой способ будет работать дольше, чем
parseInt
и parseFloat
.В своей практике, я использую только глобальные функции для преобразования строки к числу. И вам советую.
#web #javascript #data
👍24🔥7🐳3❤2
Стили именования переменных
Я часто использую такие понятия, как
Вероятно, я что-то забыл, но тут точно собраны самые основные стили наименований.
Спасибо за прочтение, это важно для меня ❤️
Я часто использую такие понятия, как
pascal case
или camel case
, но внезапно понял, что они очевидны не для всех. Оставляю небольшую шпаргалку со всеми стилями именования: // camel case
const name = "progway"
const getChannelName = () => name
const publicationStatus = ...
// pascal case
const Name = "progway"
const GetChannelName = () => Name
const PublicationStatus = ...
// snake case
const name = "progway"
const get_channel_name = () => name
const publication_status = ...
// flat case
const name = "progway"
const getchannelname = () => name
const publicationstatus = ...
const hashtag = "#iloveit"
// train case (HTTP заголовки)
Access-Control-Allow-Origin
Content-Length
Content-Type
Cache-Control
// kebab case (css свойства)
font-size
background-color
grid-template-columns
Вероятно, я что-то забыл, но тут точно собраны самые основные стили наименований.
Спасибо за прочтение, это важно для меня ❤️
👍40❤13🔥5🐳4
Метод массива toSorted
Относительно новые фишки языка уже просачиваются на собеседования, поэтому ближайшие посты будут посвящены разбору нововведений спецификации ECMAScript 2023. В этой спецификации было представлено много новых методов, которые позволяют упростить работу с массивами.
Проблема обычного метода
В этом примере в консоли мы увидим уже отсортированный массив, несмотря на то, что, казалось бы, никак не обрабатывали результат вызова метода. На самом деле, метод
И как раз для упрощения этой операции в спецификации и появился новый метод —
На примере это будет выглядеть следующим образом:
Не сказал бы, что что-то невероятно сильно изменилось, но такая запись точно безопаснее, проще и визуально выглядит гораздо легче.
Аналогичные замены появились и для методов
Это не все нововведения ECMAScript 2023, но это их весомая часть. Разбор остальных нововведений будет в скором времени.
Спасибо за прочтение, это важно для меня ❤️
#javascript #theory #web #data
Относительно новые фишки языка уже просачиваются на собеседования, поэтому ближайшие посты будут посвящены разбору нововведений спецификации ECMAScript 2023. В этой спецификации было представлено много новых методов, которые позволяют упростить работу с массивами.
toSorted
— это метод массива, который работает аналогично уже давно существующему методу sort
, а именно, как и ожидается, сортирует массив. Проблема обычного метода
sort
заключается в том что его вызов мутирует исходный массив. Это может вызвать неудобства и проблемы в тех местах, где нам запрещено менять исходные данные, например при обработке экшенов в redux
.const nums = [1, 4, 3, 2]
nums.sort()
console.log(nums) // [1, 2, 3, 4]
В этом примере в консоли мы увидим уже отсортированный массив, несмотря на то, что, казалось бы, никак не обрабатывали результат вызова метода. На самом деле, метод
sort
напрямую изменяет массив, для которого был вызван. Для решения такой проблемы часто можно видеть следующий хак:const nums = [1, 4, 3, 2]
const newNums = [...nums].sort()
console.log(nums) // [1, 4, 3, 2]
console.log(newNums) // [1, 2, 3, 4]
И как раз для упрощения этой операции в спецификации и появился новый метод —
toSorted
. Его работу в чём то можно сравнить с методами map
и filter
, а именно в том, что все эти метода совершают какие-то действия только над копией массива не затрагивая изначальный, при это возвращая полностью новый массив.На примере это будет выглядеть следующим образом:
const nums = [1, 4, 3, 2]
const newNums = nums.toSorted()
console.log(nums) // [1, 4, 3, 2]
console.log(newNums) // [1, 2, 3, 4]
Не сказал бы, что что-то невероятно сильно изменилось, но такая запись точно безопаснее, проще и визуально выглядит гораздо легче.
Аналогичные замены появились и для методов
reverse
и splice
. Для них еще один небольшой пример:const nums = [1, 2, 3, 4];
const reversed = nums.toReversed();
console.log(nums) // [1, 2, 3, 4]
console.log(reversed) // [4, 3, 2, 1]
const nums = [1, 2, 3, 4];
const spliced = nums.toSpliced(0, 1);
console.log(nums) // [1, 2, 3, 4]
console.log(spiced) // [2, 3, 4]
Это не все нововведения ECMAScript 2023, но это их весомая часть. Разбор остальных нововведений будет в скором времени.
Спасибо за прочтение, это важно для меня ❤️
#javascript #theory #web #data
❤50👍11🔥8🐳6
Event: особенности target и currentTarget
Напоминаю, что при обработке события, функция-обработчик получает первым аргументом объект события
Скорее всего, из сухих определений мало что можно понять, поэтому рассмотрим пример:
Тут мы видим, что
Эта тема крайне тесно связана с событийной моделью браузера, о которой можно прочитать в одном из моих прошлых постов.
Различие между
Спасибо за прочтение, это важно для меня ❤️
#theory #web #javascript
Напоминаю, что при обработке события, функция-обработчик получает первым аргументом объект события
Event
, который содержит различные поля, это самое событие идентифицирующие. Одними из таких полей являются свойства target
и currentTarget
, рассмотрим их поближе:event.target
— это тот элемент вёрстки, который вызвал событие.event.currentTarget
— это тот элемент вёрстки, к которому прикреплен обработчик события.Скорее всего, из сухих определений мало что можно понять, поэтому рассмотрим пример:
<button id="outer">
Outer Button
// всегда будем кликать именно на
// внутреннюю кнопку
<button id="inner">Inner Button</button>
</button>
const outerButton = document.getElementById('outer');
const innerButton = document.getElementById('inner');
outerButton.addEventListener('click', function(event) {
// выведет 'inner', потому что этот элемент вызвал событие
console.log('event.target:', event.target.id);'
// выведет 'outer', так как обработчик принадлежит именно
// внешней кнопке
console.log('event.currentTarget:', event.currentTarget.id); // выведет 'outer'
});
innerButton.addEventListener('click', function(event) {
// ожидаемо увидим 'inner'
console.log('event.target:', event.target.id);
// также ожидаемо будет 'inner', так как этот обработчик
// принадлежит уже innerButton
console.log('event.currentTarget:', event.currentTarget.id);
});
Тут мы видим, что
event.target
всегда ссылается на кнопку inner
, поскольку именно она и триггерит событие, когда пользователь на нее кликает. В свою очередь, event.currentTarget
ссылается именно на тот элемент, чей обработчик сработал.Эта тема крайне тесно связана с событийной моделью браузера, о которой можно прочитать в одном из моих прошлых постов.
Различие между
event.target
и event.currentTarget
особенно полезно при работе с вложенными элементами, когда обработчики событий привязаны к родительским элементам, то есть при делегировании событий, о чём я также писал ранее. Ну и на собесе поможет, конечно же)Спасибо за прочтение, это важно для меня ❤️
#theory #web #javascript
❤30👍16🔥2🐳2
Двухфакторная аутентификация и факторы аутентификации
Фактор аутентификации — это способ подтверждения личности пользователя.
Существует несколько факторов аутентификации:
— Фактор знания — это информация, которую может знать конкретный пользователь, например, пароль, PIN-код или ответ на секретный вопрос
— Фактор владения — это что-то, что пользователь имеет, например, мобильное устройство для получения одноразового кода аутентификации через SMS или приложение аутентификатор
— Фактор индивидуальности — это что-то, что является частью пользователя, например, биометрические данные, такие как скан отпечатка пальца, сетчатки или параметры распознавания лица
Когда пользователь вводит свой пароль, то есть подтверждает первый фактор, система запрашивает дополнительный фактор подтверждения, чтобы убедиться в его личности. Такой подход к аутентификации называется двухфакторным.
Двухфакторная аутентификация (2FA) — подход к выполнению аутентификации пользователя, когда для идентификации личности используется сразу два фактора.
В последнее время двухфакторная аутентификация стала стандартом, так как это значимо повышает безопасность приложений, аккаунтов пользователей, а значит и безопасность их данных.
Также важно знать, что среди факторов аутентификации присутствует некая иерархия, то есть, фактор индивидуальности является более надежным, чем фактор владения, а фактор владения — более надежным, чем фактор знания.
Комбинировать различные факторы аутентификации можно в любом виде, но самые распространенные из них:
— Номер телефона + SMS — вы не просто знаете номер телефона, но и владеете им
— Почта + пароль + код из сообщения на почту — вы не просто знаете учетные данные, но и имеете доступ к почте
— Face ID — вы обладаете индивидуальными чертами лица
— Отпечаток пальца
Возможно, есть ещё какие-то распространенные связки, но, кажется, что основные я вспомнил
Также даю ссылку на свой прошлый пост, где я объяснил разницу между авторизацией и аутентификацией. Это важно в контексте этого поста.
Спасибо за прочтение, это важно для меня ❤️
#theory #data
Фактор аутентификации — это способ подтверждения личности пользователя.
Существует несколько факторов аутентификации:
— Фактор знания — это информация, которую может знать конкретный пользователь, например, пароль, PIN-код или ответ на секретный вопрос
— Фактор владения — это что-то, что пользователь имеет, например, мобильное устройство для получения одноразового кода аутентификации через SMS или приложение аутентификатор
— Фактор индивидуальности — это что-то, что является частью пользователя, например, биометрические данные, такие как скан отпечатка пальца, сетчатки или параметры распознавания лица
Когда пользователь вводит свой пароль, то есть подтверждает первый фактор, система запрашивает дополнительный фактор подтверждения, чтобы убедиться в его личности. Такой подход к аутентификации называется двухфакторным.
Двухфакторная аутентификация (2FA) — подход к выполнению аутентификации пользователя, когда для идентификации личности используется сразу два фактора.
В последнее время двухфакторная аутентификация стала стандартом, так как это значимо повышает безопасность приложений, аккаунтов пользователей, а значит и безопасность их данных.
Также важно знать, что среди факторов аутентификации присутствует некая иерархия, то есть, фактор индивидуальности является более надежным, чем фактор владения, а фактор владения — более надежным, чем фактор знания.
Комбинировать различные факторы аутентификации можно в любом виде, но самые распространенные из них:
— Номер телефона + SMS — вы не просто знаете номер телефона, но и владеете им
— Почта + пароль + код из сообщения на почту — вы не просто знаете учетные данные, но и имеете доступ к почте
— Face ID — вы обладаете индивидуальными чертами лица
— Отпечаток пальца
Возможно, есть ещё какие-то распространенные связки, но, кажется, что основные я вспомнил
Также даю ссылку на свой прошлый пост, где я объяснил разницу между авторизацией и аутентификацией. Это важно в контексте этого поста.
Спасибо за прочтение, это важно для меня ❤️
#theory #data
🔥31🐳7👍6
Измерение времени в JavaScript
JavaScript предлагает несколько способов для измерения времени выполнения кода, которые могут быть полезны при оптимизации и анализе производительности. Я думаю, что все мы знаем про глобальный объект
Как атрибут глобального объекта
То же самое можно сделать с использованием
2. Меньше накладных расходов.
Если подводить итог, то я просто за то, чтобы использовать инструменты по назначению. Perfomance API решает крайне важную и популярную задачу, это самый точный и универсальный инструмент для выполнения замеров времени. Мы всё ещё можем использовать
#web #theory #data #javascript
JavaScript предлагает несколько способов для измерения времени выполнения кода, которые могут быть полезны при оптимизации и анализе производительности. Я думаю, что все мы знаем про глобальный объект
Date
, который позволяет работать нам с таймстемпами, но также есть ещё один менее известный способ — Perfomance API
Как атрибут глобального объекта
window
, performance
предоставляет пользователям лишь набор методов. И эти методы позволяют работать с производительностью более точно. Например, метод performance.now()
возвращает количество миллисекунд с высокой точностью, прошедших с начала исполнения текущей страницы.const start = performance.now();
// Код, который нужно измерить
const end = performance.now();
console.log(`Время выполнения: ${end - start} миллисекунд`);
То же самое можно сделать с использованием
Date
, но почему это не лучший способ?1. perfomance.now()
более точен и возвращает время с точностью до тысячных долей миллисекунды (микросекунды). Это позволяет более точно рассчитывать время выполнения, особенно если речь идёт о коротких по времени операциях.2. Меньше накладных расходов.
Date
— очень тяжелый конструктор, его вызов стоит дорого. В свою очередь, Perfomance API не только занимает меньше времени, но и исключает связанные с временем вызова погрешности из расчётов. Особенно может быть полезно, если необходимо измерять время каждой итерации одного цикла, например.Если подводить итог, то я просто за то, чтобы использовать инструменты по назначению. Perfomance API решает крайне важную и популярную задачу, это самый точный и универсальный инструмент для выполнения замеров времени. Мы всё ещё можем использовать
Date
для этих задач, но зачем? Это как console.log’ами
дебажить. Ой.. Я ведь не один так делаю, да?)#web #theory #data #javascript
👍23🐳15❤1
This media is not supported in your browser
VIEW IN TELEGRAM
Что такое псевдоэлементы
Псевдоэлементы — это специальные ключевые слова, которые используются для дополнительной стилизации страницы без изменения HTML.
Одними из наиболее распространенных псевдоэлементов являются
У нас обязательно должно быть свойство
Смотрите крутую статью на доке, там гораздо больше теории и других псевдоэлементов. А я рассмотрю интересный пример с прикрепленной гифки:
Тут вся магия реализована как раз через
Накидайте бананов 🍌, если вам нравятся посты с гифками и примерами с кодпена. Может почаще делать буду такое.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — #web #theory #code
Псевдоэлементы — это специальные ключевые слова, которые используются для дополнительной стилизации страницы без изменения HTML.
Одними из наиболее распространенных псевдоэлементов являются
::before
и ::after
. Они позволяют добавить контент до или после содержимого элемента соответственно:div::before {
content: "До элемента";
}
div::after {
content: "После элемента";
}
У нас обязательно должно быть свойство
content
, а в остальном — можно использовать любые CSS правила.Смотрите крутую статью на доке, там гораздо больше теории и других псевдоэлементов. А я рассмотрю интересный пример с прикрепленной гифки:
.btn::before {
background-color: #0A88F3;
transition: 0.3s ease-out;
}
.btn.hover-filled-slide-right::before {
top:0;
bottom: 0;
right: 0;
height: 100%;
width: 100%;
}
.btn.hover-filled-slide-right:hover::before {
width: 0%;
}
Тут вся магия реализована как раз через
::before
, и это, как я считаю, самый удобный и правильный способ реализовать подобное. Мы просто анимируем параметр width
, постепенно приводя его из 100% в 0% на наведение курсора. Всё гениальное просто.Накидайте бананов 🍌, если вам нравятся посты с гифками и примерами с кодпена. Может почаще делать буду такое.
Спасибо за прочтение, это важно для меня ❤️
@prog_way_blog — #web #theory #code
🍌53👍5🔥3❤2🐳2
Ещё один формат айдишников
Самыми популярными вариантами создания айдишников можно назвать
Лично я, среди этих двух вариантов, предпочёл бы использовать
Если на длину
Думаю, что на этих примерах идея более чем понятна. Мы просто дописывали к каждому айдишнику название сущности через знак двоеточия, соответственно дебажить и читать данные стало в разы проще. С какой-то стороны, мы увеличиваем длину айдишника, что тоже не хорошо, но рост размера
Таким образом, получаем самый безопасный, стабильный, читаемый айдишник. Не без минусов, конечно, но всё же, так ли он критичен?
Пост вдохновлён идеей одного из подписчиков канала, за что большое спасибо. Напоминаю, что моя личка открыта, обязательно приходите.
Спасибо за прочтение, это важно для меня ❤️
#web #data
Самыми популярными вариантами создания айдишников можно назвать
uuid
и целое положительное число:6e522170-d7d5-494b-ae1f-5589608a6a51 // uuid.v4
4312 // целое положительное число
Лично я, среди этих двух вариантов, предпочёл бы использовать
uuid
, так как это наиболее безопасный и стабильный способ создавать айдишники, но у uuid есть два неоспоримых минуса: читаемость и длина. Если на длину
uuid
ещё можно закрыть глаза, то вот читаемость порой просто убивает. Мне довелось поработать в проде с системой, которая содержит огромное количество разных сущностей, где каждая сущность ссылается на десяток других по ID, модели часто выглядели как набор ключ:айдишник. С целью улучшить читаемость таких идентификаторов, был сделан следующий шаблон:<название модели>:<uuid>
примеры:
link:b386b8fd-64b6-4f49-85c0-b7292ec43713
building:364c2c5e-4cd2-4aec-b570-bb7e317ca018
office:56c5f243-b07f-450f-a6f0-18e6e363504c
user:f05db8bb-df2c-4575-b990-f87c3a8dd663
role:6fbdc403-0698-4e79-ade7-8a75dd6cd85b
Думаю, что на этих примерах идея более чем понятна. Мы просто дописывали к каждому айдишнику название сущности через знак двоеточия, соответственно дебажить и читать данные стало в разы проще. С какой-то стороны, мы увеличиваем длину айдишника, что тоже не хорошо, но рост размера
payload’a
, отдаваемого на UI, был мизерный, меньше 5%. Зато очень сильно улучшилась читаемость.Таким образом, получаем самый безопасный, стабильный, читаемый айдишник. Не без минусов, конечно, но всё же, так ли он критичен?
Пост вдохновлён идеей одного из подписчиков канала, за что большое спасибо. Напоминаю, что моя личка открыта, обязательно приходите.
Спасибо за прочтение, это важно для меня ❤️
#web #data
👍33🐳8🔥4❤2🍌1
Что такое ECMAScript?
ECMAScript, или же ECMA-262 — это стандарт скриптовых языков программирования общего назначения, который определяет синтаксис, структуры данных, правила и другие аспекты языка.
Наиболее известный пример — JavaScript, но также спецификации придерживаются языки, например, TypeScript или CoffeScript.
Спецификация ECMAScript пересматривается каждый год и версионируется двумя различными способами. На примере спецификации 2015 года, её названия — это
Вообще, эта спецификация решает крайне важные задачи для развития языка и веба в целом, такие как, как не странно, стандартизация, расширяемость языка и контроль его эволюционного развития. Всё это осуществляется через систему предложений от комьюнити, где каждое предложение на изменение языка называется
Важно понимать, что в старых версиях браузеров не будут поддерживаться новые функции языка. Для решения этой проблемы существует
Более подробно о нововведениях каждой из версий спецификации можно почитать в отличной статье на хабре.
Также оставляю ссылку на драфт
Такой вот пост вышел. Много ссылок, зато они очень интересные.
Спасибо за прочтение, это важно для меня ❤️
#web #theory #javascript
ECMAScript, или же ECMA-262 — это стандарт скриптовых языков программирования общего назначения, который определяет синтаксис, структуры данных, правила и другие аспекты языка.
Наиболее известный пример — JavaScript, но также спецификации придерживаются языки, например, TypeScript или CoffeScript.
Спецификация ECMAScript пересматривается каждый год и версионируется двумя различными способами. На примере спецификации 2015 года, её названия — это
ES6
или же ECMAScript2015
. Соответственно, спецификация 2018 года будет называться ES9
и так далее.Вообще, эта спецификация решает крайне важные задачи для развития языка и веба в целом, такие как, как не странно, стандартизация, расширяемость языка и контроль его эволюционного развития. Всё это осуществляется через систему предложений от комьюнити, где каждое предложение на изменение языка называется
proposal
. Подробнее о них можно прочитать в официальном гит репозитории. Также прилагаю ссылку на proposal на добавление нового глобального объекта для взаимодействия с датами, замены Date
— Temporal
. Просто посмотреть как это выглядит, нас это изменение каснётся уже очень скоро.Важно понимать, что в старых версиях браузеров не будут поддерживаться новые функции языка. Для решения этой проблемы существует
Babel
, который транспилирует код новых версий в старые, используя полифилы. Более подробно о полифилах писал в отдельном посте. Более подробно о нововведениях каждой из версий спецификации можно почитать в отличной статье на хабре.
Также оставляю ссылку на драфт
ECMAScript2025
, где можно посмотреть черновики спецификации следующего года.Такой вот пост вышел. Много ссылок, зато они очень интересные.
Спасибо за прочтение, это важно для меня ❤️
#web #theory #javascript
👍25❤6🔥4🐳3🍌1
Preload и Prefetch
Preload и Prefetch — опции загрузки контента, которые позволяют улучшить пользовательский опыт и просто загружать все ресурсы значительно быстрее.
Preload — это механизм HTML, который позволяет вам указать браузеру загружать ресурсы (скрипты, стили, шрифты и изображения) ещё до того, как они будут использованы на странице. Это особенно полезно для ресурсов, которые будут запрошены в будущем в результате действий пользователя, таких как навигация по страницам или выполнение каких-либо действий:
В этом примере браузер будет предварительно загружать файл
Prefetch — предназначен для загрузки ресурсов, которые будут использоваться на последующих страницах, а не на текущей. Он сообщает браузеру о том, какие ресурсы необходимо предварительно загрузить в фоновом режиме для улучшения скорости загрузки последующих страниц. С каким-нибудь реактом такой фокус не прокатит, однако это точно можно применять, например, со статически-генерируемыми сайтами через что-то типа
Можем просто загрузить следующую страничку в фоне и, если пользователь захочет на нее перейти, она откроется сильно быстрее.
В целом, preload и prefetch — это одни из самых базовых способов оптимизировать загрузку фронтенда, которыми точно не стоит пренебрегать. Не одним же реактом едины.
Спасибо за прочтение, это важно для меня ❤️
#web #theory
Preload и Prefetch — опции загрузки контента, которые позволяют улучшить пользовательский опыт и просто загружать все ресурсы значительно быстрее.
Preload — это механизм HTML, который позволяет вам указать браузеру загружать ресурсы (скрипты, стили, шрифты и изображения) ещё до того, как они будут использованы на странице. Это особенно полезно для ресурсов, которые будут запрошены в будущем в результате действий пользователя, таких как навигация по страницам или выполнение каких-либо действий:
<link rel="preload" href="styles.css" as="style">
В этом примере браузер будет предварительно загружать файл
styles.css
, как только он обнаружит этот тег <link>
в HTML-документе, даже до того, как он встретит место, где эти стили используютсяPrefetch — предназначен для загрузки ресурсов, которые будут использоваться на последующих страницах, а не на текущей. Он сообщает браузеру о том, какие ресурсы необходимо предварительно загрузить в фоновом режиме для улучшения скорости загрузки последующих страниц. С каким-нибудь реактом такой фокус не прокатит, однако это точно можно применять, например, со статически-генерируемыми сайтами через что-то типа
11ty
.<link rel="prefetch" href="next-page.html">
Можем просто загрузить следующую страничку в фоне и, если пользователь захочет на нее перейти, она откроется сильно быстрее.
В целом, preload и prefetch — это одни из самых базовых способов оптимизировать загрузку фронтенда, которыми точно не стоит пренебрегать. Не одним же реактом едины.
Спасибо за прочтение, это важно для меня ❤️
#web #theory
❤27👍14🐳3🍌1
Создание собственных ошибок в приложении
С ростом приложения может быть полезно создавать собственные ошибка для удобства их обработки, лебага и логирования. В этом посте поговорим о стандартных способах как это можно сделать.
Обычно ошибки выбрасываются следующим образом:
Это удобно и быстро, но с ростом приложения можно оптимизировать и это. Для этого нужно создать собственный класс ошибки:
Обратите внимание, что нам нужно обязательно унаследовать собственную ошибку от стандартного класса
Далее разберем пример создания ошибок, которые могут возникнуть в работе с
Тут мы создаём две ошибки, которые далее сможем использовать в нашем приложении. Этап с объединением под
Кстати, чтобы обработать конкретную ошибку определенным способом, используется следующая конструкция:
Конструкция со
На этом всё, что я хотел описать в этой теме. Надеюсь, что это было полезно. Поддержите реакциями)
Спасибо за прочтение, это важно для меня ❤️
#web #javascript #theory #data
С ростом приложения может быть полезно создавать собственные ошибка для удобства их обработки, лебага и логирования. В этом посте поговорим о стандартных способах как это можно сделать.
Обычно ошибки выбрасываются следующим образом:
throw Error("Ошибка сервера")
Это удобно и быстро, но с ростом приложения можно оптимизировать и это. Для этого нужно создать собственный класс ошибки:
class CustomError extends Error {
constructor(message: string) {
super(message);
this.name = 'CustomError';
}
}
Обратите внимание, что нам нужно обязательно унаследовать собственную ошибку от стандартного класса
Error
и вызвать конструктор родительского класса через super
— это необходимые шаги для правильной инициализации собственной ошибки. this.name
устанавливается для того, чтобы ошибку в логах было проще идентифицировать. Это очень полезно, но не обязательно.Далее разберем пример создания ошибок, которые могут возникнуть в работе с
API
:class NullableRequestParameter extends Error {
constructor(message = 'Required req param is nullable') {
super(message)
this.name = 'NullableRequestParameter'
}
}
class Unauthorized extends Error {
constructor(message = 'User is unauthorized') {
super(message)
this.name = 'Unauthorized'
this.code = 401
}
}
export const RestServiceError = {
NullableRequestParameter,
Unauthorized
} as const
// где-то выбросим нужную нам ошибку
throw RestServiceError.Unauthorized()
Тут мы создаём две ошибки, которые далее сможем использовать в нашем приложении. Этап с объединением под
RestServiceError
можно опустить, это уже мой собственный код стайл. Люблю объединять общие сущности под единым началом.Кстати, чтобы обработать конкретную ошибку определенным способом, используется следующая конструкция:
try {
// код, где может быть ошибка
} catch (error) {
switch (true) {
case error instanceof RestServiceError.Unauthorized:
// обработка ошибки Unauthorized
break;
case error instanceof RestServiceError.NullableRequestParameter:
// обработка ошибки NullableRequestParameter
break;
default:
// обработка всех непредвиденных ошибок
}
}
Конструкция со
switch (true)
является более предпочтительной из-за читаемости и расширяемости, хотя можно решить ту же задачу просто через if else
.На этом всё, что я хотел описать в этой теме. Надеюсь, что это было полезно. Поддержите реакциями)
Спасибо за прочтение, это важно для меня ❤️
#web #javascript #theory #data
❤26👍9🔥2🐳2🍌1