От автора: Chrome DevTools – обязательный инструмент анализа для понимания того, что происходит под капотом приложения, а также для проведения аудита производительности. При взаимодействии с сайтом, как обычный пользователь, с помощью DevTools вы можете узнать самые мельчайшие детали о странице. Инструмент отлично подходит для ручного анализа.
Однако если вам необходим мониторинг CSS и анализ веб-производительности относительно времени, этот инструмент может показаться слабым. Автоматизированные сервисы по синтетическому мониторингу не предоставляют столько информации, сколько есть в DevTools, и по большей части они имитируют всего один тип взаимодействия с пользователем – ожидание загрузки страницы.
В этом посте я покажу, как с помощью DevTools Protocol, Puppeteer и Headless Chrome создать инструмент мониторинга по мощности сравнимый с DevTools. С помощью этого подхода вы сможете автоматизировать любое действие, выполняемое вручную в DevTools UI. Мы продемонстрируем эту технику на примере программного отслеживания процентного соотношения неиспользуемого CSS в приложении.
Задача: вычислить реальное процентное соотношение неиспользуемого CSS
Наша цель – создать скрипт, который будет измерять процент неиспользуемого CSS этой страницы. Обратите внимание, что пользователь может взаимодействовать со страницей и перемещаться с помощью разных вкладок.
С помощью DevTools можно измерить объем неиспользуемого CSS на странице с помощью вкладки Coverage. Процент неиспользуемого CSS после загрузки составляет 55%,, но после клика на каждую вкладку применяется больше CSS правил, и процент падает до примерно 15%. Значительно. Наша автоматизированная задача должна отражать реальный процент неиспользуемого CSS, т.е. наш скрипт должен имитировать пользовательское взаимодействие и клики по всем вкладкам.
Шаг 0: знакомьтесь с Chrome без Chrome
Headless Chrome – новая функция, представленная в Chrome 59. Теперь вы можете запускать Chrome в режиме Headless Mode – т.е. окно браузера не открывается, а сайты рендерятся только в памяти. Новая возможность идеально подходит для тестирования и автоматизации.
Как и другие безголовые браузеры, его можно использовать для автоматизации пользовательского взаимодействия со страницей. Так как это Chrome, то Headless Mode можно использовать для автоматизации действий DevTools. Мы будем использовать Headless Chrome в автоматизации для загрузки и взаимодействия со страницей во время захвата CSS. Headless Chrome можно контролировать через код с помощью DevTools Protocol. О нем мы и поговорим далее.
Шаг 1: шпионим за DevTools через DevTools
DevTools UI похож на остальной интерфейс Chrome, однако это одностраничное приложение, написанное на Web technologies. Это отдельный проект, который можно скачать и поиграться. Так как это всего лишь клиентское приложение, оно должно получать данные об инспектируемой странице через объект Chrome. DevTools front end открывает соединение WebSockets с Chrome и двумя обменами сообщениями, соответствующие DevTools Protocol.
Например, откройте вкладку Console в DevTools и введите 1+1 – это протокольные сообщения, которые будут переданы из и в DevTools Frontend:
Именно поэтому мы можем быть уверены, что любое действие, выполненное вручную в DevTools, также можно запустить программно через DevTools Protocol.
Чтобы автоматизировать поиск неиспользуемого CSS, необходимо понять, какие команды DevTools Protocol посылать во время старта/остановки отслеживания на вкладке DevTools Coverage. Мы знаем, что DevTools UI – это веб-страница, использующая WebSockets для отправки протокольных команд, поэтому есть один способ – использовать DevTools, чтобы шпионить инспектировать DevTools. Как это сделать:
Запустите Chrome с флагом —remote-debugging-port=9222.
Перейдите на любой сайт (пример unused-css-example-site-qijunirqpu.now.sh).
Откройте новую вкладку и перейдите на localhost:9222.
Выберите страницу с первой вкладки в списке Insectable pages. Должна открыться страница с DevTools UI, инспектирующим страницу с первой вкладки. Будем называть ее DevTools #1.
Откройте DevTools, как обычно вы это делаете! (cmd+opt+i или F12) На странице вы должны увидеть дополнительный объект DevTools, инспектирующий DevTools UI из шага 4. Назовем его DevTools #2.
В DevTools #2 перейдите на вкладку Network и выберите фильтр WS.
Обновите страницу.
В DevTools #2 кликните на один WebSocket и перейдите на вкладку Frames.
В DevTools #1 выполните действие, для которого необходимо найти протокольную команду. В нашем случае необходимо открыть вкладку Coverage и стартовать/остановить захват покрытия.
Запишите посланные/полученные команды через WebSocket в DevTools #2. В нашем случае метод для старта отслеживания покрытия CSS.startRuleUsageTracking, а для остановки — CSS.stopRuleUsageTracking. Эврика!
Шаг 2: собираем все вместе
Теперь мы знаем, какие команды DevTools Protocol использовать. Поэтому теперь можно перейти к написанию скрипта автоматизации. Скрипт будем писать на Puppeteer – node.js библиотеке для запуска и управления Headless Chrome. Это высокоуровневая абстракция поверх DevTools Protocol. Это довольно удобно, потому что автоматизировать простые пользовательские взаимодействия с помощью DevTools Protocol было бы слишком утомительно. Например, для имитации клика пользователя по кнопке через грубые команды DevTools Protocol, необходимо найти координаты элемента и вызвать события mousePressed и mouseReleased. Puppeteer делает все остальное, когда вы используете ее метод click.
Тем не менее, когда вам нужно «запачкать руки» в грубых командах DevTools Protocol, Puppeteer позволяет это сделать. Вот почему библиотека идеально подходит под нашу задачу. Мы будем использовать ее удобную абстракцию для имитации клика пользователя по вкладкам, а также возможность отправки чистых команд DevTools Protocol для старта/остановки CSS отслеживания.
Наш код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
const puppeteer = require('puppeteer'); init(); async function init() { //Open Headless Chrome const browser = await puppeteer.launch(); //Open a new tab const page = await browser.newPage(); //Start sending raw DevTools Protocol commands are sent using `client.send()` //First off enable the necessary "Domains" for the DevTools commands we care about const client = page._client; await client.send('Page.enable'); await client.send('DOM.enable'); await client.send('CSS.enable'); //Start tracking CSS coverage await client.send('CSS.startRuleUsageTracking'); //Add this event to be notified whenever a stylesheet is added //(payload contains the stylesheet size which is needed to calculate the percentage) const stylesheets = []; client.on('CSS.styleSheetAdded', stylesheet => { stylesheets.push(stylesheet.header); }); //Trigger the user interaction with the page to hit more CSS rules //(in our case this means trigger clicking on each fo the tabs) const url = '//unused-css-example-site-qijunirqpu.now.sh'; await page.goto(url); await page.click('.tab.type2'); await page.click('.tab.type3'); await page.click('.tab.type4'); //Stop tracking CSS and get `ruleUsage` data object const { ruleUsage } = await client.send('CSS.stopRuleUsageTracking'); //You can see how `calcUnusedCssPercentage` is implemented here: ////github.com/cowchimp/headless-devtools/blob/17398336400eae3a7088069f1a27639c2ad30ac2/src/calcUnusedCss/index.js#L25 //(not shown here for brevity and because it's just in-memory math operations) const unusedCSS = calcUnusedCssPercentage(stylesheets, ruleUsage); console.log(`${unusedCSS}% of your CSS is unused`); await browser.close(); } |
Если хотите использовать этот скрипт на своем сайте, он доступен как NPM модуль, а полные исходники лежат на github. Эта версия позволяет передавать блок инструкций с пользовательскими взаимодействиями в виде внешнего колбека.
Заключение
Вот и все, мы написали скрипт, вычисляющий реальный процент неиспользуемого CSS в приложении. Выхлоп скрипта – «15% of your CSS is unused».
Не забывайте, что это лишь один пример общих действий DevTools, полезных и которые можно автоматизировать. Когда в следующий раз будете делать что-то через DevTools, спросите себя, можно ли это автоматизировать, и сколько времени это сэкономит.
Автор: Johnny
Источник: //blog.cowchimp.com/
Редакция: Команда webformyself.