Рефакторинг существующих компонентов

Рефакторинг существующих компонентов в Slim.js направлен на повышение читаемости кода, упрощение поддержки и улучшение производительности без изменения внешнего поведения приложения. Slim.js использует реактивный подход к работе с DOM через кастомные элементы, что делает особое внимание к структуре компонентов критически важным.


Структура компонента и её оптимизация

Типичный компонент в Slim.js имеет три ключевых части:

  1. Шаблон (template) – HTML-разметка компонента.
  2. Скрипт (script) – логика, обработчики событий, вычисляемые свойства.
  3. Стили (style) – CSS, специфичный для компонента.

Рефакторинг начинается с анализа этих частей. Основные направления оптимизации:

  • Изоляция логики: перемещение сложных функций в отдельные модули или утилиты, чтобы компонент занимался только своей основной задачей.
  • Минимизация пересчётов DOM: использование реактивных свойств и observe() вместо ручного изменения элементов через querySelector.
  • Ясность шаблонов: избегание вложенных условий и циклов в шаблоне, предпочтение вычисляемых свойств.

Пример упрощения вычисляемого свойства:

class MyComponent extends Slim {
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

Вместо непосредственного составления строки в шаблоне:

<p>{firstName} {lastName}</p>

Разделение больших компонентов

Большие компоненты часто содержат несколько независимых логических блоков. Для их рефакторинга применяются следующие подходы:

  • Создание дочерних компонентов: каждый логический блок выносится в отдельный Slim-компонент. Это уменьшает связность и повышает переиспользуемость.
  • Использование слотов: позволяет передавать внутреннее содержимое в дочерний компонент без изменения родительской логики.

Пример использования слота:

<custom-card>
  <p slot="content">Основной текст карточки</p>
</custom-card>
class CustomCard extends Slim {
  get useShadow() { return true; }
  template() {
    return `<div class="card"><slot name="content"></slot></div>`;
  }
}

Управление состоянием

Slim.js поддерживает реактивные свойства, что облегчает управление состоянием. При рефакторинге стоит обратить внимание на:

  • Минимизацию количества реактивных свойств: не все данные должны быть реактивными, только те, которые влияют на DOM.
  • Группировка связанных состояний: вместо множества отдельных свойств можно использовать объект или Map, чтобы уменьшить количество обновлений.

Пример:

class TodoList extends Slim {
  constructor() {
    super();
    this.todos = [];
  }

  addTodo(todo) {
    this.todos = [...this.todos, todo]; // реактивное обновление
  }
}

Оптимизация событий и обработчиков

Старые компоненты могут содержать избыточные обработчики событий, что снижает производительность:

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

Пример делегирования:

this.shadowRoot.addEventListener('click', (e) => {
  if (e.target.matches('.delete-btn')) {
    this.deleteItem(e.target.dataset.id);
  }
});

Улучшение читаемости шаблонов

Шаблоны Slim.js поддерживают синтаксис {property} и директивы :if, :each. Для рефакторинга:

  • Избегать длинных вложенных директив. Вместо цепочек :if внутри :each лучше вынести условие в вычисляемое свойство.
  • Использовать вычисляемые массивы и фильтры для списков вместо сложной логики прямо в шаблоне.

Пример:

get activeTodos() {
  return this.todos.filter(todo => !todo.completed);
}
<ul>
  <li :each="activeTodos">{text}</li>
</ul>

Работа с CSS

Рефакторинг компонентов включает оптимизацию стилей:

  • Избегать глобальных селекторов; использовать изоляцию через Shadow DOM.
  • Вынос повторяющихся стилей в отдельные файлы.
  • Минимизировать inline-стили для улучшения производительности и читаемости.

Пример использования Shadow DOM:

class StyledButton extends Slim {
  get useShadow() { return true; }
  template() {
    return `<button class="btn">Нажми</button>`;
  }
  style() {
    return `.btn { background: blue; color: white; padding: 10px; border-radius: 5px; }`;
  }
}

Применение шаблонов проектирования

При рефакторинге крупных компонентов полезно использовать шаблоны проектирования:

  • Композиция: предпочтительнее наследования, особенно для повторно используемых частей.
  • Фабрика компонентов: для динамического создания похожих компонентов с различными параметрами.
  • Observer Pattern: для управления реактивными свойствами и синхронизации состояний между компонентами.

Автоматизация тестирования

Рефакторинг сопровождается обязательным тестированием:

  • Unit-тесты для методов компонента.
  • Snapshot-тесты шаблонов.
  • Тестирование событий и реактивных изменений.

Пример проверки реактивного свойства:

const component = new TodoList();
component.todos = [{ text: 'Task 1', completed: false }];
assert.equal(component.activeTodos.length, 1);

Пошаговая стратегия рефакторинга

  1. Анализ существующего компонента: выявление слабых мест и дублирующегося кода.
  2. Выделение вычисляемых свойств и логики в отдельные функции.
  3. Разделение больших компонентов на дочерние.
  4. Оптимизация шаблонов и стилей.
  5. Проверка реактивности и корректности обновлений DOM.
  6. Рефакторинг обработчиков событий и состояния.
  7. Тестирование и фиксация производительности.

Эти подходы позволяют поддерживать код Slim.js чистым, масштабируемым и удобным для командной разработки, обеспечивая одновременно высокую производительность и читаемость компонентов.