fix: add patterns, rerender and js
This commit is contained in:
96
docs/architecture/11-patterns.md
Normal file
96
docs/architecture/11-patterns.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 11
|
||||||
|
---
|
||||||
|
|
||||||
|
# Паттерны проектирования
|
||||||
|
|
||||||
|
Паттерн проектирования — это часто встречающееся решение определённой проблемы при проектировании архитектуры программ.
|
||||||
|
|
||||||
|
В отличие от готовых функций или библиотек, паттерн нельзя просто взять и скопировать в программу. Паттерн представляет собой не какой-то конкретный код, а общую концепцию решения той или иной проблемы, которую нужно будет ещё подстроить под нужды вашей программы.
|
||||||
|
|
||||||
|
Паттерны часто путают с алгоритмами, ведь оба понятия описывают типовые решения каких-то известных проблем. Но если алгоритм — это чёткий набор действий, то паттерн — это высокоуровневое описание решения, реализация которого может отличаться в двух разных программах.
|
||||||
|
|
||||||
|
Если привести аналогии, то алгоритм — это кулинарный рецепт с чёткими шагами, а паттерн — инженерный чертёж, на котором нарисовано решение, но не конкретные шаги его реализации.
|
||||||
|
|
||||||
|
## Из чего состоит паттерн?
|
||||||
|
Описания паттернов обычно очень формальны и чаще всего состоят из таких пунктов:
|
||||||
|
|
||||||
|
- проблема, которую решает паттерн;
|
||||||
|
- мотивации к решению проблемы способом, который предлагает паттерн;
|
||||||
|
- структуры классов, составляющих решение;
|
||||||
|
- примера на одном из языков программирования;
|
||||||
|
- особенностей реализации в различных контекстах;
|
||||||
|
- связей с другими паттернами.
|
||||||
|
|
||||||
|
Такой формализм в описании позволил создать обширный каталог паттернов, проверив каждый из них на состоятельность.
|
||||||
|
|
||||||
|
## Классификация паттернов
|
||||||
|
Паттерны отличаются по уровню сложности, детализации и охвата проектируемой системы. Проводя аналогию со строительством, вы можете повысить безопасность перекрёстка, поставив светофор, а можете заменить перекрёсток целой автомобильной развязкой с подземными переходами.
|
||||||
|
|
||||||
|
Самые низкоуровневые и простые паттерны — _идиомы_. Они не универсальны, поскольку применимы только в рамках одного языка программирования.
|
||||||
|
|
||||||
|
Самые универсальные — _архитектурные паттерны_, которые можно реализовать практически на любом языке. Они нужны для проектирования всей программы, а не отдельных её элементов.
|
||||||
|
|
||||||
|
Кроме того, паттерны отличаются и предназначением. В этой книге будут рассмотрены три основные группы паттернов:
|
||||||
|
|
||||||
|
- **[Порождающие паттерны](https://refactoring.guru/ru/design-patterns/creational-patterns)** беспокоятся о гибком создании объектов без внесения в программу лишних зависимостей.
|
||||||
|
- **[Структурные паттерны](https://refactoring.guru/ru/design-patterns/structural-patterns)** показывают различные способы построения связей между объектами.
|
||||||
|
- **[Поведенческие паттерны](https://refactoring.guru/ru/design-patterns/behavioral-patterns)** заботятся об эффективной коммуникации между объектами.
|
||||||
|
|
||||||
|
|
||||||
|
## Зачем знать паттерны?
|
||||||
|
Вы можете вполне успешно работать, не зная ни одного паттерна. Более того, вы могли уже не раз реализовать какой-то из паттернов, даже не подозревая об этом.
|
||||||
|
|
||||||
|
Но осознанное владение инструментом как раз и отличает профессионала от любителя. Вы можете забить гвоздь молотком, а можете и дрелью, если сильно постараетесь. Но профессионал знает, что главная фишка дрели совсем не в этом. Итак, зачем же знать паттерны?
|
||||||
|
|
||||||
|
- **Проверенные решения.** Вы тратите меньше времени, используя готовые решения, вместо повторного изобретения велосипеда. До некоторых решений вы смогли бы додуматься и сами, но многие могут быть для вас открытием.
|
||||||
|
|
||||||
|
- **Стандартизация кода.** Вы делаете меньше просчётов при проектировании, используя типовые унифицированные решения, так как все скрытые проблемы в них уже давно найдены.
|
||||||
|
|
||||||
|
- **Общий программистский словарь.** Вы произносите название паттерна, вместо того, чтобы час объяснять другим программистам, какой крутой дизайн вы придумали и какие классы для этого нужны.
|
||||||
|
|
||||||
|
## Критика паттернов
|
||||||
|
Паттерны были описаны более 20-ти лет назад, поэтому только ленивый не успел бросить в них камень. Давайте рассмотрим самую популярную критику.
|
||||||
|
|
||||||
|
### Костыли для слабого языка программирования
|
||||||
|
Нужда в паттернах появляется тогда, когда люди выбирают для своего проекта язык программирования с недостаточным уровнем абстракции. В этом случае, паттерны — это костыль, который придаёт этому языку суперспособности.
|
||||||
|
|
||||||
|
Например, паттерн **Стратегия** в современных языках можно реализовать простой анонимной (лямбда) функцией.
|
||||||
|
|
||||||
|
### Неэффективные решения
|
||||||
|
Паттерны пытаются стандартизировать подходы, которые и так уже широко используются. Эта стандартизация кажется некоторым людям догмой и они реализуют паттерны «как в книжке», не приспосабливая паттерны к реалиям проекта.
|
||||||
|
|
||||||
|
### Неоправданное применение
|
||||||
|
Если у тебя в руках молоток, то все предметы вокруг начинают напоминать гвозди.
|
||||||
|
|
||||||
|
Похожая проблема возникает у новичков, которые только-только познакомились с паттернами. Вникнув в паттерны, человек пытается применить свои знания везде. Даже там, где можно было бы обойтись кодом попроще.
|
||||||
|
|
||||||
|
## Каталог паттернов проектирования
|
||||||
|
- **[Порождающие:](https://refactoring.guru/ru/design-patterns/creational-patterns)** Отвечают за удобное и безопасное создание новых объектов или даже целых семейств объектов.
|
||||||
|
- [Фабричный метод](https://refactoring.guru/ru/design-patterns/factory-method)
|
||||||
|
- [Абстрактная фабрика](https://refactoring.guru/ru/design-patterns/abstract-factory)
|
||||||
|
- [Строитель](https://refactoring.guru/ru/design-patterns/builder)
|
||||||
|
- [Прототип](https://refactoring.guru/ru/design-patterns/prototype)
|
||||||
|
- [Одиночка](https://refactoring.guru/ru/design-patterns/singleton)
|
||||||
|
- **[Структурные:](https://refactoring.guru/ru/design-patterns/structural-patterns)** Отвечают за построение удобных в поддержке иерархий классов.
|
||||||
|
- [Адаптер](https://refactoring.guru/ru/design-patterns/adapter)
|
||||||
|
- [Мост](https://refactoring.guru/ru/design-patterns/bridge)
|
||||||
|
- [Компоновщик](https://refactoring.guru/ru/design-patterns/composite)
|
||||||
|
- [Декоратор](https://refactoring.guru/ru/design-patterns/decorator)
|
||||||
|
- [Фасад](https://refactoring.guru/ru/design-patterns/facade)
|
||||||
|
- [Легковес](https://refactoring.guru/ru/design-patterns/flyweight)
|
||||||
|
- [Заместитель](https://refactoring.guru/ru/design-patterns/proxy)
|
||||||
|
- **[Поведенческие:](https://refactoring.guru/ru/design-patterns/behavioral-patterns)** Решают задачи эффективного и безопасного взаимодействия между объектами программы.
|
||||||
|
- [Цепочка обязанностей](https://refactoring.guru/ru/design-patterns/chain-of-responsibility)
|
||||||
|
- [Команда](https://refactoring.guru/ru/design-patterns/command)
|
||||||
|
- [Итератор](https://refactoring.guru/ru/design-patterns/iterator)
|
||||||
|
- [Посредник](https://refactoring.guru/ru/design-patterns/mediator)
|
||||||
|
- [Снимок](https://refactoring.guru/ru/design-patterns/memento)
|
||||||
|
- [Наблюдатель](https://refactoring.guru/ru/design-patterns/observer)
|
||||||
|
- [Состояние](https://refactoring.guru/ru/design-patterns/state)
|
||||||
|
- [Стратегия](https://refactoring.guru/ru/design-patterns/strategy)
|
||||||
|
- [Шаблонный метод](https://refactoring.guru/ru/design-patterns/template-method)
|
||||||
|
- [Посетитель](https://refactoring.guru/ru/design-patterns/visitor)
|
||||||
|
|
||||||
|
|
||||||
|
🚀 **_Источник: [Рефакторинг.Гуру](https://refactoring.guru/ru)_**
|
||||||
103
docs/browser/08-rerender_js.md
Normal file
103
docs/browser/08-rerender_js.md
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ререндер страницы в контексте event loop
|
||||||
|
|
||||||
|
Ререндер (перерисовка страницы) и event loop действительно тесно связаны в браузере, хотя происходят на разных уровнях работы движка.
|
||||||
|
|
||||||
|
## 🧠 Что такое event loop (цикл событий)
|
||||||
|
|
||||||
|
Event Loop — это механизм, который координирует выполнение JavaScript и обновление пользовательского интерфейса в браузере.
|
||||||
|
Он следит за очередями задач (macrotasks и microtasks) и периодически синхронизирует результаты с рендерингом страницы.
|
||||||
|
|
||||||
|
Упрощённо:
|
||||||
|
1. JS выполняется в однопоточном окружении.
|
||||||
|
2. Когда движок сталкивается с асинхронной задачей (таймер, fetch, промис), она попадает в очередь.
|
||||||
|
3. Event loop циклически:
|
||||||
|
- берёт задачу из очереди макротасков (например, setTimeout, fetch, click),
|
||||||
|
- выполняет её,
|
||||||
|
- затем обрабатывает все микротаски (например, .then, queueMicrotask),
|
||||||
|
- и только после этого может произойти рендер (отрисовка кадра).
|
||||||
|
|
||||||
|
## 🎨 Где тут ререндер страницы
|
||||||
|
Ререндер (или «перерисовка кадра») происходит между циклами event loop, после того как:
|
||||||
|
- закончено выполнение всех JS-задач текущей итерации (включая microtasks),
|
||||||
|
- браузер свободен,
|
||||||
|
- и наступает момент обновления UI (обычно раз в 16,6 мс для 60 fps).
|
||||||
|
|
||||||
|
Можно представить цикл так:
|
||||||
|
```text
|
||||||
|
[ Выполнение JS ] → [ Очередь microtasks ] → [ Пересчёт layout / repaint / composite ] → [ Следующий event loop tick ]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📅 Когда браузер решает перерисовать страницу
|
||||||
|
|
||||||
|
Браузер не будет рендерить страницу посреди выполнения JavaScript — это важно.
|
||||||
|
Рендеринг откладывается, пока:
|
||||||
|
- не закончится текущая макротаска,
|
||||||
|
- не будут выполнены все микротаски (Promise callbacks),
|
||||||
|
- и браузер решит, что пора обновить UI.
|
||||||
|
|
||||||
|
Например:
|
||||||
|
```js
|
||||||
|
console.log("start");
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
document.body.style.background = "red";
|
||||||
|
console.log("microtask done");
|
||||||
|
});
|
||||||
|
console.log("end");
|
||||||
|
```
|
||||||
|
Порядок событий:
|
||||||
|
```text
|
||||||
|
start
|
||||||
|
end
|
||||||
|
microtask done
|
||||||
|
[перерисовка после microtasks — фон становится красным]
|
||||||
|
```
|
||||||
|
|
||||||
|
## ⚙️ Пример с блокировкой рендера
|
||||||
|
|
||||||
|
Если ты сделаешь что-то тяжёлое в JS, например:
|
||||||
|
```js
|
||||||
|
while (true) {} // бесконечный цикл
|
||||||
|
```
|
||||||
|
— event loop не сможет дойти до стадии «рендера», и страница «замрёт».
|
||||||
|
Поэтому анимации, реактивные интерфейсы и плавные переходы требуют, чтобы JS отдавал управление обратно браузеру (через requestAnimationFrame, setTimeout, await, и т.д.).
|
||||||
|
|
||||||
|
## Как requestAnimationFrame вписывается в event loop
|
||||||
|
|
||||||
|
requestAnimationFrame (rAF) — это специальный API, который браузер вызывает перед следующей перерисовкой.
|
||||||
|
Это позволяет выполнять обновления DOM/Canvas синхронно с циклом рендера, без пропусков кадров.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
→ JS выполняется
|
||||||
|
→ rAF callback запланирован
|
||||||
|
→ microtasks выполняются
|
||||||
|
→ браузер вызывает rAF callback
|
||||||
|
→ обновление layout/repaint
|
||||||
|
→ кадр готов
|
||||||
|
```
|
||||||
|
## 🧩 В контексте фреймворков (React, Vue и т.п.)
|
||||||
|
Когда React вызывает setState(), обновления не происходят мгновенно:
|
||||||
|
- Они ставятся в очередь микрозадач или макрозадач (в зависимости от режима).
|
||||||
|
- После завершения текущего JS-такта React вычисляет новый виртуальный DOM.
|
||||||
|
- Затем браузер, на этапе рендера event loop, перерисовывает изменённые части UI.
|
||||||
|
|
||||||
|
Таким образом, **event loop управляет моментом**, когда обновления React реально становятся видимыми.
|
||||||
|
|
||||||
|
## 📊 Итоговое резюме
|
||||||
|
|
||||||
|
| Этап | Что делает |
|
||||||
|
|--------------|---------------------------------------------------------------------|
|
||||||
|
| Macrotask | Выполняет основную JS-задачу (скрипт, обработчик события и т.д.) |
|
||||||
|
| Microtasks | Обрабатывает все промисы и микрозадачи |
|
||||||
|
| Render phase | После JS — браузер вычисляет layout, стили и отрисовывает изменения |
|
||||||
|
| Next tick | Начинается следующий цикл event loop |
|
||||||
|
|
||||||
|
|
||||||
|
### Визуальная схема event loop и рендера (в виде диаграммы)
|
||||||
|
<img src="images/08-rerender-phases.png" width="600"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
docs/browser/images/08-rerender-phases.png
Normal file
BIN
docs/browser/images/08-rerender-phases.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
Reference in New Issue
Block a user