Что такое tracing в google chrome
Возможно, вы знаете, что у браузере Google Chrome есть встроенный профилировщик. Но даже из тех людей, кто его видел, большинство считает, что использовать его можно только для отладки Javascript или отрисовки кадров в браузере. Но на самом деле его весьма просто можно прикрутить в качестве средства визуализации данных профилирования в вашем проекте.
Я не открою здесь каких-то уникальных секретов, например, Colt McAnlis писал о подобном применении профилировщика Chrome в игровых проектах ещё в 2012 году. Всё, написанное там, всё ещё является правдой, а я напишу ещё один материал — просто для лучшего распространения знаний о столь полезном инструменте.
7. Копирование изображения в виде Data URL
Есть два способа работы с изображениями, выводимыми на веб-страницах. Первый способ заключается в загрузке изображений из внешних источников. Второй — в кодировании изображений в виде так называемых Data URL. На MDN можно узнать о том, что Data URL — это URL с приставкой :data. Такие URL позволяют встраивать прямо в документ файлы небольшого размера. Раньше их называли «Data URI», так было до тех пор, пока это название не было выведено из обращения WHATWG.
Как, пользуясь Chrome, превратить изображение в Data URL?
Ниже приведена анимированная демонстрация этого процесса.
Копирование изображения в виде Data URL
Использование Chrome Tracing
Всё, что нам нужно сделать, это:
- Создать JSON-файл определенного формата, содержащий данные о профилируемых событиях
- Открыть в Chrome страницу chrome://tracing
- Перетащить JSON-файл на эту страницу
Преимущества данного подхода:
- Значительно улучшенный UI: зум, скрол, фильтрация, статистика и т.д.
- Нам больше не нужно писать свой (пусть даже простой) код для UI
- Значительно упростившийся код по сбору и обработке данных (JSON создать проще, чем SVG)
10. Обращение к текущему выделенному элементу из консоли
Поговорим об ещё одной «магической» переменной, которой можно пользоваться в консоли. Это — переменная $0 . Она позволяет обратиться из консоли к элементу, который выделен в панели Elements.
Обращение к элементу с помощью $0
13. Сохранение ссылки на DOM-элемент во временной глобальной переменной
Если нам нужно быстро получить ссылку на DOM-элемент в консоли, мы можем выполнить следующую последовательность действий:
- Выделить элемент.
- Щёлкнуть по нему правой кнопкой мыши, вызвав контекстное меню.
- Выбрать в меню команду Store as a global variable.
Сохранение ссылки на элемент DOM в виде временной глобальной переменной
А какими малоизвестными возможностями инструментов разработчика Chrome пользуетесь вы?
Когда-нибудь трассировали рантайм вашего приложения? Знаете сколько запросов делает вон тот серый ендпоинт, который? А как долго вычитываются те кросс-референсы на схожий тип ресурсов с каждой странички сущностей, которую нужно вернуть в запрос? Пытались ли вы замерить как долго приходится ждать пользователю из-за опциональных полей запроса, которые он время от времени добавляет? Задумывались ли вы что будет если запараллелизировать эти шесть запросов к тем двум базам данных?
Если что-нибудь выше звучит интересно, или как минимум знакомо — добро пожаловать под кат.
chrome://tracing
Если ввести chrome://tracing в адресную строку Chrome, то вы попадёте на вот такую страничку:
Сам инструмент очень близко дружит с трассировочными данными самого V8 (и хрома). А с недавних пор node тоже позволяет нативно трассировать рантайм с поддержкой chrome://tracing в качестве фронтенда. Для трассировки достаточно просто нажать заветную “Record” и сделать несколько пассов над соседней вкладкой, после чего можно пронаблюдать в деталях чем именно занимался браузер, когда вы старательно болтали курсор внутри окна, хаотично крутя мышкиным колесом. Для нашего удобства, добрые люди даже написали очень подробную статью о том как интерпретировать результаты.
Формат данных, потребляемых этим визуализатором хорошо задокументирован, и отлично подходит даже для трассировки вещей отдаленных от рендеринга, вычисления разметки и отлова мусорной отрисовки. Благодаря открытости и способности загружать внешние файлы, этот трассировщик достаточно легко интегрируется с любой средой, способной на любой I/O. Кроме того, помимо самой визуализации есть и некоторые встроенные возможности для анализа групп событий. В общем, полезный и гибкий инструмент, который может пригодится и здорово помочь там, где в традиционном случае нужно было бы парсить тонны логов в поисках определенности.
Весь фронтенд трассировщика, кстати, написан на ванильном JS и лежит на GitHub. Сама chrome://tracing — обычная веб-страничка и её можно инспектировать через DevTools как и любую другую. То есть, если инструмент не сможет удовлетворить вас… полностью, то его можно спокойно помять под необходимый сценарий.
В опыте автора, необходимость в таком инструменте появилась во время работы над бессерверной системой для интерента вещей. В определенных сценариях, количество запусков лямбда функций достигало десятков и сотен для выполнения одной единственной операции. Анализировать все внутренности этих запусков по одним только логам было отнюдь не весело. Хотелось чего-то, что помогло бы окинуть картину одним взглядом целиком. Помог самописный трассировщик, который умел инструментировать внутренности наших функций и все запросы, которые они делали. О горе, автор тогда и не подозревал о существовании chrome://tracing, поэтому для трассировщика был написан с нуля фронтенд на d3, которому можно посвятить отдельный пост (tldr; не рендерьте ничего сложного через DOM, только canvas и WebGL). Давайте теперь посмотрим на несколько примеров, где трассировка помогла с оптимизацией:
Дано: асинхронный мемоизирующий сервис и несколько суб-сервисов, которые его вызывают.
Проблема: при нескольких вызовах кеширующего сервиса подряд, результат не успевает попадать в кеш, соответственно вместо одного запроса, сервис делает n.
Решение: прогревание кеша (префетч, работает если серия вызовов нуждается в одной и той же зависимости), либо ленивая блокирующая мемоизация (название импровизированное)
Дано: один из SDK при каждой инициализации делал дополнительные блокирующие запросы (и пусть весь мир подождёт) о которых мы не подозревали, они никак не логировались и не были задокументированы.
Решение: инструментирование SDK для отключения этого “вредного” запроса.
Дано: трассировка показала, что пользовательские скрипты на несколько строк выполняются на два порядка дольше ожидаемого. Дебаг показал что проблема в чрезмерном использовании переменных из глобального скоупа.
Решение: симуляция глобального скоупа для пользовательского кода через аргументы функции
Код выше симулирует глобальные переменные для скрипта через аргументы виртуальной функции (привет, CommonJS).
Дано: Некоторые сущности достаточно велики (2.5-3Мб)
Проблема: подозрение на то, что такие сущности долго и дорого загружать по сети.
Решение: трассировка показала, что загрузка таких сущностей — одна из самых дешевых операций и есть куда более глубинные проблемы требующие решения. Данные помогли сконцентрировать рефакторинг на частях системы, которые дали многократный прирост в производительности после улучшения.
Помимо этих примеров, была масса случаев, когда трассировщик помогал быстро и точно оценить последствия изменений, давал возможность смотреть на всю картину целиком, избегая “построчного” поглощения информации, в целом проявив себя как инструмент упрощающий жизнь.
Общие сведения
Вы используете инструменты разработчика Chrome для того чтобы отлаживать код.
Команда открытия инструментов разработчика
Иногда вы заходите в панель Console чтобы, пользуясь возможностями консоли, исследовать данные, которые выводит ваша программа. Иногда вы заглядываете на панель Elements чтобы взглянуть на CSS-код, который применяется для стилизации DOM-элементов.
Панель Console
Но хорошо ли вы знаете инструменты разработчика Chrome? На самом деле, тут есть множество мощных, но не слишком известных возможностей, которые способны значительно повысить эффективность вашего труда.
Здесь я собираюсь рассказать о самых полезных таких возможностях, которые, хочется надеяться, вам пригодятся.
Формат JSON-файла
Этот формат достаточно прост сам по себе, а также хорошо документирован. Базовая структура выглядит вот так:
traceEvents — это события, которые будут показаны в UI. Всё, что не является событиями, считается «метаданными», которые будут показаны в диалоге метаданных (в данном случае это meta_user и meta_cpu_count). Вышеуказанный JSON-файл будет выглядеть в Chrome Tracing вот так:
События, которые описаны в нём, достаточно просты. Они называются «завершенными» (тип ph:X) — для их описания нам потребуется указать время начала и длительность в микросекундах (аттрибуты ts и dur). Ещё указываются аттрибуты ID процесса и ID потока, а также имя события. Необходимости указывать отношение родитель-ребёнок нет — UI определит его сам на основе времени начала и длительности каждого события.
К событиям также можно прикреплять какие-небудь данные (аттрибут args), которые при выборе данного события будут отображаться на нижней панели. Есть небольшой нюанс — чтобы событие вообще можно было выбрать, у него должен быть непустой args. То есть хотя бы что-нибудь (пусть даже ненужное) туда лучше положить. Не можете придумать что — продублируйте там длительность события (возможно, преобразовав его из микросекунд в милисекунды или секунды).
Вот и всё, что я хотел рассказать по базовому использованию этого инструмента. Возможно, статья получилась несколько простоватой — но это потому, что и сам инструмент простой и удобный. Для продвинутых вариантов его использования читайте документацию. Удачного профилирования.
Всем привет!
Меня зовут Костя, я занимаюсь разработкой Яндекс.Браузера. Недавно у нас в Новосибирском офисе в Академгородке проходила небольшая C++ party, на которой я рассказывал о том, какие инструменты мы применяем при разработке браузера и что можно позаимствовать для других больших проектов, например, про ninja, OWNERS. В ходе разработки мы очень пристально следим за производительностью: загрузка CPU, потребление памяти, время выполнения различных операций и так далее. При этом активно используются различные утилиты, но также и внутренние отладочные инструменты браузера, например, внутренняя страница browser://tracing (для Яндекс.Браузера, chrome://tracing для Chromium и Chrome).
Если коротко, то на этой странице можно проследить длительность выполнения разных функций и количество вызовов в разбивке по процессам, потокам и переданным аргументам. Само собой, в этом нет никакой магии и для того, чтобы это работало, по коду требуется расставить специальные макросы. Как мне кажется, это очень удобный инструмент, который позволяет найти кучу разных проблем. Я считаю, что такой инструмент может оказаться полезным и в других проектах, так что я решил показать как можно его применить.
Зачем это нужно?
Конечно, для того, чтобы трейсить проекты существуют самые разные инструменты, но у них всех есть огромный минус — их нельзя использовать у конкретного пользователя, хотя это может быть очень важным для понимания и диагностики проблемы. Диагностику, которую собирает браузер на browser://tracing можно собирать в любой момент. Ее можно включать только на определенный период, чтобы повторить баг, а в остальные моменты она не приносит большого оверхеда.
Что нам понадобится?
В первую очередь, конечно, будут нужны исходники. По большому счету то, что нам нужно находится в папке base/trace_event внутри нее используются в том числе и другие компоненты из подпапки base, например, time, threading, synchronization и т.д. Я решил поступить очень просто и просто слинковаться с base.dll из сборки хромиума. К счастью, репозиторий хромиума у меня есть даже на домашнем компьютере, не говоря уж о рабочих. Для тех, кто хочет пойти таким же путем, тут есть ссылки на инструкции для сборки под разные платформы. Важно: для компонентной сборки нужно установить переменную окружения GYP_DEFINES=«component=shared_library».
Во-вторых нам нужны заголовочные файлы, которые можно взять здесь.
Как вариант, вместо этих двух пунктов можно сделать проще и добавить файлы из base к себе в проект.
Включаем трейсинг и пользуемся
Для начала нам нужно включить трейсинг. Для этого требуется создать фильтр категорий, который мы хотим применять. Категория — это идентификатор некоторый группы отслеживаемой операции. Категории нужны, чтобы выбирать какие группы мы хотим отслеживать в данный момент. Затем нужно вызвать метод SetEnabled у синглтона класса TraceLog.
Теперь придумаем сложную задачу, время выполнения которой мы хотим отслеживать и добавим в нужных местах макрос TRACE_EVENT. Этот макрос разворачивается в инстанцирование объекта класса ScopedTracer, который, как можно догадаться, отчитается о длительности выполнения в рамках scope. Подробнее можно посмотреть здесь
Осталась заключительная часть — нужно выключить трейсинг и сохранить результаты на диск. Сразу признаюсь, что в основном код взят отсюда
Итак, все необходимое есть, осталось только собрать все в одну кучу.
Результат
В результате получаем файл trace.json, который можно открыть на browser://tracing и увидеть следующее:
Заключение
Как можно заметить, получилось очень несложно позаимствовать достаточно полезный функционал из хромиума и применить его. Хотелось бы подчеркнуть, что кроме этого в исходниках хромиума очень много интересных подходов и просто-напросто готовых решений, которые так или иначе можно применить у себя в проекте.
Если у кого-то есть еще подобные примеры — расскажите о них в комментариях. От себя могу добавить, что, например, в фреймворке распределенных вычислений Яндекса YT используются хромиумовские коллбеки, которые были слегка доработаны напильником. Еще я однажды слышал байку про индусов, которые на базе хромиума сделали клиент для облачного диска, но не могу найти пруфов сейчас.
Автор статьи, перевод которой мы сегодня публикуем, хочет поделиться советами по профессиональной работе с инструментами разработчика браузера. А именно, эти советы рассчитаны на программистов, которые по какой-то причине решили, что их основным браузером будет Google Chrome.
Устройство простейшего трассировщика
Переходя к практической реализации простейшего трассировщика, их можно условно разделить на две большие группы, по способу инструментации кода:
- Централизованный — все точки захвата устанавливаются из единственной точки в коде. Трассировщик вызывает необходимые модули приложения и перегружает точки входа в них.
- Распределенный — все точки захвата определяются по месту необходимости, напрямую вызывая код трассировщика. Непосредственно определяют начало события и его конец.
Распределенный подход хорош тем, что можно очень ситуативно определять длительность и содержание событий, включая в них целые блоки полезного кода. Также, он проще для начальной реализации, потому что трассировщик избавлен от необходимости абстрактно отлавливать потенциальные ошибки и обеспечивать неизменный поток исполнения.
Самый банальный пример трассировщика второго типа может выглядеть так:
Все достаточно банально и трассировщик не должен беспокоиться ни о каких сторонних эффектах инструментируемого кода. Также, никогда не используйте ничего наподобие `Math.random().toString(16).substr(2);`, этот пример сугубо для иллюстрации, есть куда более правильные способы.
Как только мы захотим перейти к централизованному подходу, нам нужен будет абстрактный интерфейс для установки точек захвата:
Такой метод можно будет вызывать в том единственном месте, которое будет сердцем конфигурации. Обычный monkey-patching, даже нечего добавить. Легко заметить что метод имеет несколько недостатков:
- Расположение модуля относительно трассировщика
- Никаких проверок ввода
- Никакая поддержка асинхронных функций
Помимо более явного поведения для пользователя, это позволяет упростить валидацию на существование:
Поведение при невалидной конфигурации может быть жёстким (выбросить ошибку) или мягким (игнорировать модуль, продолжить работу). Теоретически хороший трассировщик должен позволять следовать любому из путей при помощи конфигурации, так как оба варианта могут быть оправданы в разных случаях.
Обработка асинхронных функций — уже чуть более интересная задача. Во первых, нужно определить является ли инструментируемый метод асинхронным, и изменить поведение трассировщика для определения конца события. Для этого можно модифицировать наш перегруженный метод следующим образом:
Из интересного, трассировщик должен гарантировать отсутствие сторонних эффектов во время выполнения. Поэтому он должен пробрасывать любые словленные ошибки назад в поток приложения.
Вот и все, такой примитивный трассировщик уже можно использовать для чего-то полезного. Из дополнительных возможностей, которыми можно озадачится:
- Поддержка before и after точек захвата для инструментируемого кода, с передачей аргументов и возвращаемого результата для любых других дополнительных действий
- Поддержка событий различных типов по именам, это просто удобно
- Поддержка сохранения метаданных об успешности каждого события
- Поддержка сохранения результатов выполнения инструментированного метода
- Библиотека стандартных точек захвата для публичных интерфейсов node.js и популярных библиотек
- Поддержка экспорта в других форматах, например: Open Tracing
- Возможность удалённого запуска трассировочных сессий с отправкой результата на клиент
- Защита от непреднамеренно долгих сессий (на нашей памяти были случаи, когда включенный трассировщик генерировал несколько гигабайт данных и ронял родительское приложение).
Суть в том, что каждое событие трассировщика раскрывается в два объекта представляющих начало и конец асинхронного события chrome://tracing. Помимо асинхронных событий, можно создавать и “законченные” (Completed) события. Но они перекрывают друг друга при рендере в chrome://tracing из-за чего их не так просто анализировать :3
После того как все события сконвертированы, останется просто аккуратно сложить их массивом в поле объекта `traceEvents` и сохранить его куда-нибудь, откуда его не будет мучительно долго искать через файловый проводник.
Заключительным шагом будет добавить инструментацию в части вашего приложения где происходит что-то неявное, запустить его и загрузить полученный файл в chrome://tracing.
Google любит добавлять скрытые функции в свои приложение и Google Chrome не является исключением. Google Chrome позволяет отобразить секретное меню «Параметры разработчика» на странице расширенных настроек, используя очень простой прием, который мы обсудим в этой статье.
Для начала необходимо запустить приложение Google Chrome.
Откройте меню, нажав на три точки в правом верхнем углу.
В открывшемся меню выберите пункт «Настройки».
Прокрутите меню настроек в самый низ и нажмите на опцию «О браузере Chrome».
Вернитесь в настройки и Вы увидите новый пункт «Developer options».
В данный момент в этом меню только одна опция «Tracing».
В трассировке доступны три раздела:
- Default categories: содержит 117 опций, и все они включены по умолчанию.
- Disabled-by-default categories: содержит 71 опцию, и все по умолчанию выключены.
- Tracing mode: по умолчанию для этого параметра установлено значение «Record until full». Вы можете изменить значение на «Record until full (large buffer)» или «Record continuously»
Вы также можете нажать на кнопку «Record trace», но учтите предупреждение: «Трассировки могут содержать данные пользователя или сайта, связанные с активным сеансом просмотра, включая вкладки инкогнито».
Если Вы нажмете кнопку «Record trace», Chrome начнет записывать трассировку, и на панели уведомлений будет отображаться уведомление о том, что трассировка Chrome записывается. Вы можете нажать на уведомление и нажать «Stop recording», чтобы остановить запись трассировки. В уведомлении будет отображаться ссылка «Share Trace», чтобы поделиться трассировкой с другими.
Предыстория
Для некоторой части нашей системы сборки кода мы когда-то написали простенький профилировщик (называется TinyProfiler). Он достаточно тривиален — замеряет время выполнения определенных блоков кода и создаёт набор HTML+SVG файлов, которые визуализируют эти данные в стиле flame-графов:
Это, в принципе, неплохо работало, но полученный HTML был не очень интерактивным. Можно было подвести мышку к определенному блоку и увидеть его название во всплывающей подсказке, но на этом все удобства и заканчивались. Не было ни зума, ни фильтрации, ни скрола, ни поиска — в общем ничего, чего хотелось бы получить от более-менее профессионального инструмента. Всё это можно было, конечно, сесть и написать, но… зачем же это делать, если можно этого не делать? Ведь уже есть кто-то (разработчики Chrome), кто всё это уже сделал.
▍Пример
Откройте какую-нибудь страницу, например — раздел Medium с самыми популярными материалами по JavaScript.
Теперь откройте панель команд и выберите в ней команду Screenshot Capture full size screenshot .
Команда для снятия скриншота всей страницы
В нашем распоряжении окажется скриншот всей страницы, который попадёт в папку загрузок.
Скриншот всей страницы
Как видите, изображение имеет очень большую высоту. Я его тут, для удобства, уменьшил. На самом же деле это — большое качественное изображение.
Аналогично, если нужно сделать скриншот элемента DOM, можно воспользоваться сторонней программой, которая, правда, не позволит получить изображение, относящееся в точности к нужному элементу. Решить эту задачу нам поможет команда Screenshot Capture node screenshot .
Пользуются ей так: сначала выбирают нужный элемент в панели Elements, а потом выполняют команду.
Создание скриншота области экрана, относящейся к конкретному элементу DOM
Вот как выглядит скриншот, снятие которого показано на предыдущем анимированном рисунке.
Скриншот элемента DOM
6. Копирование содержимого JavaScript-переменных
Можно ли скопировать значение JavaScript-переменной для последующего использования этого значения? Не исключено, что вам такая задача может показаться невозможной, но в консоли Chrome можно воспользоваться особой командой, copy() , которая позволяет копировать содержимое переменных в буфер обмена.
Копирование содержимого JS-переменной
Этой функции нет в стандарте ECMAScript. Она доступна нам благодаря Chrome.
1. Пункт меню Run command
Для начала мне хотелось бы в двух словах рассказать о пункте меню инструментов разработчика, который называется Run command. Этот пункт меню для Chrome — всё равно, что командная оболочка для Linux. Он позволяет вводить команды для управления Chrome.
Для того чтобы до этого пункта меню добраться, откройте инструменты разработчика, после чего можете сразу же воспользоваться соответствующим сочетанием клавиш:
- В Windows — Ctrl + Shift + P .
- В macOS — Cmd + Shift + P .
Пункт меню Run command
После этого будет открыта панель команд, в которой можно найти массу команд, позволяющих выполнять очень много всего интересного.
Панель команд
Поговорим о некоторых командах из данной панели.
3. Обращение к результатам последней операции в консоли
Консоль часто используется для отладки кода. Представьте, что вам нужно узнать о том, как обратить строку средствами JavaScript. Вы поискали в интернете и нашли такой фрагмент кода:
Вы попробовали запустить этот код в консоли и, как оказалось, работает он правильно.
Проверка кода в консоли
Итак, строку этот код «переворачивает». Однако вам непонятно то, как работают методы split() , reverse() и join() . Вы не знаете о том, с чем именно они работают на промежуточных этапах «переворачивания» строки. Поэтому вы решаете выполнять этот код пошагово. Начинаете вы с первого метода, получив его результат, запускаете на этом результате второй метод и так далее.
Исследование кода
Завершив эти эксперименты вполне можно понять то, как именно работает исходный фрагмент кода.
Но работа в таком стиле предусматривает выполнение множества лишних действий. Тут можно наделать ошибок, да и выглядит всё это довольно-таки неопрятно. Для того чтобы улучшить ситуацию, достаточно знать о том, что в консоли инструментов разработчика можно воспользоваться «магической» переменной $_ , которая позволяет ссылаться на результат последней выполненной операции.
Использование $_
Как видите, $_ — это особая переменная, значение которой всегда равняется результату последней операции, выполненной в консоли. Эта переменная может очень хорошо помочь вам при отладке кода.
Пример использования $_
2. Продвинутые механизмы создания скриншотов
Веб-разработчику иногда требуется сделать снимок части экрана. Уверен, у вас уже есть очень удобная программа для решения этой задачи. Вот несколько типичных задач по созданию скриншотов:
- Снятие скриншотов целых страниц, даже тех их частей, которые не видны в окне браузера.
- Захват копии области экрана, которая относится исключительно к конкретному элементу DOM.
- Screenshot Capture full size screenshot
- Screenshot Capture node screenshot
9. Перетаскивание объектов в панели Elements
Иногда, в ходе тестирования интерфейса, нужно поменять расположение некоторых DOM-элементов страницы. Для того чтобы это сделать, мы можем воспользоваться возможностью панели Elements, которая заключается в перемещении любых HTML-элементов в коде страницы.
Перетаскивание элемента
На вышеприведённом анимированном рисунке показано, как я, перетаскивая мышью элемент на панели Elements, меняю положение этого элемента на веб-странице.
▍Пример
Вот код веб-страницы:
Нам надо проверить стилизацию псевдоклассов. Для этого мы можем воспользоваться панелью Elements.
Исследование стилей псевдоклассов
4. Повтор отправки XHR-запроса
Если эту задачу решает начинающий разработчик, то он просто обновит страницу. Но постоянное обновление страниц для повторной отправки запросов может оказаться слишком трудоёмкой задачей. На самом деле, с запросами можно работать, используя средства панели Network.
Команда повтора XHR-запроса
Для того чтобы повторно выполнить уже отправленный XHR-запрос, надо действовать так:
- Откройте панель Network.
- Щёлкните по кнопке XHR.
- Вызовите контекстное меню запроса, который нужно повторить.
- Выберите в меню команду Replay XHR.
Повтор XHR-запроса
8. Удобное представление массивов объектов
Представьте, что у нас имеется массив объектов. Например — такой:
Выведем его в консоли.
Массив объектов, выведенный в консоли
Как видите, просматривать его, когда он выведен в таком виде, не очень-то удобно. А если подобный массив будет длиннее, а элементы, которые в нём имеются, будут иметь более сложную структуру, тогда разобраться с ним будет ещё сложнее.
К нашему счастью, в Chrome есть специальная функция, table() , которая позволяет форматировать массивы объектов.
Отформатированный массив объектов
Часто эта функция оказывается очень кстати.
11. Исследование псевдоклассов
На MDN можно узнать о псевдоклассах следующее:
Псевдоклассы дают возможность стилизовать элемент на основе не только отношений в DOM-дереве, но и основываясь на внешних факторах, таких как история посещений (например, :visited), состояние содержимого (вроде :checked у некоторых элементов формы) или позиции курсора мыши (например, :hover определяет, находится ли курсор мыши над элементом).
Для некоего элемента можно предусмотреть стили, имеющие отношение к различным псевдоклассам. Для того чтобы проверить эти стили, псевдоклассами можно управлять прямо из панели Elements.
Управление псевдоклассами
12. Быстрое скрытие элемента
При отладке стилей страницы часто нужно скрыть элемент. Для того чтобы сделать это максимально быстро, достаточно выделить элемент и нажать на клавиатуре клавишу H .
Быстрое скрытие элемента
Это приводит к добавлению стиля visibility: hidden !important; к соответствующему элементу.
5. Мониторинг загрузки страницы
На полную загрузку страницы, от самого начала этого процесса, до самого конца, может потребоваться более десяти секунд. Для того чтобы узнать о том, что именно происходит в ходе загрузки страницы, можно организовать наблюдение за этим процессом.
В инструментах разработчика Chrome можно делать скриншоты страницы в разные моменты загрузки, установив флаг Capture screenshots на панели Network.
Флаг Capture screenshots и наблюдение за загрузкой страницы
Щёлкая по скриншотам, можно просматривать запросы, выполнявшиеся в соответствующие моменты времени. Визуальное представление процесса загрузки страницы даст вам более высокий, чем раньше, уровень понимания того, что именно происходит при загрузке страницы.
Анализ загрузки страницы
Читайте также: