Перейти к содержимому

Блог

Как у вас с памятью?

Часто ли вы занимаетесь утечками памяти? Честно говоря, я — нет, но тема мне интересна. Каждый раз, когда я копаюсь в проблемах, связанных с памятью в веб-приложениях, я обнаруживаю, что надо задействовать мозг по максимуму: вспомнить, как устроена работа с памятью в JS, разобраться со всеми этими данными из Memory вкладки в DevTools, четко представлять, какие данные и когда нужны для приложения.

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

Посмотрите Memory Leaks в гайдах — это отобранные ссылки со статьями, как работает GC, как лучше отлаживаться в DevTools. Также планирую со временем добавить практические советы.

0 дней без ошибок с SVG background

У нас SVG в качестве фона сверху нашего сайта, основной фон — просто серый. Для картинки у нас такой css:

.container {
background-image: url(path/to/our.svg);
background-repeat: no-repeat;
background-size: 100% 144px;
}

Всех всё устраивает, однако подкрались праздники и дизайнерка предложила обновить картинку на более праздничную (и, конечно, добавить снег, но с ним как раз проблем не было). Дизайнерка попросила не растягивать новую картинку (как мы делаем обычно, просто растягивая её до 100%), так что обновила css:

.container {
background-image: url(path/to/holiday.svg);
background: no-repeat;
background-size: auto 144px;
background-position: left top;
}

Тестировщики протестировали, и всё улетело в предпраздничный релиз.

Пару дней спустя мне написал коллега: можем ли мы что-то сделать с нашим праздничным фоном на широких экранах? Я проверила, и это была катастрофа: на широких экранах (более чем 2500px) наш фон заканчивался на 2000px, и дальше справа было просто серое пятно.

Фикс был быстрый и простой:

.container {
background-image: url(path/to/holiday.svg);
background: repeat-x;
background-size: auto 144px;
background-position: left top;
}

Просто не забывайте: либо 100%, либо repeat.

HOC или не HOC?

В наборе кат для изучения паттернов попалась одна про Higher-Order Component(HOC) в React — truncate paragraph with HOC in React. Плюс недавно разбиралась с паттерном Декоратор, и примером применения для React как раз считается HOC.

И вот я задумалась: а действительно ли хоки актуальны?

Чаще всего я вижу хоки, когда работаю с кодом, написанным 3-4 года назад, но в новом коде я практически их не вижу. Опять же, в старой документации React есть целая страница, посвященная HOC и примерам использования, а вот в новой классной документации ничего нет.

Кажется, что кастомные хуки вытеснили хоки. Что такого особенного ты можешь сделать с HOC, что не можешь, просто написав кастомный хук?

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

Boxes in boxes, Или что застряло у меня в голове

Я периодически решаю задачи на leetcode или codewars, и недавно наткнулась на кату “Boxes in boxes”.

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

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

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

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

Оставлю мой код с комментами здесь, чтобы если можно было вспомнить ход мысли:

function draw(n) {
// all for one box, our start
let res = [" _ ", "|_|"];
for (let i = 1; i < n; i++) {
res = [
// top line - just add tops of boxes
' _' + res[0],
// draw existing boxes without left border (top 1/2 part is repeat existing but partially)
...res.slice(1).map(str => '| ' + str.slice(1)),
// draw existing with left border and without bottom
...res.slice(1, -1).map(str => '| ' + str),
// draw bottom
'|_' + res[res.length-1],
]
}
return res.join('\n');
}

Остаётся только надеяться, что на интервью мне эта задача не попадётся 🤪

Сегодня узнала, что можно в ref передавать callback

От моего внимания как-то ускользнуло, что в React можно передавать функцию-callback как ref для элемента, а не только объект, созданный с помощью useRef.

const scroller = (node: HTMLDivElement) => {
if (!node) return;
node.scrollIntoView({ behavior: "smooth" });
};
// somewhere in component
<div ref={scroller} />

Как это работает:

  • Когда элемент добавляется в DOM, React вызывает функцию-callback и передает в неё DOM-узел как аргумент.
  • Когда элемент удаляется из DOM, React вызывает эту функцию с аргументом null.
  • Callback также вызывается каждый раз, когда передается новая функция (например, при каждом рендере, если она определена как обычная функция).