EverProduct
Фронтенд

Этап 03 · Язык

Рентген: инструменты разработчика и метод

Перед лицом бага существуют два человека: тот, кто что-то меняет и перезагружает, и тот, кто выдвигает гипотезу и проверяет её. Разница между ними — карьера.

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

Один закомментирует строку, перезагрузит, поменяет значение, перезагрузит, добавит !important, перезагрузит, переставит вызов, перезагрузит. Иногда начинает работать, и почему — неизвестно. Баг теперь спрятан, а не устранён, и ничего не выучено.

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

Отладка — не талант. Это двоичный поиск по расстоянию между тем, чего ты ждал, и тем, что произошло.

Метод

Шесть шагов. Это не ритуал: пропуск любого — и есть то место, куда уходят часы.

1. Воспроизведи надёжно. Баг, который нельзя вызвать по требованию, нельзя починить — можно только угадывать. Найди точную последовательность. Если случается «иногда», это «иногда» — улика: обычно за ним стоят тайминги, кэш или конкретная запись.

2. Сформулируй ожидаемое и фактическое точно. Не «список сломан», а «я ждал двенадцать элементов по дате, получил двенадцать элементов в случайном порядке». Половина всех багов решается честным написанием этой фразы, потому что она заставляет заметить, что именно ты знаешь.

3. Локализуй делением пополам. Где-то между уходом данных с сервера и пикселями на экране правильное стало неправильным. Проверь середину. Данные там были верные? Значит, поломка ниже по течению. Не были? Выше. Четыре деления превращают тысячу строк в шестьдесят.

4. Выдвини одну гипотезу и сделай её опровержимой. «Дата приезжает строкой, поэтому сравнение лексикографическое» — проверяется за десять секунд. «Что-то не так с сортировкой» — не гипотеза, а пересказ симптома.

5. Меняй одно. Поменяешь три — и если заработает, ты не узнал ничего и не сможешь откатить два лишних.

6. Убедись, что починка объясняет всё. Если баг ушёл, а сказать почему ты не можешь, значит, он не ушёл, а переехал. Этот шаг пропускают на усталости, и именно он отвечает за появление того же бага через три недели.

Прочитай сообщение

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

«Cannot read properties of undefined (reading 'name')» сообщает три вещи: ожидался объект, оказался undefined, и чинить надо там, где это значение должно было появиться, а не на строке, где взорвалось.

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

Панели, в которых ты будешь жить

Elements — настоящий DOM, который не всегда совпадает с твоим HTML. Выбери элемент, и панель стилей покажет все применившиеся правила, что было перебито и каким получилось итоговое вычисленное значение. Это ответ почти на любой вопрос по CSS за две секунды, а схема блочной модели внизу говорит, откуда взялись отступы. Соседняя вкладка Accessibility показывает второй интерфейс из соответствующей статьи.

Console — ошибки, предупреждения и твой собственный вывод. console.log легитимен, это не «инструмент для новичков», как иногда намекают. Но у него есть родственники получше: console.table для массивов объектов превращает двадцать строк шума в читаемую таблицу; console.time меряет; console.count отвечает на «сколько раз это выполнилось»; console.trace — на «кто это вызвал». А $0 ссылается на элемент, выбранный сейчас в Elements, и позволяет потыкать в него живьём.

Sources — место, где отладка становится серьёзной. Ставишь точку останова, выполнение замирает, и видны все переменные в области видимости и весь стек вызовов. Информации здесь строго больше, чем даёт console.log, потому что видно всё в этот момент, а не одну вещь, которую ты догадался напечатать.

Продвинутые формы стоит выучить рано: они превращают невозможные баги в обычные. Условные точки останова (замереть, только когда идентификатор равен 4712, вместо прохода по четырёмстам итерациям), точки останова на DOM (замереть, когда что угодно меняет этот элемент, — так находится таинственный код, правящий твою кнопку) и точки останова на запросах (замереть при обращении к этому адресу).

Network — коды статусов, тайминги, заголовки, реальное отправленное и полученное тело. Когда фронтенд и бэкенд расходятся во мнениях, чья это вина, эта панель закрывает спор одним скриншотом. Ограничение скорости и «отключить кэш» живут здесь же.

Application — локальное и сессионное хранилище, куки, сервис-воркеры. Здесь получают ответы «почему до сих пор залогинен?» и «почему отдаётся старая версия?».

Performance — диаграмма того, чем был занят главный поток. По-настоящему ею пользуется следующая статья; пока достаточно знать, что она есть и показывает длинные задачи.

Точки останова против логов

Оба инструмента верные и разной формы.

Точки останова отвечают на вопрос «каково состояние в этот момент»: все переменные, весь стек, живьём. Бери их, когда что-то не так здесь и непонятно почему.

