码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 搭建自动化 Web 页面性能检测系统 —— 设计篇


    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。。

    本文作者:琉易 liuxianyu.cn

    页面性能对于用户体验、用户留存有着重要影响,当页面加载时间过长时,往往会伴随着一部分用户的流失,也会带来一些用户差评。性能的优劣往往是同类产品中胜出的影响因素,也是一个网站口碑的重要评判标准。

    一、名称解释

    前端监控一般分为合成监控和真实用户监控。

    1.1、合成监控

    合成监控就是模拟用户的使用场景,访问一个页面,通过一些工具和规则去检测页面,提取一些性能指标,生成一份检测报告,注重检测。

    合成监控的优缺点:

    优点 缺点
    实现简单,社区方案成熟 配置复杂,不能完全还原用户真实场景
    能采集到更丰富的数据 登录等场景需要单独处理
    不影响真实用户的页面访问性能 单次检测数据不够准确

    1.2、真实用户监控

    file

    真实用户监控是指用户在页面上访问,访问时会产生各类性能数据,在用户访问停止的时候,将这些性能数据传输到服务端,进行数据整理分析的过程,注重监控。

    真实用户监控的优缺点:

    优点 缺点
    完全还原用户真实场景 对用户的访问性能有一定影响
    登录等场景无需单独解决 无法采集完整的资源加载瀑布图
    数据样本足够大且真实,数据价值高 无法可视化展示页面加载过程

    1.3、定义合适的性能指标

    1. 首次内容渲染时长(First Contentful Paint, FCP)
      页面最新出现的内容渲染时长
    2. 首次展现平均值(Speed Index, SI)
      页面内容可见填充的速度
    3. 最大内容绘制时间(Largest Contentful Paint, LCP)
      页面核心内容呈现时间,不采用 loading 状态的数据
    4. 可交互时间(Time to Interactive, TTI)
      用户是否会体验到卡顿
    5. 总阻塞时间(Total Blocking Time, TBT)
      主线程被阻塞的时间,无法作出输入响应
    6. 累计布局样式偏移(Cumulative Layout Shift, CLS)

    file

    二、为什么做

    基于需要对公司的 Web 产品进行性能优化,在做性能优化的同时,优化的衡量标准也不可或缺。在页面开发时观察页面的性能并不够准确,因为不同的开发设备性能表现不同,所伴随的变量也较多,不能够准确的反映性能优化效果,也无法观察产品的性能变化趋势。为什么自研呢,自研有以下好处:

    (1)借助第三方的性能检测服务往往不能保证检测数据的安全性。

    (2)第三方的性能检测服务一般无法与公司内部系统打通流程,一般无法自动化检测公司内部产品。

    (3)可以做一些自定义开发,比如根据产品特点调整不同的性能指标权重,从而更准确的计算分数。

    那么在检测收集到了这么多的指标数据后,页面性能到底如何呢,如果你的老板问你公司的产品页面性能如何,你该如何回复呢?假设列举一大堆时间指标、偏移量等数据,老板看到这些数值的时候可能就是一头雾水,根本理解不了产品的页面性能到底如何。那么自研可以针对产品类型,给出一个统一的标准,这样就方便去对比各个产品的性能表现了。

    三、怎么做

    3.1、基础依赖

    下面是检测系统的整体架构:

    file

    这里设计的性能检测系统主要包含前端页面和服务端,其中:

    前端页面展示性能检测入口、检测结果、性能趋势、性能排行榜等。

    服务端基于 Nestjs + Lighthouse + Puppeteer 实现,通过 Typeorm 操作 MySQL 数据库,记录和查询性能检测数据。

    另外辅助一些插件进行定时监测、结果通知等操作,实现自动化检测,相比页面开发时通过开发者工具中的 Lighthouse 检测有以下好处:

    (1)不用开发者主动触发;

    (2)不会阻塞开发过程,无需等待;

    Lighthouse 用于检测 Web 网页的性能,主要基于 4 个主要步骤实现,分别是交互驱动、性能数据收集、审计整理以及记录。具体为:

    (1)用户在性能检测入口输入待检测的页面地址,点击开始检测,页面通过接口调用性能检测服务

    (2)Lighthouse 遍历当前页面的收集器方法并合成一个总的收集器方法以便于采集数据

    (3)对上述采集到的性能数据进行计算和评分

    Lighthouse 主要提供六个收集器,通过以下六个收集器即可采集到和实际访问接近的性能数据,每个收集器的功能不一,如下:

    (1)收集 DOM 元素相关数据、DOM 节点最大深度、滚动条等

    (2)收集页面内的所有图片资源,并记录下每个图片元素的宽高和定位等属性

    (3)收集相关指标,如:FCP、LCP、CLS 等

    (4)收集 JS 事件监听数量、JS 堆栈等

    (5)收集页面的所有请求,包括状态码、请求头、响应头、请求方式等

    (6)收集 window.performance 下的性能数据,用于计算加载时间

    Puppeteer 是 Chrome 团队提供的一个无界面 Chrome 工具,俗称无头浏览器,通过提供的 API 可以控制 Node 端的 Chrome 工具进行指定的操作。在这里设计的性能检测系统中,由于 Lighthouse 进行检测时打开的类似于无痕窗口,没有登录信息,所以 Puppeteer 主要帮助我们实现模拟登录。

    当检测页面需要登录时,分析出页面属于哪个 devops 实例,然后通过 Puppeteer 跳转到对应的登录页面,然后输入用户名、密码、验证码,待登录完成后跳转至正确的页面,再进行页面性能检测。如果登录后还在登录页,表示登录失败,则获取错误提示并抛出。

    以下是检测系统的一个流程图:

    file

    3.2、关键代码

    // 开始检测
    async run(urlDto: UrlDto): Promise {
        const start = new Date().getTime();
        try {
            const { url, loginUrl } = urlDto;
            const needLogin = url.includes('devops') || loginUrl;
            console.log(`本次检测${needLogin ? '' : '不'}需要登录`, url);
    
            const runResult = needLogin
                ? await this.withLogin(urlDto)
                : await this.withOutLogin(url);
    
            // 保存检测结果文件,便于预览
            const urlStr = url.replace(/http(s?):\/\//g, '').replace(/\//g, '');
            fs.writeFileSync(`./static/${urlStr}-report.html`, runResult?.report);
    
            // 性能数据
            const performance = runResult?.lhr?.categories?.performance || {};
            const data = {
                ...performance,
                auditRefs: performance?.auditRefs?.filter((item) => item.weight),
            };
            // console.log(data);
            console.log(`本次耗时:${((new Date().getTime() - start) / 1000).toFixed(2)}s`);
    
            return {
                code: 200,
                data,
                message: `耗时:${((new Date().getTime() - start) / 1000).toFixed(2)}s`,
            };
        } catch (error) {
            return {
                code: 401,
                message: error,
            };
        }
    }
    
    

    3.3、检测规则

    系统除了支持手动输入网页地址检测,也支持自动检测。为了便于统计每个子产品的真实表现,每天凌晨自动检测 10 次,去掉最高分,去掉最低分,从其余分数中选择中位数作为每天的检测评分。

    性能检测时的数据采集可能因为网页服务的不稳定性,导致有偏大或偏小的数据,所以提供某个时间段某个指标的直方图来分析数据的基本特征。也会提供某个产品的整体分数趋势,便于统计某个时间段内该产品的性能变化,也可以提现性能优化前后的效果。

    file

    四、写在后面

    这篇文章简单介绍了下该性能检测系统的初步设计、一些页面性能的概念以及采用的技术点,后续请关注《搭建自动化 Web 页面性能检测系统 —— 实践篇》。


    最后

    欢迎关注【袋鼠云数栈UED团队】~
    袋鼠云数栈UED团队持续为广大开发者分享技术成果,相继参与开源了欢迎star

    • 大数据分布式任务调度系统——Taier
    • 轻量级的 Web IDE UI 框架——Molecule
    • 针对大数据领域的 SQL Parser 项目——dt-sql-parser
    • 袋鼠云数栈前端团队代码评审工程实践文档——code-review-practices
    • 一个速度更快、配置更灵活、使用更简单的模块打包器——ko
  • 相关阅读:
    水果店圈子:小型水果店用什么保鲜,经营水果店的保鲜方法
    C#使用WebSocket与网页实时通信
    MindSpore Ascend 内存管理
    rk3588使用vscode远程debug 配置文件
    企业帮助中心如何在线搭建,还能多场景使用呢?
    【云原生 • Kubernetes】一文深入理解资源编排 - yaml 文件
    indexDB & localForage
    使用 Python (Pyxel)制作一个经典的 Lode Runner 游戏
    python数据结构与算法-07_哈希表
    Mysql之分组查询,Group By,Group Having的用法
  • 原文地址:https://www.cnblogs.com/dtux/p/17433983.html
    • 最新文章
    • 攻防演习之三天拿下官网站群
      数据安全治理学习——前期安全规划和安全管理体系建设
      企业安全 | 企业内一次钓鱼演练准备过程
      内网渗透测试 | Kerberos协议及其部分攻击手法
      0day的产生 | 不懂代码的"代码审计"
      安装scrcpy-client模块av模块异常,环境问题解决方案
      leetcode hot100【LeetCode 279. 完全平方数】java实现
      OpenWrt下安装Mosquitto
      AnatoMask论文汇总
      【AI日记】24.11.01 LangChain、openai api和github copilot
    • 热门文章
    • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
      奉劝各位学弟学妹们,该打造你的技术影响力了!
      五年了,我在 CSDN 的两个一百万。
      Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
      面试官都震惊,你这网络基础可以啊!
      你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
      心情不好的时候,用 Python 画棵樱花树送给自己吧
      通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
      13 万字 C 语言从入门到精通保姆级教程2021 年版
      10行代码集2000张美女图,Python爬虫120例,再上征途
    Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
    正则表达式工具 cron表达式工具 密码生成工具

    京公网安备 11010502049817号