Chulakov Dev – Telegram
Chulakov Dev
1.15K subscribers
140 photos
5 videos
205 links
Канал команды разработки Студии Олега Чулакова.

Советы по Frontend- и Backend-разработке web-сервисов, мобильных приложений, статьи и презентации от наших разработчиков, анонсы проектов и многое другое.

Обсудить проект @YuraAndreev
Download Telegram
Грокаем и мокаем
#mobile_native #android #kotlin

Robert Anson Heinlein «Stranger in a strange land»

В разработке сложных мобильных приложений могут протекать процессы, требующие фиктивных тестовых данных или mock-объектов. Например, процесс написания unit-тестов и запуска их в CI/CD либо демонстрация приложения в demo-режиме, где использование оригинальных источников данных невозможно или нецелесообразно.

Рассмотрим, как произвести подмену модели ViewModel на MockViewModel при реализации demo-режима приложения. Добавим в gradle-файл модуля добавим boolean-переменную, обозначив демо-сборку приложения.

Получение ViewModel во фрагменте выглядит так:
ViewModelProviders.of(yourFragment).get(YourViewModel.class)


Реализуем класс ViewModelHolder, который будет уточнять класс модели ViewModel исходя из используемого режима приложения.

Во всех фрагментах приложения мы можем использовать вызов метода getViewModel класса ViewModelHolder для получения нужной модели.

ViewModelHolder.getViewModel(this,YourViewModel::class.java)


Если описать свою модель MockYourViewModel, наследуя ее от YourViewModel, то в ней необходимо будет переопределить только те методы, которые нужно мокнуть. В gradle можно явно указать, какой тип ViewModel необходимо использовать. А использование BuildConfig.IS_DEMO не будет дублироваться по всему приложению.
Самое время поставить точку
#frontend #debug #react #nodejs

Каждый современный браузер, даже IE, имеет встроенные средства отладки клиентского JavaScript. У Chrome, например, есть инструменты разработчика, которые позволяют расставлять точки останова, выводить отладочную информацию и в режиме реального времени работать с некоторыми объектами js.

У такой отладки есть минусы — вы отлаживаете уже скомпилированный js, например из EcmaScript или TypeScript. Получается, что код пишется на одном языке, а отлаживается — на другом. Иногда удобно сразу исправлять код в момент отладки.

Наши frontend-разработчики используют IDE Visual Studio Code, в которой есть удобные встроенные средства отладки кода 🐞

VS Code позволяет настраивать различные сценарии отладки — можно отлаживать и серверный, и клиентский js.

Для настройки дебагера в VS Code используется файл ./vscode/launch.json. Чтобы мы могли отлаживать браузерный js, понадобится расширение, сопрягающее работу отладчика с браузерами движка Chrome. Для отладки nodejs-кода будем использовать вот это расширение.