Логи отвечают на вопрос «что происходило во времени и в каком порядке» — ровно то, в чём точки останова плохи, потому что пауза меняет тайминги и пройти паузами сотню итераций некомфортно.

Итого: логи для последовательностей и асинхронного порядка, точки останова для состояния. Ещё два слова в словарь: инструкция debugger в коде — это точка останова, которую можно временно закоммитить и засунуть внутрь условия, а «блэкбоксинг» библиотечных файлов не даёт отладчику проваливаться во внутренности фреймворка, которые тебе не интересны.

Когда «у меня работает»

Эта фраза — не отговорка, а список гипотез. Между твоей машиной и их машиной что-то отличается, и кандидаты известны: кэш (жёсткая перезагрузка или приватное окно), расширения (они внедряют скрипты и режут запросы), другой браузер, другие данные (у них в аккаунте пятьдесят записей, или пустое поле, или имя с апострофом), размер экрана, скорость сети, локаль и часовой пояс — классический баг со съехавшей на день датой — и сборка старее той, которую ты, как тебе кажется, тестируешь.

Пройти по этому списку продуктивнее, чем в пятый раз смотреть в уже прочитанный код.

Части, которые не про технику

Объясни вслух. Резиновая уточка работает, и сфера «Как учиться» объясняет почему: в голове знание существует черновиком, где ощущение связности подменяет настоящие связи. Речь заставляет черновик стать предложениями, и дыра всплывает прямо посреди фразы — обычно той, где ты говоришь «а потом он берёт идентификатор из… погоди».

Отойди. После долгого пристального смотрения сфокусированный режим гоняет один и тот же маршрут по тем же трём файлам. Рассеянный режим — прогулка, душ, другое дело — находит маршрут, которым ты не ходил. Это не метафора, это статья про два режима, и баги решаются в душе именно потому, что отойти — техника, а не капитуляция.

Ограничь время. Тридцать минут без продвижения означают, что неверна стратегия, а не что нужно ещё сорок минут той же стратегии. Меняй что-то структурное: спроси кого-нибудь, объясни кому-нибудь, перепиши кусок с нуля или начни с первого шага.

Веди журнал багов. Три строки на каждый настоящий баг: симптом, настоящая причина, как нашёл. Через месяц ты увидишь собственные повторяющиеся категории — «я постоянно предполагаю, что данные приехали», «я постоянно забываю про порядок асинхронного», — и это ценнее любого списка общих советов, потому что это про тебя. Это тот самый разбор полётов, который сфера «Как учиться» рекомендует после экзаменов, применённый к тому, что ты делаешь ежедневно.

На практике

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

Изучай по одной панели в неделю. Elements, потом Console, потом Sources, потом Network. По двадцать минут, с разносом по времени, — это осознанная практика на инструменте, которым ты будешь пользоваться ближайшее десятилетие.

Замени три console.log точкой останова и посмотри на всю область видимости. Большинство людей так и не видят, насколько больше там информации.

Примени console.table к следующему массиву объектов. Мелочь с мгновенно очевидным выигрышем.

Пиши фразу «ожидал — получил» до того, как что-либо трогать. Каждый раз.

Заведи журнал багов сегодня, пусть даже три строки в неделю.

Проверь себя

Закрой статью и ответь своими словами:

  1. Каковы шесть шагов метода и какой из них пропускают на усталости?
  2. Почему «починка работает, но я не знаю почему» — не починка?
  3. Как читать стек вызовов и с какой строки начинать?
  4. Что говорит панель стилей такого, чего не даёт угадывание?
  5. Когда точка останова лучше лога, а когда наоборот?
  6. Перечисли шесть гипотез за фразой «у меня работает».
  7. Почему объяснение бага вслух так часто его решает?

Коротко

  • Отладка — это метод: воспроизвести, сформулировать ожидаемое и фактическое, поделить пространство поиска пополам, выдвинуть одну опровержимую гипотезу, поменять одно, убедиться, что объяснение полное.
  • В сообщении об ошибке и стеке вызовов обычно уже есть ответ; читай их целиком и начинай с первой строки собственного кода.
  • Elements отвечает на вопросы по CSS за секунды, Network закрывает спор фронта с бэком, Sources показывает все переменные в моменте, Application объясняет застрявшее состояние.
  • console.table, console.time, console.count, console.trace и $0 стоят больше, чем ещё один console.log.
  • Точки останова показывают состояние, логи — последовательность, а условные, DOM- и сетевые точки останова превращают невозможные баги в обычные.
  • «У меня работает» — это список гипотез: кэш, расширения, браузер, данные, размер, сеть, локаль, сборка.
  • Объяснение вслух вскрывает дыру, отход включает рассеянный режим, а тридцать минут без продвижения означают смену стратегии, а не удвоение усилий.
  • Журнал багов в три строки показывает твои собственные повторяющиеся категории ошибок — обратную связь, которую больше взять негде.