Специалист по Blazor делится распространенными ошибками, которые совершают начинающие веб-разработчики, и дает советы, как их избежать.
Я ежедневно использую Blazor для создания веб-приложений уже более шести лет. В этой статье я хочу поделиться распространенными ошибками, которые совершают начинающие разработчики Blazor, и помочь вам их избежать.
Изображение создано с помощью ИИ
Ошибка №1: Отношение к Blazor как к традиционному ASP.NET Core MVC или Razor Pages
Ошибка: Новички часто полагают, что Blazor — это просто очередная эволюция ASP.NET Core MVC или Razor Pages. Особенно часто в эту категорию попадают опытные .NET-разработчики (десктопных или мобильных приложений). Важно с самого начала понять концептуальные различия.
В то время как Razor Pages и MVC ориентированы на разработку на основе страниц, Blazor ориентирован на компоненты и состояние.
В то время как Razor Pages и MVC ориентированы на разработку на основе страниц, Blazor ориентирован на компоненты и состояние.
Мышление в категориях связных, переиспользуемых компонентов — это основа создания поддерживаемых и масштабируемых веб-приложений на Blazor.
Вместо полной перезагрузки страницы мы обновляем состояние компонента и позволяем движку Blazor перерисовывать только те части пользовательского интерфейса, которые требуют обновления.
Вместо прямой отдачи HTML мы поддерживаем состояние пользовательского интерфейса с течением времени и позволяем движку перерисовывать те части страницы, которые должны быть обновлены.
Ключевой урок: Blazor — это современный фреймворк для одностраничных веб-приложений (ближе к JavaScript-фреймворкам, таким как Angular или React).
Ошибка №2: Непонимание жизненного цикла компонента (и его методов)
Ошибка: Новички часто не понимают основ модели жизненного цикла компонентов Blazor. Они используют неправильные методы для загрузки данных или запуска изменений состояния там, где этого делать не следует, что вызывает ненужные перерисовки (проблема производительности).
Каждый метод жизненного цикла имеет определенную цель и время выполнения. Важно размещать код в правильном месте. В противном случае может возникнуть неожиданное поведение.
Каждый метод жизненного цикла имеет определенную цель и время выполнения. Важно размещать код в правильном месте. В противном случае может возникнуть неожиданное поведение.
Типичные проблемы:
- Данные загружаются дважды
- Мерцание интерфейса (множественные изменения)
- Проблемы с производительностью
Краткий обзор или эмпирическое правило:
- OnInitialized/OnInitializedAsync выполняются один раз при создании компонента и добавлении его в дерево компонентов.
- OnParametersSet/OnParametersSetAsync запускаются каждый раз при изменении параметра компонента.
- OnAfterRender/OnAfterRenderAsync запускаются после отрисовки пользовательского интерфейса.
Например, если вы поместите логику загрузки данных в метод жизненного цикла OnInitialized, а ваш компонент зависит от параметра компонента (например, ID пользователя), код загрузки данных не будет вызван при изменении ID пользователя.
Правильный подход — поместить код загрузки данных в метод жизненного цикла OnParametersSetAsync:
Еще одна ошибка — загрузка данных в методе жизненного цикла OnAfterRenderAsync. Чтобы заставить Blazor перерисовать компонент, нужно вызвать метод StateHasChanged. Это приводит к бесконечному циклу изменений состояния и перерисовок компонента.
Если нам нужно использовать метод OnAfterRenderAsync в определенных случаях (например, для взаимодействия с DOM/JavaScript), всегда используйте аргумент firstRender, чтобы выполнять код только при первой отрисовке.
Эмпирическое правило: используйте OnInitializedAsync для статической настройки, а OnParametersSetAsync — для всего, что зависит от параметров.
Ключевой урок: изучение основ модели жизненного цикла компонентов Blazor и размещение кода в правильном методе жизненного цикла помогает избежать многих проблем, созданных своими руками (например, ненужных потерь производительности).
Ошибка №3: Неправильная обработка состояния
Ошибка: Новички иногда дублируют состояние, помещая всё в состояние компонента или в общее (глобальное) состояние.
Как правило, размещайте состояние как можно ближе к месту его использования.
Как правило, размещайте состояние как можно ближе к месту его использования.
- Например, компонент счетчика должен отслеживать состояние (число) как свойство состояния компонента.
- Используйте параметры компонента, когда родительский компонент управляет информацией, предоставляемой дочернему компоненту. Типичные сценарии включают шаблоны «мастер-деталь», где родительский компонент отображает список пользователей, а дочерний компонент предоставляет детали для конкретного пользователя.
- Используйте каскадные параметры для информации, разделяемой на нескольких уровнях одного и того же дерева компонентов. Например, предоставьте ID клиента в качестве каскадного значения, когда всё дерево компонентов предоставляет подробную информацию о его контрактах и записях общения.
- Используйте сервисы для обмена информацией между несколькими (несвязанными) деревьями компонентов. Например, используйте сервис для отслеживания выбранного языка пользовательского интерфейса.
Узнайте, когда использовать параметры компонентов, каскадные параметры, сервисы и локальное состояние.
Ключевой урок: используйте локальное состояние (состояние компонента) там, где это возможно, и используйте общее состояние, когда это необходимо. Используйте контейнеры состояния (сервисы) там, где это применимо.
Ошибка №4: Игнорирование производительности рендеринга
Ошибка: Некоторые новички не осознают, что ненужные перерисовки происходят чаще, чем ожидается, замедляя работу веб-приложения.
Всякий раз, когда изменяются параметры компонента или локальное состояние (свойства или поля компонента), Blazor запускает перерисовку. Кроме того, события и другие механизмы внутри фреймворка Blazor могут потенциально вызвать перерисовку компонента.
Первая оптимизация, которая приходит на ум, — это разделение большого компонента на несколько компонентов.
Например, компонент профиля пользователя может отображать данные из восьми разных частей приложения. Допустим, мы реализуем его с помощью одного компонента; изменение одного свойства (например, обновленный статус «в сети») вызовет перерисовку всего профиля пользователя.
Если мы разделим компонент на разные дочерние компоненты, по одному для каждого раздела приложения, то при изменении статуса пользователя на экране будет перерисован только компонент UserOnlineState.
Еще одна упускаемая из виду проблема производительности — чрезмерное использование двусторонней привязки в формах.
Подумайте об использовании свойства @onchange, чтобы запускать обновление только тогда, когда пользователь покидает поле ввода, вместо запуска обновления при каждом нажатии клавиши.
Третья потенциальная проблема производительности — вычисление ресурсоемких данных при каждой отрисовке, а не только при изменении параметра. Использование методов OnParametersSet/OnParametersSetAsync для вычисления ресурсоемких данных является лучшей практикой.
Ключевой урок: тестируйте производительность вашего компонента и избегайте ненужных перерисовок.
Ошибка №5: Смешивание слишком большого количества логики в компонентах
Ошибка: Новички часто смешивают логику пользовательского интерфейса с бизнес-логикой, доступом к данным и управлением состоянием в компонентах Blazor.
В целом, мы хотим иметь небольшие, связные и переиспользуемые компоненты. Однако важен не только размер, но и форма.
В целом, мы хотим иметь небольшие, связные и переиспользуемые компоненты. Однако важен не только размер, но и форма.
При первом знакомстве с Blazor разработчики часто склонны перегружать компоненты Blazor логикой. Хотя код пользовательского интерфейса, такой как логика взаимодействия, отлично подходит для компонентов, мы не хотим реализовывать логику доступа к данным внутри них.
Вместо этого мы должны использовать внедрение зависимостей (dependency injection) для подключения сервисов доступа к данным в наши компоненты Blazor.
Разделение ответственности по-прежнему важно при разработке веб-приложений на Blazor. Мы хотим, чтобы бизнес-логика оставалась чистой и не зависела от фреймворка пользовательского интерфейса. Она должна быть пригодной для повторного использования и обмена при создании будущих приложений.
Вынос логики в повторно используемые, тестируемые и масштабируемые сервисы является ключевым моментом при разработке приложений любого значимого размера, и это также справедливо для всех веб-приложений Blazor.
Ключевой урок: архитектура приложения также важна для веб-приложения Blazor. Соблюдайте разделение ответственности и размещайте в компонентах Blazor только тот код, который там должен быть (код пользовательского интерфейса и взаимодействия).
Ошибка №6: Непонимание различий между Blazor Server и WebAssembly
Ошибка: Новички могут выбрать неправильную модель хостинга, не понимая последствий этого решения.
Динамичный мир, особенно в интернете, заставляет верить в простые утверждения, например, что Server — это просто бэкенд, а WebAssembly всегда быстрее.
Правда в том, что принятие решения о выборе модели хостинга для вашего приложения гораздо сложнее, чем простое утверждение.
Изучите такие темы, как компромиссы между задержкой (latency) и объемом передаваемых данных (payload).
- Если для вас очень важна быстрая отзывчивость, WebAssembly может быть хорошим выбором, даже если он загружается медленнее (поскольку изначально требуется передать больше данных).
- Если для вашего приложения критически важна быстрая загрузка первой страницы, Blazor Server может стать лучшим выбором.
- Если вам нужно простое бизнес-приложение для внутреннего использования, Blazor Server может быть хорошим вариантом, так как его легко развертывать и обновлять, а также он позволяет выполнять большую часть кода на сервере (безопасность).
Убедитесь, что вы понимаете влияние выбора той или иной модели взаимодействия, прежде чем принимать решение для вашего приложения.
Ключевой урок: изучите и поймите модели взаимодействия Blazor Server и Blazor WebAssembly, прежде чем решать, что использовать для вашего приложения.
Ошибка №7: Отказ от использования повторно используемых компонентов
Ошибка: Новички иногда слишком часто копируют и вставляют код пользовательского интерфейса вместо создания компонентов.
В начале нашего пути в разработке на Blazor нам нужно понять, что накладные расходы на создание (и инстанцирование) компонента Blazor меньше, чем мы думаем, и преимущества обычно оправдывают это.
В начале нашего пути в разработке на Blazor нам нужно понять, что накладные расходы на создание (и инстанцирование) компонента Blazor меньше, чем мы думаем, и преимущества обычно оправдывают это.
Выделение небольших фрагментов в отдельные компоненты упрощает их поддержку (более сфокусированный, связный код) и делает их более пригодными для повторного использования.
Правильно параметризованный компонент также может избавить от большого количества повторяющегося кода. А шаблонизированные компоненты (Templated Components) предоставляют еще один уровень абстракции.
Это особенно важно при реализации элементов управления пользовательского интерфейса, таких как компоненты в библиотеке Progress Telerik UI for Blazor.
Ключевой урок: научитесь понимать, когда выделение компонента имеет смысл, чтобы избежать дублирования кода и обеспечить возможность его повторного использования.
Заключение
Мы все с чего-то начинаем на пути становления веб-разработчиком Blazor. Сейчас, в эпоху генерации кода с помощью ИИ, мы стоим на плечах гигантов и можем учиться на ошибках, которые совершили другие.
В этой статье я поделился ошибками, которые чаще всего вижу у начинающих веб-разработчиков Blazor. Есть и другие подводные камни, но избегание упомянутых уже поставит вас на шаг впереди большинства новичков.
Если вы хотите узнать больше о разработке на Blazor, посмотрите мой бесплатный ускоренный курс по Blazor на YouTube. И следите за блогом Telerik, чтобы узнать больше об основах Blazor.











