Адаптивный дизайн и медиа-запросы

Адаптивный дизайн в веб-разработке обеспечивает корректное отображение интерфейсов на различных устройствах и экранах. В контексте Inferno важно понимать, что компонентная структура позволяет динамически управлять отображением элементов в зависимости от размеров окна или устройства пользователя.

Ключевой подход заключается в реактивной обработке изменений размеров окна и условной рендеринг-компонент. Inferno, будучи высокопроизводительным виртуальным DOM-фреймворком, позволяет минимизировать перерасчёт DOM при изменениях состояния.

Использование медиа-запросов в стилях

Медиа-запросы в CSS остаются основным инструментом адаптивного дизайна. Встроенные или внешние CSS-файлы могут содержать правила вида:

@media (max-width: 768px) {
  .sidebar {
    display: none;
  }
  .content {
    padding: 10px;
  }
}

@media (min-width: 769px) {
  .sidebar {
    display: block;
    width: 250px;
  }
  .content {
    padding: 20px;
  }
}

Ключевой момент: медиа-запросы позволяют разделять стили для мобильных и десктопных устройств без вмешательства JavaScript. Однако для более сложной логики компонентов может потребоваться динамический рендеринг в зависимости от размера экрана.

Отслеживание размеров окна в Inferno

Для динамического реагирования на изменения размеров окна используется слушатель событий resize. Например, в классовых компонентах:

import { Component } from 'inferno';

class ResponsiveComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      windowWidth: window.innerWidth
    };
    this.handleResize = this.handleResize.bind(this);
  }

  componentDidMount() {
    window.addEventListener('resize', this.handleResize);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize);
  }

  handleResize() {
    this.setState({ windowWidth: window.innerWidth });
  }

  render() {
    const { windowWidth } = this.state;
    return (
      <div>
        {windowWidth < 768 ? (
          <p>Мобильная версия</p>
        ) : (
          <p>Десктопная версия</p>
        )}
      </div>
    );
  }
}

Для функциональных компонентов с хуками используется useState и useEffect:

import { useState, useEffect } from 'inferno-hooks';

function ResponsiveFunctional() {
  const [windowWidth, setWindowWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWindowWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return (
    <div>
      {windowWidth < 768 ? (
        <p>Мобильная версия</p>
      ) : (
        <p>Десктопная версия</p>
      )}
    </div>
  );
}

Комбинирование медиа-запросов и условного рендеринга

Оптимальная стратегия адаптивного дизайна в Inferno сочетает CSS-медиа-запросы и динамический рендеринг компонентов. CSS управляет базовой структурой и стилями, а JavaScript позволяет изменять логическую структуру компонентов, включая или исключая элементы DOM на лету.

Пример адаптивного меню:

function Navbar({ windowWidth }) {
  return (
    <nav>
      {windowWidth < 768 ? (
        <button>Меню</button>
      ) : (
        <ul>
          <li>Главная</li>
          <li>О нас</li>
          <li>Контакты</li>
        </ul>
      )}
    </nav>
  );
}

Важность производительности

Inferno оптимизирован для высокой скорости обновления виртуального DOM, что делает его подходящим для частых изменений размеров окна. При использовании медиа-запросов совместно с динамическим рендерингом важно минимизировать количество состояний, которые вызывают перерисовку, чтобы избежать лишних операций.

Адаптивные изображения и ресурсы

Для оптимизации загрузки медиа-контента применяются:

  • srcset и sizes для <img>
  • picture с различными форматами изображений
  • Ленивая загрузка (loading="lazy") для изображений вне экрана

В Inferno можно динамически выбирать изображение в зависимости от состояния окна:

const imageSrc = windowWidth < 768 ? 'image-small.jpg' : 'image-large.jpg';

return <img src={imageSrc} alt="Пример" />;

Поддержка сложных макетов

Использование CSS Grid и Flexbox позволяет создавать адаптивные макеты без излишнего JavaScript, а комбинация с Inferno обеспечивает гибкость компонентов и возможность динамической перестановки блоков, например:

.container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}
<div className="container">
  <Card />
  <Card />
  <Card />
</div>

Такой подход совместим с реактивной логикой Inferno, обеспечивая одновременно адаптивность и производительность.