Microsoft создала даже сборник рецептов настройки отладчика для различного типа приложений и языков разработки.
Например, для отладки кода на Next.js можно взять за основу вот эту инструкцию (https://github.com/Microsoft/vscode-recipes/tree/master/Next-js) и отлаживать как клиентскую, так и серверную часть вашего приложения. Не забудьте включить source-maps в настройках сборщиков для Dev-режима, чтобы отладчик показывал исходный, а не транспилированный код.

Старайтесь минимизировать использование механизмов псевдоотладки, типа console.log. Отладка в режиме runtime дает вам полностью объективную, живую картину состояния ваших переменных, объектов и текущего хода выполнения. Вы производите отладку внешними средствами, не изменяя свой код, и спите спокойно, не думая о том, что ваши console.log() проявят себя на промышленном сервере или в браузере у конечного пользователя 🙃
Барабаним сами
#mobile_dev #android #kotlin

Хочу такой барабан, как на iPhone

Спорить о юзабилити стандартных элементов управления мобильных ОС можно вечно. Мы не будем.

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

На «Хабре» есть статья, которая рассказывает, как создавать Picker через Canvas. Такой подход имеет ряд недостатков. Например, сложность реализации анимированной плавной прокрутки с ускорениями и необходимость реализации метода onDraw для однотипных, но разных интерфейсов.

Реализуем вариант бесконечного барабана через SnapHelper. Picker будет оперировать списком строк List<String>, который передается в конструктор адаптера для RecyclerView. Количество элементов в этом RecyclerView будет Integer.MAX_VALUE. За счет этого мы добьемся «бесконечной» прокрутки списка.

Для реализации эффекта барабана при прокрутке определим класс SlideLayoutManager. Метод onScrollStateChanged, помимо вызова суперметода, для каждого элемента вычисляет расстояние до центра RecyclerView и возвращает позицию элемента с минимальным расстоянием. Метод scrollVerticallyBy с помощью функции scaleDownView производит корректировку визуальных составляющих элементов, например размера и цвета.

Пример инициализации Picker можно увидеть здесь.

Реализацию XML-разметки picker_item, а также размещение RecyclerView в разметке Layout оставим за кадром этой заметки.

Оперируя различными визуальными эффектами, можно изменять внешний вид и поведение нашего барабана.
Останься в памяти моей
#frontend #backend #reactjs #nodejs

Даже опытный react-разработчик может не до конца осознавать, как используется оперативная память компонентами его приложения. Недавно мы обнаружили memory leak в сервисе — через N дней многопоточное приложение на стороне SSR переставало работать из-за нехватки оперативной памяти.

Оказалось, что при очередном запросе пользователя составной заголовок страницы записывался в глобальный объект, не затирая предыдущие значения.

Встречается распространенная проблема, при которой react-компонент был размонтирован, но инициализированные в нем setTimeout или setInterval не были остановлены и продолжают выполняться в фоне. Сборщик мусора не будет выполнять очистку памяти от данных, используемых в этих методах, следовательно, происходит систематическая утечка памяти.

С ростом кодовой базы продукта увеличивается и объем хранимой информации как на стороне клиента, так и на стороне сервера. Повышается вероятность возникновения новых утечек.

На стороне клиента контролировать потребляемую браузером память и работу сборщика мусора помогают инструменты разработчика. Например, браузер Google Chrome и его DevTools позволяют делать периодические снепшоты состояния памяти в различные промежутки времени работы приложения. Снимки можно анализировать и сравнивать между собой специальными средствами.

На серверной стороне также возможно настроить мониторинг используемой памяти. Для этого необходимо запустить nodejs с флагом --inspect и открыть в Chrome специальную страницу chrome://inspect. Здесь настраивается интеграция с серверной частью вашего приложения для работы отладочного механизма. Затем процесс работы со снимками памяти сервера и их анализа происходит в таком же интерфейсе, как и в случае с клиентской частью.
Жадный импорт
#backend #php

Разрабатывая веб-сервис для крупного застройщика, мы столкнулись с задачей импорта большого количества номенклатурных данных. Причем данные выгружались из различных корпоративных систем клиента и представляли собой файлы формата csv и xml.

Данные импорта содержали информацию об объектах застройки с подробными их характеристиками. Данные по каждому объекту перед сохранением в БД должны были проходить определенный препроцессинг в виде валидации, проверок существования справочной информации и определения операции вставки/изменения. Все стандартно.

Осуществляя считывание информации об объектах из различных файлов, мы накапливали информацию на промежуточных шагах в массивы. Затем обрабатывали каждый элемент этого массива — создавали промежуточные объекты для валидации и в конечном итоге модели для сохранения. Упрощенный псевдокод такого подхода можно посмотреть здесь.

При импорте большого количества данных из множества разнородных файлов потребление оперативной памяти становилось все больше. В один момент импорт съел 2 Гб.

«Хватит это терпеть», — сказал разработчик Илья и призвал на помощь генераторы. Их использование позволило избавиться от промежуточных накоплений и обрабатывать данные построчно на лету. Весь процесс импорта после внедрения генераторов стал занимать практически константное значение потребляемой RAM.

Наш псевдокод немного преобразился. Стоит отметить, что использование генераторов делает код чище и позволяет работать с нативными итераторами в PHP.
​​React: профилирование жизненного цикла
#frontend #reactjs

Среди React-разработчиков популярно браузерное расширение React DevTools, позволяющее отлаживать клиентскую часть React-приложения. Это расширение содержит полезный инструмент профилирования, который нативно поддерживается самой библиотекой React, начиная с версии 16.5.

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

Рассмотрим пример уровня кода. В функциональный компонент SomeList передается объект с данными состояния dataSource из родительского компонента App. SomeList содержит дочерний компонент SomeItem, который оперирует переданным ему dataSource-объектом. При обновлении состояния в компоненте App, даже если сам объект dataSource не изменился, производится цепной ререндер нижестоящих компонентов SomeList и SomeItem, которые отслеживают dataSource. В данном случае обновление этих компонентов является избыточным.

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

В текущем примере для оптимизации повторного рендеринга компонентов применим механизм мемоизации, представленный в HOC React.memo(...). Теперь запустим профилировщик и почувствуем разницу.

На Reactjs.org есть отличное введение, которого будет достаточно для базовой проверки своих проектов.
Алина и Тайный Санта
#algorithms #math #jokes

Посвящается нашему офис-менеджеру Алине

Новогодние поздравления в Студии проходят по принципу церемонии Тайного Санты. Как же офис-менеджеру Алине организовать этот процесс, сохраняя максимальную анонимность, при условии что в Студии работает 100+ человек? 😱

Каждый сотрудник должен получить адресованный ему подарок, иначе на общем вручении выйдет конфуз.

Алина берет список всех сотрудников у HR Дарьи и садится за разработку алгоритма (идет к старшему разработчику Александру).

Чтобы организовать случайность пар «дарящий — получатель», список сотрудников перемешивается и помещается в массив L1. Затем элементы множества L1 циклически смещаются в любую сторону на число, не равное length(L1), и записываются в новый массив L2.

Теперь в L1[i] находится отправитель подарка для получателя L2[i]. Читателю должно быть очевидно 😂, что получившееся отображение f: L1 -> L2 биективно, а потому подарки достанутся всем. 🎁

Пары получены, но наша Алина делала все вручную, и теперь она знает все «тайны» и, что самое обидное, знает, кто подарит подарок именно ей. Исправим это с помощью HR Дарьи.

Даша и Алина делят список L1 на L11 и L12 таким образом, что Даша находится в одном списке, а Алина — в другом. Каждая из девочек выбирает себе половину списка, в котором нет ее фамилии/имени. Повторим процедуру перемешивания и сдвижки для списков L1j, сохраняя список со сдвигом в L2j. Теперь в L1j[i] находится отправитель подарка для L2j[i], где j = 1,2. Очевидно, что полученные отображения f1j: L1j -> L2j также биективны. Все учтено при полной секретности. 😎

З.Ы. Реализацию алгоритма оставим на усмотрение любопытного читателя. С наступающим Новым годом и Рождеством! 🎄
Контент — это мы
#backend #frontend #qa #mobile

Авторы заметок канала Chulakov Dev — это реальные люди, лучшие специалисты Студии №1 в России.

Уникальный контент — это реальный опыт решения насущных и сложных задач в рамках крупнейших проектов.

Команда Студии Олега Чулакова поздравляет вас с Новым годом и Рождеством. В наступившем 2020 году мы продолжим публикации и постараемся сделать их еще интереснее.
Отлично, оптимизируем дальше
#backend #php #orm

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

Первоначально, в пострелизный период, сервис хранил и обрабатывал около 300 квартир с сопутствующими номенклатурными данными. Для обеспечения реактивности интерфейсов и удобства вывода данные о сущностях и их атрибутах собирались в единую структуру. Это позволяло достаточно быстро перестраивать клиентский вывод без дополнительных REST-запросов, при этом фильтруя и сортируя данные.

Сервис развивался, и в какой-то момент нам выгрузили 1200 квартир. С учетом всех реляций количество связанных объектов стало достаточно большим — на одну квартиру приходилось около 12 связанных объектов с нетривиальной выборкой через ActiveRecord-модели. Конечный набор json-данных стал формироваться за 4 секунды.

«Хватит это терпеть», — сказал разработчик Илья и принялся оптимизировать, вооружившись профайлером и литром пива. Исходные данные профайлера: 4 секунды, 64 Мб памяти и более 140 запросов в БД. Используя эти данные, мы добавили недостающие индексы по ключам на уровне СУБД, а самое главное — мы оптимизировали реляции в ActiveRecord-моделях и сократили количество запросов к БД. После первой итерации профайлер показал следующее: 3 секунды, 32 Мб памяти и 80 запросов в БД.

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

После этой итерации мы получили следующие результаты: 1,5 секунды исполнения, 24 Мб и 54 запроса. Профайлер показал, что бОльшая часть времени тратится на манипуляции с ActiveRecord-моделями — инициализация и маппинг данных в объекты.

«Не на массивах же все это делать»

На последнем этапе оптимизации мы отказались от использования ORM. ActiveRecord-модели были заменены на заполнение простых DTO-объектов. Общение с БД и выборку данных мы реализовали через построитель запросов фреймворка Yii. Финальный результат: 0,4 секунды, 18 Мб памяти и около 32 запросов в БД.
​​ViewPager2. Подглядываем красиво
#mobile_native #android #java

20 ноября 2019 года вышла в релиз стабильная версия нового инструмента для пошагового показа экранов в ОС Android — ViewPager2. Переход с первой версии облегчается преемственностью синтаксиса ViewPager. Также новый компонент использует адаптеры на основе абстрактных классов RecyclerView.Adapter или FragmentStateAdapter при работе с фрагментом.

Произведем инициализацию ViewPager2 таким образом, чтобы были видны половинки предыдущей и последующей страниц.

Реализуем свой адаптер и сверстаем элемент, используемый в нем. YourAdapter готов к работе.

Реализацию фрагмента, содержащего ViewPager2, можно посмотреть здесь.

Необходимо заставить объект viewPager игнорировать padding-ограничения. За это отвечают строки 14 и 15 класса YourFragment.java.

В качестве объекта-трансформера страницы мы устанавливаем экземпляр класса YourPagerTransformer, который позволяет показывать часть левого и правого элемента списка при скролле.

Если ширина экрана WIDTH пикселей, а контент в layout/item.xml занимает x пикселей, то величина marginPx, которая будет передаваться в YourPagerTransformer, должна находиться в пределах WIDTH - x < marginPx < (WIDTH - x) / 2, чтобы левый и правый элемент были видны. Иначе они сдвинутся недостаточно далеко, чтобы показаться, или наложатся друг на друга.

Стоит отметить, что с помощью различных реализаций PageTransformer можно применять разные эффекты прокрутки.
Простая UI-локализация
#mobile_dev #ios #swift

Apple Xcode позволяет локализовывать интерфейсные статические текстовые метки, ресурсы приложения — иконки, изображения, звуковые файлы и форматы вывода даты/время/валюты/единиц измерения.

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

Первым делом в Xcode создается файл Localizable.strings, который на уровне проекта является агрегацией файлов с переводами текстовых меток на различные языки. А на уровне файловой системы для каждого языка будет создана папка <LocaleId>.lproj и файл Localizable.strings в ней.

В составе фреймворка Foundation для локализации строк предусмотрена глобальная функция NSLocalizedString.

Функция NSLocalizedString под капотом вызывает метод localizedStringForKey:value:table: объекта Bundle приложения, который возвращает локализованную строку.

Упростим себе жизнь. Чаще всего фразы переводов в рамках одного источника ресурсов можно хранить в одной таблице. Тогда можно создать свою функцию-обертку local, которая получает только параметр key.

Файлы Localizable.strings содержат пары «"ключ" = "значение"», где ключом выступает параметр, переданный нашей функции local(), а значением — языковая вариация строки.

Например, этот код демонстрирует процесс получения значений заголовка, сообщения и текста кнопки для системного алерта.
Языковые фразы, например, для русской локализации будут извлечены из этого файла.
Алло, мы ищем таланты!
#job #frontend #react #redux

Если ты уверенный Frontend Developer и не понаслышке знаешь про React.js + Redux, а также работаешь с Next.js, то ты именно тот человек, который нам нужен.

Сегодня мы ищем сразу несколько супергероев:
Middle Frontend Developer в наш московский офис для работы над проектом крупнейшего банка, в офисе клиента (блек-джек, штаб-квартира и daily cash прилагаются);
Middle+ или Senior Frontend Developer в главный ростовский офис для управления командами разработчиков и работой над лучшими проектами страны.

Звони или пиши нам:
+7 863 303-61-91
hr@chulakov.ru
https://vk.com/olegchulakovstudio
https://www.instagram.com/chulakov.ru

Ты нужен нам, а мы — тебе 😎
​​Сюрпризы с UITableView
#mobile_dev #ios #swift

С помощью стандартного табличного класса UITableView из UIKit часто необходимо показать алерт-сообщение по тапу на определенную ячейку.

Если у ячейки таблицы установлен cell.selectionStyle = .none, то желаемый алерт будет отображен с заметной задержкой. Баг воспроизводится с iOS 8.1 и до сих пор не исправлен.

Избавиться от такого странного поведения можно, обернув код вывода алерта в dispatch-блок так или так.

При использовании других значений для свойства selectionStyle проблема не воспроизводится.
​​QR на службе у QA
#frontend #qa

Любой веб-разработчик/тестировщик сталкивается с проблемой ввода URL в адресную строку различных мобильных устройств.

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

Есть ряд способов упростить задачу передачи ссылок между устройствами, которые решают вопрос частично. Можно использовать сервисы генерации коротких URL и продолжать ручной ввод полученных адресов на разных устройствах. Существуют сервисы синхронизации устройств, что не всегда безопасно, да и одним таким сервисом для зоопарка устройств не обойтись.

Мы решаем эту проблему, используя автогенерацию QR-кодов. Для браузера Google Chrome существует полезное расширение, шифрующее ссылку текущей страницы в QR-код. Далее с помощью любого мобильного устройства сканируем этот код, и вуаля — мы на нужной странице.

Мобильные устройства Apple, начиная с версии iOS 11, нативно имеют встроенный QR-ридер в приложении «Камера». Для Android-устройств используем сторонние приложения из Google Play.

С помощью QR-кодов можно шифровать не только ссылки для перехода, но и текстовые заметки, легко передавая их между устройствами.

Рекомендуем к использованию!
Веб тестируй без труда, на любых устройствах
#qa #frontend

Браузеры на основе Chromium по праву считаются лидерами по числу активных пользователей. Технологии этой платформы применяются даже для создания кроссплатформенных десктопных приложений, например, на фреймворке Electron.

Каждый QA-инженер мечтает об отсутствии других браузеров и движков, в реалиях же имеет целый зоопарк устройств с различными версиями обозревателей. Все это семейство разнородных платформ приходится постоянно поддерживать, следить за совместимостью, обновлять, откатывать и запускать, используя виртуальные машины.

Некоторые QA-специалисты Студии работают в офисе клиента над LTS-продуктами, иногда в другом городе. В таких условиях передача или перевозка физических устройств для тестирования веб-сервисов невозможны.

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

Для того чтобы взаимодействовать с локально развернутыми в тестовом окружении веб-сайтами, облачные сервисы позволяют устанавливать VPN-подобное соединение посредством специального клиентского софта.

Примерами таких SaaS являются BrowserStack, Sauce Labs, LambdaTest. Множество сервисов и конкурентная среда удерживают цены на достаточно демократичном уровне, что позволяет сэкономить в краткосрочной перспективе деньги на физических устройствах.
Ты видишь LS? — Вот и я не вижу, а он есть!
#qa #frontend

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

Например, при копировании текста из Sketch-макета и вставке его в верстку встречается «невидимый» символ U+2028. Line Separator реализует перенос последующего за ним текста на новую строку, однако его интерпретация и поведение в обозревателе могут зависеть и от браузера, и от операционной системы. Более того, не все редакторы кода подсвечивают этот символ.

Так, при просмотре верстки в Google Chrome такие символы будут отображаться пользователю как [LSEP] в ОС Windows 10 и [x] в ОС Android. В то время как пользователям MacOS и Windows 7 с применением любых браузеров они просто не видны.

Мы решаем эту проблему с помощью линтера, заменяя или подсвечивая нежелательные символы в коде. Такие символы также идентифицируются при просмотре DOM в Chrome DevTools и отображаются в виде красной точки.
Что за ссылка такая — ref?
#frontend #react

На собеседованиях мы обычно спрашиваем соискателя, что такое ref в React. Ответ часто таков: «Ref — это ссылка на DOM-узел». Такое определение необратимо устарело с выходом React v16.3.0. Именно в этой версии появилось API для создания объекта ref — React.createRef().

Получение ссылки на DOM-элемент — это всего лишь один из способов использования ref в React API. В более старых версиях React можно встретить методы refs callback для решения данной задачи.

Путаница с рефами стала более очевидной с приходом React Hooks. При изменении состояния функционального компонента может понадобиться не вызывать его повторный рендер. И это задача для рефов!

Например, нам необходимо остановить таймеры, проинициализированные функциями setTimeout или setInterval по клику на кнопку. Использование React.useState() избыточно для решения такой задачи и может ввести в заблуждение других разработчиков.

Из-за большого количества вопросов и issues на GitHub в официальной документации к React Hooks появился подобный вопрос: есть ли что-то вроде переменных экземпляра?https://ru.reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables.

Мы рекомендуем именно такое определение: «ref — это объект, а его изменяемое свойство current может хранить в себе любое значение».
Проявляем смеCALCу в препроцессорах
#frontend #css #stylus #sass #less

Функция calc() дает возможность проводить математические операции прямо в CSS, причем передавать в нее можно разные единицы измерения. Чтобы использовать все возможности этой функции, необходимо обращаться из нее к переменным.

Чистый CSS позволяет делать это без проблем — обращение к переменной производится путем вызова функции var():
--offset: 16px;
.block {
width: calc(100% - var(--offset));
}

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

В SASS для вызова из calc() переменную нужно обернуть в #{ }:
$offset: 16px;
.block {
width: calc(100% - #{$offset});
}

В Less это делается похожим образом, но строка с calc() экранируется:
@offset: 16px;
.block {
width: ~"calc(100% - @{offset})";
}

В Stylus синтаксис чуть сложнее:
$offset = 16px;
.block {
width "calc(100% - %s)" % $offset
}

Если необходимо использовать несколько переменных, Stylus позволяет делать так:
$breadth = 100%;
$offset = 16px;
.block {
width "calc(%s - %s)" % ($breadth $offset)
}
Babel + core-js = ❤️
#frontend #javanoscript #babel #corejs

Новые js-фичи часто опережают возможности браузеров. Для использования современных конструкций языка разработчикам приходится применять полифилы, настраивать сборщики, проверять поддержку различных методов.

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

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

На помощь приходит Babel. Пакет @babel/presset-env подключает необходимые модули библиотеки полифилов core-js, когда в коде используются не поддерживаемые браузерами языковые конструкции. Пресет ориентируется на список браузеров, указанный в package.json.

Чтобы Babel автоматически добавлял нужные полифилы в бандл, нужно создать в корне проекта babel.config.json. Такая конфигурация будет проверять пакеты из node_modules и добавлять полифилы core-js в соответствии с browserlist, указанном в package.json.

Вместо большого количества импортов и отказа от современных методов JavaScript можно добавить всего 14 строк в конфигурацию Babel. Подробнее о конфигурации Babel можно почитать здесь, о полифилах — тут.
Да грузись ты уже 😡
#qa #frontend

Уважающий себя веб-сервис с клиентской браузерной частью немыслим без наличия хорошо проработанной мобильной версии и адаптивности интерфейсов. Такое веб-приложение должно быстро и без сбоев работать в условиях мобильного интернета, с переменной скоростью соединения 3G/LTE-сетей.

Frontend-разработчики часто применяют принцип отложенной загрузки ресурсов для оптимизации скорости подачи контента и функционала пользователю. Сначала показывается только необходимый контент, а тяжелые ресурсы подгружаются асинхронно, в процессе взаимодействия с текущим интерфейсом. Например, когда пользователь сделает скролл до нужного блока.

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

Представим, что основной скрипт main.js пытается вызвать методы some-library-noscript.js, которые загружаются асинхронно. Без проверки доступности методов библиотеки или события, срабатывающего на ее загрузку в main.js, пользователь потеряет необходимый ему функционал и не решит свою целевую задачу.

Чем выше скорость интернета — тем больше шансов упустить заветную ошибку.

Начинающий разработчик может неверно реализовать динамическую подгрузку ресурсов, а QA-инженер должен об этом помнить и считать каждого разработчика начинающим 😂

Узнать, как правильно организовать асинхронность загрузки ресурсов, вам помогут полезные ссылки ниже 👇

Lazy Loading Images and Video
Скрипты: async, defer
Dynamic imports
Ошибки быть не должно!
#frontend #react #nextjs

Когда пользователь взаимодействует с веб-ресурсом, помимо ожидаемого результата, он может наблюдать специальные страницы, отображающие нештатные ситуации в виде http-исключений. Разрабатывая сервисы на Next.js, необходимо управлять выводом таких страниц, анализируя ответы от RESTful API. А с учетом технологии SSR обработчик должен уметь изменять Status Code при отдаче страницы с сервера.

Коробочное решение фреймворка позволяет обработать 404 и 500 http-статусы и кастомизировать вывод страниц для них. При этом обработчик не учитывает случай, когда скрипт страницы загружен, а метод API вернул статус >= 400.

Мы решили отказаться от стандартного способа перехвата и обработки http-исключений в пользу собственного хелпера handleResponseStatus.js.

В хелпере мы учли возможность добавления «глобальных» запросов, таких как авторизация, и «параллельных» запросов, например загрузки меню сайта. Эту задачу решает callback-функция requestFunction, которая возвращает Promise.all. В теле колбека можно контролировать последовательность выполнения с помощью async/await, а в Promise.all — добавлять параллельные запросы.

Осталось привести пример использования хелпера в _app.js и поделиться полезными ссылками 👇

NextJS | getInitialProps
NextJS | Custom Error
ReactDOMServer