Это 74-я оригинальная статья без воды.Если вы хотите получить больше оригинальных статей, выполните поиск в официальном аккаунте и подпишитесь на нас~ Эта статья была впервые опубликована в блоге Zhengcaiyun:Как построить систему тестирования производительности от 0 до 1
предисловие
Производительность страницы переднего плана оказывает важное влияние на удержание пользователей и интуитивно понятный пользовательский интерфейс.Когда время загрузки страницы превышает 2 секунды, большое количество пользователей будет теряться на каждую секунду увеличения времени загрузки.Поэтому оптимизация производительности страницы, несомненно, для веб-сайта — это очень важный шаг.
Итак, как мы можем узнать производительность страницы? Зная производительность страницы, как ее оптимизировать? Показателей производительности для страницы много, столкнувшись с большим количеством показателей производительности, ветеран может какое-то время не знать, с чего начать анализ. Более того, за разные бизнесы отвечают разные команды, и показатели анализа эффективности нельзя обобщать. Например, для общего веб-сайта электронной коммерции должно быть много изображений, и повышение производительности загрузки изображений окажет большее влияние на повышение производительности веб-сайта. Для некоторых страниц среднего уровня, состоящих из форм, преимущества повышения скорости загрузки изображений гораздо меньше, чем у веб-сайтов электронной коммерции.
Подводя итог, можно сказать, что у разных команд разные бизнесы, между бизнесами огромные различия, а показатели эффективности нельзя обобщить, поэтому использовать единую модель обнаружения для охвата всех сценариев нереально. В этой статье рассказывается, как настроить платформу тестирования производительности, принадлежащую вашей собственной команде.
Давайте взглянем на платформу тестирования производительности Zhengcaiyun — Baice.
Прежде чем говорить о показателях производительности, давайте поговорим о Lighthouse.
Lighthouse
Lighthouse — это инструмент автоматизации с открытым исходным кодом для анализа и улучшения качества веб-приложений. Существует 4 способа запуска Lighthouse в инструментах разработчика Chrome, расширении Chrome, Node CLI и модуле Node. Baice в основном основан на методе модуля Node, расширяется и развивается на его основе.Подробнее об использовании Lighthouse см. Git:GitHub.com/Google CHROM…
На следующем рисунке показан окончательный результат определения производительности страницы Lighthouse.Вы можете видеть, что показатели на самом деле относительно полные.
Кто-то может спросить, почему бы просто не использовать Lighthouse напрямую. Во-первых, по неописуемым причинам, когда Lighthouse напрямую используется в инструментах разработчика Chrome в Китае, он всегда будет находиться в состоянии разогрева Lighthouse. Во-вторых, расширение Chrome также не поддерживает страницы, требующие авторизации. Наконец, для некоторых требований к настройке, описанных в предисловии, Lighthouse не может полностью удовлетворить их, поэтому необходимо выполнить настройку на основе Lighthouse, чтобы создать платформу тестирования производительности, отвечающую бизнес-требованиям.
Общая архитектура дизайна
На следующем рисунке показана общая архитектура системы Baice.
- Внешний интерфейс в основном использует диаграммы Antd и Antd, включая отображение обычных страниц и отображение некоторых диаграмм тенденций производительности.
- Сервер разработан на основеnesjs и подключен к Sentry для мониторинга тревог. Шлем используется для защиты системы от некоторых известных веб-уязвимостей.
- node-schedule используется для расчета производительности страницы, которая еженедельно подсчитывается системой, и для отправки электронных писем через nodemailer.
- Сжатие в основном используется для включения gzip.
- Основные службы обнаружения разработаны на базе Puppeteer и Lighthouse.
Процесс сбора Baice данных о производительности страницы
Основным методом страницы мониторинга системы Baice является синтетический мониторинг.Что такое синтетический мониторинг, вы можете обратиться к этой статье:Как Ant Financial достигает максимальной производительности переднего плана. Подводя итог, можно сказать, что преимущества синтетического мониторинга заключаются в следующем: данных, которые можно собрать, больше, а различные операционные среды можно настраивать в соответствии с различными сценариями. Прежде всего, Baice необходимо сформулировать различные модели обнаружения в соответствии с различными сценариями, такими как первая страница облака Zhengcai и средняя страница облака Zhengcai. Во-вторых, основная цель Baice — повысить производительность страницы, а сравнивать производительность страницы необходимо при условии, что среда и аппаратные условия совпадают, поэтому лучше выбрать синтетический мониторинг.
Давайте взглянем на диаграмму архитектуры Chrome Lighthouse (диаграмма взята из Lighthouse Git), которая в основном основана на 4 основных шагах, а именно: интерактивное вождение, сбор, аудит и запись.Ссылаясь на Chrome Lighthouse, логика модели обнаружения Baice также в основном состоит из этих 4 шагов, состоящих из:
1. После взаимодействия со страницей инициируйте запрос на вызов службы.
2. Пройдите коллекторы, необходимые для текущей страницы, объедините их в общий коллектор и соберите данные.
3. Подсчитайте и оцените данные, собранные на втором этапе.
4. Сохраните результаты теста производительности в базе данных.
Схема реализации Baice, собирающего данные о производительности страницы
Стоги-ста-политика для достижения программ сбора данных о производительности, полагаются в основном на маяке комбинированного маяка Cuppleer Browser Browser, Cuppeter Chrome Chrome Team предоставляет интерфейс без инструмента, известный как браузер без головы, сторона хромированного узла для управления через API. Основная стратегия логична сто-х хром портирования без дисплея, новая вкладка и открытая API с помощью маяка, маяк рассчитывает определенные показатели эффективности, специфическую логику обнаружения, показанную на рисунке 17. Далее я объясню, как использовать ключевой код ключевых шагов в нем.
○ Начать вход
Ниже приведен код Baice на 100 миллионов долларов.Основной процесс заключается в следующем.Функция ловушки используется для получения данных о производительности в разное время при открытии страницы.
/**
* 执行页面信息收集
*
* @param {PassContext} passContext
*/
async run(runOptions: RunOptions) {
const gathererResults = {};
// 使用 Puppeteer 创建无头浏览器,创建页面
const passContext = await this.prepare(runOptions);
try {
// 根据用户是否输入了用户名和密码判断是否要登录政采云
await this.preLogin(passContext);
// 页面打开前的钩子函数
await this.beforePass(passContext);
// 打开页面,获取页面数据
await this.getLhr(passContext);
// 页面打开后的钩子函数
await this.afterPass(passContext, gathererResults);
// 收集页面性能
return await this.collectArtifact(passContext, gathererResults);
} catch (error) {
throw error;
} finally {
// 关闭页面和无头浏览器
await this.disposeDriver(passContext);
}
}
○ Создайте безголовый браузер
Создайте безголовый браузер и страницу, укажите ширину и высоту, соответствующие браузеру, и укажите параметры работы.Чтобы узнать параметры браузера, обратитесь к следующим статьям:Puppeteer API. Вы можете установить для заголовка значение false, чтобы увидеть создание браузера и новой страницы, а также можно использовать локальную отладку.
/**
* 登录前准备工作,创建浏览器和页面
*
* @param {RunOptions} runOptions
*/
async prepare(runOptions: RunOptions) {
// puppeteer 启动的配置项
const launchOptions: puppeteer.LaunchOptions = {
headless: true, // 是否无头模式
defaultViewport: { width: 1440, height: 960 }, // 指定打开页面的宽高
// 浏览器实例的参数配置,具体配置可以参考此链接:https://peter.sh/experiments/chromium-command-line-switches/
args: ['--no-sandbox', '--disable-dev-shm-usage'],
executablePath: '/usr/bin/chromium-browser', // 默认 Chromium 执行的路径,此路径指的是服务器上 Chromium 安装的位置
};
// 服务器上运行时使用服务器上独立安装的 Chromium
// 本地运行的时候使用 node_modules 中的 Chromium
if (process.env.NODE_ENV === 'development') {
delete launchOptions.executablePath;
}
// 创建浏览器对象
const browser = await puppeteer.launch(launchOptions);
// 获取浏览器对象的默认第一个标签页
const page = (await browser.pages())[0];
// 返回浏览器和页面对象
return { browser, page };
}
○ Имитация входа
Сценарий имитации входа в систему см. в другой статье.«Baice System» реализует имитацию входа в системуОбщая логика реализации выглядит следующим образом: откройте страницу входа Zhengcaiyun через безголовый браузер, имитируйте ввод имени пользователя и пароля через Puppeteer API и имитируйте нажатие кнопки входа. В соответствии с функцией совместного использования файлов cookie с одним и тем же доменным именем в одном и том же браузере вы можете начать тест производительности, открыв новую вкладку и открыв URL-адрес для тестирования.
○ Открыть страницу
Как использовать Lighthouse в Puppeteer, см.Using Puppeteer with Lighthouse. Следующий код в основном определяет производительность настольной веб-страницы, а функция изменения среды обнаружения будет выпущена позже: вы можете определить, является ли страница мобильным телефоном или компьютером, по доменному имени Zhengcaiyun и переключаться между ними. различный просмотр в соответствии с различными системными средами, параметрами устройства.
/**
* 在 Puppeteer 中使用 Lighthouse
*
* @param {RunOptions} runOptions
*/
async getLhr(passContext: PassContext) {
// 获取浏览器对象和检测链接
const { browser, url } = passContext;
// 开始检测
const { artifacts, lhr } = await lighthouse(url, {
port: new URL(browser.wsEndpoint()).port,
output: 'json',
logLevel: 'info',
emulatedFormFactor: 'desktop',
throttling: {
rttMs: 40,
throughputKbps: 10 * 1024,
cpuSlowdownMultiplier: 1,
requestLatencyMs: 0, // 0 means unset
downloadThroughputKbps: 0,
uploadThroughputKbps: 0,
},
disableDeviceEmulation: true,
onlyCategories: ['performance'], // 是否只检测 performance
// chromeFlags: ['--disable-mobile-emulation', '--disable-storage-reset'],
});
// 回填数据
passContext.lhr = lhr;
passContext.artifacts = artifacts;
}
○ Функции ловушек
Функция ловушки на самом деле является абстрактным классом, и при запуске разных собраний соответствующий класс будет реализовывать абстрактный класс. Основная функция функции-ловушки состоит в том, чтобы регистрировать обратные вызовы в разное время.В основном есть две функции-ловушки, beforePass и afterPass. Функция beforePass в основном заключается в регистрации некоторых прослушивателей до загрузки страницы.Например, если вы хотите получить глубину узла DOM после загрузки страницы, вам необходимо зарегистрировать прослушиватель в beforePass. afterPass в основном возвращает структурированные данные после завершения статистики производительности страницы.
/**
* 执行所有收集器中的 afterPass 方法
*
* @param {PassContext} passContext
* @param {GathererResults} gathererResults
*/
async afterPass(passContext: PassContext, gathererResults: GathererResults) {
const { page, gatherers } = passContext;
// 遍历所有收集器,执行 afterPass 方法
for (const gatherer of gatherers) {
const gathererResult = await gatherer.afterPass(passContext);
gathererResults[gatherer.name] = gathererResult;
}
// 执行完所有方法后截图记录
gathererResults.screenshotBuffer = await page.screenshot();
}
○ Реализация коллектора
Baice имеет в общей сложности 6 сборщиков, а именно сбор Domstats, сбор элементов изображения, сбор Lighthouse, сбор метрик, сбор сетевых регистраторов и сбор производительности.
Каждый сборщик реализует определенную функцию сбора:
- Сбор Domstats: сбор данных, связанных с DOM, таких как количество элементов DOM, максимальная глубина DOM, наличие в документе полос прокрутки и т. д.
- Сбор элементов изображения: соберите все изображения и запишите ширину, высоту, расположение и другие атрибуты изображений.
- Lighthouse Gathering: собирайте показатели, связанные с Lighthouse: такие как FCP, LCP, TBT, CLS и т. д.
- Сбор метрик: количество прослушивателей событий JS, размер стека JS.
- Сбор сетевых регистраторов: собирает все запросы страниц, включая коды состояния, методы запросов, заголовки запросов, заголовки ответов и т. д.
- Сбор производительности: он в основном записывает некоторые данные в window.performance, которые используются для расчета некоторого времени.
Возьмите Domstats Gathering в качестве примера, чтобы подробно объяснить, как получить данные об обнаружении страниц. Сначала реализуйте 2 метода абстрактного класса: beforePass и afterPass. Логика реализации beforePass заключается в добавлении к объекту страницы метода мониторинга момента времени domcontentloaded.Основная функция метода мониторинга — определить, есть ли в документе горизонтальная полоса прокрутки. Метод afterPass в основном получает данные в Lighthouse lhr, анализирует и получает максимальную глубину DOM, количество узлов DOM и т. д.
import { Gatherer } from './gatherer';
import { PassContext } from '../interfaces/pass-context.interface';
// 实现 Gatherer 抽象类
export default class DOMStats extends Gatherer {
horizontalScrollBar;
/**
* 页面打开前的钩子函数
*
* @param {PassContext} passContext
*/
async beforePass(passContext: PassContext) {
const { browser } = passContext;
// 当浏览器的对象发生变化的时候,说明新打开页面了,此时可以获取到标签页 page 对象
browser.on('targetchanged', async target => {
const page = await target.page();
// 等待 dom 文档加载完成的时候
page.on('domcontentloaded', async () => {
// 通过 evaluate 方法可以获取到页面上的元素和方法
this.horizontalScrollBar = await page.evaluate(() => {
return document.body.scrollWidth > document.body.clientWidth;
});
});
});
}
/**
* 页面执行结束后的钩子函数
*
* @param {PassContext} passContext
*/
async afterPass(passContext: PassContext) {
const { artifacts } = passContext;
// 从 lighthouse 结果对象 lhr 中获取 dom 节点的 depth,width 和 totalBodyElements
const {
DOMStats: { depth, width, totalBodyElements },
} = artifacts;
return {
numElements: totalBodyElements,
maxDepth: depth.max,
maxWidth: width.max,
hasHorizontalScrollBar: !!this.horizontalScrollBar,
};
}
}
Дождавшись завершения всех собраний, данные можно сбросить.
○ Рассчитать оценку на основе модели
После того, как данные сохранены в базе данных, рассчитываются разные оценки в соответствии с разными моделями. Первая страница отображается повторно, и будет загружено больше изображений, а промежуточная страница повторно отправляется, поэтому разные модели должны иметь разную логику расчета. В Zhengcaiyun фреймворк, который мы используем для главной страницы, — это Vue, а для средней страницы используется React (на некоторых страницах все еще используется jQuery по историческим причинам). Поэтому модели можно условно различать по каркасу. Определить, является ли фреймворк Vue или React, можно на основе того, содержит ли DOM_reactRootContainer
и__vue__
судить.
/**
* 计算得分方法,根据模型上的得分配置项最终生成得分并入库
*
* @param {Artifact} artifact
* @param {string[]} whitelist
*/
async calc(artifact: Artifact, whitelist?: string[]): Promise<AuditDto> {
// 根据每条 metaid 动态加载不同的计算方法文件,每个 metaid 指的就是一个性能评分指标,比如说是否有横向滚动条
const audit = await import(`../audits/${this.meta.id}`).then(m => m.default);
// 执行每个计算方法文件中的 audit 方法,计算得分,比如没有横向滚动条的时候得5分,有横向滚动条不得分
const { rawValue, score, displayValue, details = [] } = audit.audit(artifact, whitelist);
const auditDto = new AuditDto();
auditDto.id = this.meta.id;
// 检测指标名称展示
auditDto.title = this.meta.title;
// 检测指标描述
auditDto.description = this.meta.description;
// 检测指标详情
auditDto.details = details;
// 检测指标登记,判断是否计算入得分
auditDto.level = this.level;
// 扣分上限根据不同的 meta,可能上限也有不同,upperLimitScore 指的是扣分上限,从数据库获取
auditDto.score = score * this.weight <= -this.upperLimitScore ? -this.upperLimitScore : score * this.weight;
// 得分情况
auditDto.rawValue = rawValue;
// 得分如何展示
auditDto.displayValue = displayValue;
return auditDto;
}
Ниже приведена модель интерфейса Zhengcaiyun.Каждый элемент является индикатором обнаружения.Элемент будильника является только напоминанием и на самом деле не вычитает баллы.Внешний интерфейс в основном основан на загрузке и отображении изображения.Поэтому в модели дизайн, больше внимания будет уделяться времени загрузки страницы ключевым показателям, а основное внимание будет уделяться отображению изображений.
Предыдущий контент в основном представляет функции сбора данных и оценки Baice, которые также являются наиболее важными функциями Bace. В дополнение к основным функциям Baice также имеет такие функции, как просмотр данных, предоставление решений по производительности, тенденции производительности, сравнение производительности и регулярный мониторинг. Я не объясняю их по одному в этой статье.
○ Автоматическое обнаружение
Конечно, в дополнение к описанному выше ручному обнаружению, Baice также поддерживает автоматическое обнаружение. Основная цель автоматического определения — подсчитать все страницы, включенные в систему, и подсчитать, какие страницы имеют наилучшую оптимизацию производительности, а какие плохо оптимизированы. Конкретная логика: каждую пятницу в 14:00 все страницы, включенные в Baice, будут тестироваться, и 10 страниц с наивысшими результатами тестов, 10 страниц с самыми низкими результатами тестов и 10 страниц с самыми быстрыми результатами тестов будут проверены. проверяется автоматически Логика обнаружения в основном реализуется через node-schedule. Для отправки электронных писем ejs может реализовать шаблон рендеринга, после определения шаблона вы можете отправить его через nodemailer.
import {
Injectable,
OnModuleInit,
} from '@nestjs/common';
import * as schedule from 'node-schedule';
@Injectable()
export class ScheduleService implements OnModuleInit {
onModuleInit() {
this.init();
}
async init() {
// 本地启动时不执行一系列定时任务
if (process.env.NODE_ENV !== 'development') {
// 每周五02:00开始收集页面性能
schedule.scheduleJob(`hawkeye-weekly-report`, '0 0 2 * * 5', async () => {
// 调用检测接口记录性能评分
await this.report();
});
// 每周五18:00发送周报
schedule.scheduleJob(`hawkeye-weekly-send`, '0 0 18 * * 5', async () => {
// 发送邮件的具体实现方法,主要通过 ejs 渲染模版,通过 nodemailer 发送邮件
await this.send();
});
}
}
}
○ Стыковка с Любаном
О том, что такое Любань, вы можете прочитать в этой статье:Система визуального построения для инженерной практики, Подводя итог одним предложением, можно сказать, что Luban — это система создания страниц Zhengcaiyun.
При стыковке с Luban это в основном включает ввод данных о производительности на странице Luban и ввод страницы Luban (для облегчения последующих еженедельных регулярных проверок).
- Ввод данных о производительности Luban: и предоставьте тестовую кнопку, когда Luban создаст страницу, вызовите интерфейс оценки производительности Baice и сгенерируйте тестовые данные.
- Вход на страницу Luban: Когда новая страница Luban выходит в сеть, интерфейс ввода Baice будет вызван автоматически, и новая страница будет введена в систему Baice.
конец
Если вы также хотите создать собственную платформу для тестирования производительности и случайно увидели эту статью, я надеюсь, что эта статья будет вам полезна.
В этой статье в основном рассказывается о том, как построить производительную платформу. После того, как вы смогли создать платформу производительности, вы можете подумать о модели обнаружения бизнес-страниц.
Рекомендуемое чтение
Анализ исходного кода vue-router и назначение разрешений динамической маршрутизации
Написание качественного поддерживаемого кода: обзор комментариев
Карьера
ZooTeam, молодая, увлеченная и творческая команда, связанная с отделом исследований и разработок продукции Zhengcaiyun, базируется в живописном Ханчжоу. В настоящее время в команде более 40 фронтенд-партнеров, средний возраст которых составляет 27 лет, и почти 30% из них — инженеры полного стека, настоящая молодежная штурмовая группа. В состав членов входят «ветераны» солдат из Ali и NetEase, а также первокурсники из Чжэцзянского университета, Университета науки и технологий Китая, Университета Хандянь и других школ. В дополнение к ежедневным деловым связям, команда также проводит технические исследования и фактические боевые действия в области системы материалов, инженерной платформы, строительной платформы, производительности, облачных приложений, анализа и визуализации данных, а также продвигает и внедряет ряд внутренних технологий. Откройте для себя новые горизонты передовых технологических систем.
Если вы хотите измениться, вас забросали вещами, и вы надеетесь начать их бросать; если вы хотите измениться, вам сказали, что вам нужно больше идей, но вы не можете сломать игру; если вы хотите изменить , у вас есть возможность добиться этого результата, но вы не нужны; если вы хотите изменить то, чего хотите достичь, вам нужна команда для поддержки, но вам некуда вести людей; если вы хотите изменить установившийся ритм, это будет "5 лет рабочего времени и 3 года опыта работы"; если вы хотите изменить исходный Понимание хорошее, но всегда есть размытие того слоя оконной бумаги.. , Если вы верите в силу веры, верьте, что обычные люди могут достичь необыкновенных вещей, и верьте, что они могут встретить лучшего себя. Если вы хотите участвовать в процессе становления бизнеса и лично способствовать росту фронтенд-команды с глубоким пониманием бизнеса, надежной технической системой, технологиями, создающими ценность, и побочным влиянием, я думаю, что мы должны говорить. В любое время, ожидая, пока вы что-нибудь напишете, отправьте это наZooTeam@cai-inc.com