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

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

Обсудить проект @YuraAndreev
Download Telegram
Самое время поставить точку
#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
Вооружен и опасен
#qa #frontend

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

PerfectPixelпозволяет накладывать изображение поверх открытого сайта, регулировать масштаб картинки, позицию и степень прозрачности. Используется по назначению — для максимально точного сравнения макета сайта с его сверстанной версией. В Студии его применяют как QA, так и разработчики.
Chrome | Safari | Firefox | Opera | IE | Edge

Form Filler — автоматически заполняет все формы на странице случайными данными, умеет работать с радиокнопками, выпадашками, понимает типы полей. Спасательный круг для тех, кто тонет в тестировании форм, имеет открытый исходный код.
Chrome | Edge | Firefox

WhatFont — при клике на текст отрисовывает в этом месте плашку со всей информацией о его шрифте. Пользоваться расширением быстрее и нагляднее, чем инструментами разработчика.
Chrome | Safari

Full Page Screen Capture — по нажатии кнопки создает высококачественный скриншот всей страницы, старается учитывать все плавающие элементы в верстке, например шапку. Есть экспорт в .pdf и редактор в платной версии.
Chrome

ProKeys — для тех, кто любит много писать. Добавляет в браузер автокомплит текста при вводе кавычек и скобок, как в IDE. Умеет разворачивать любое кодовое слово в произвольный текст на основе шаблона — с поддержкой автоподстановки дат, контента из буфера обмена и быстрой навигацией по маркерам в шаблоне. Расширение полностью настраиваемое и имеет открытый исходный код.
Chrome | Opera

Check My Links — проходится по всем ссылкам на странице и проверяет их на валидность. Результат подсвечивается цветом прямо в верстке, есть базовый вывод в лог консоли и возможность экспорта детального отчета в CSV.
Chrome

JSONViewрасширение форматирует открытый в адресной строке JSON-файл в читабельный и удобный для навигации вид и валидирует его. Полезен при тестировании ответов от RESTful API.
Chrome

Bug Magnet — полезный инструмент для проведения исследовательского тестирования форм. Представляет собой набор «плохих», длинных или необычных фраз, невидимых символов, нестандартных языков, текстовых эксплоитов и далее по списку — все то, что потенциально может сломать отправку формы на сайте. Есть возможность расширять базу своими заготовками.
Chrome | Firefox

З.Ы. Устанавливайте любые расширения браузера осознанно. Говорят, что некоторые из них могут использовать ваши личные данные и майнить биткоины на ваших машинах 😎 Но это не точно 😉