[总结]前端性能指标分析、性能监控与分析、Lighthouse性能评分分析

news2025/6/7 0:40:41

前端性能分析大全
前端性能优化
LightHouse性能评分
性能指标监控分析
浏览器加载资源的全过程性能指标分析

性能指标

在实现性能监控前,先了解Web Vitals涉及的常见的性能指标
在这里插入图片描述

Web Vitals 是由 Google 推出的网页用户体验衡量指标体系,旨在帮助开发者量化和优化网页在实际用户终端上的性能体验。Web Vitals 强调“以用户为中心”的度量,而不是纯技术层面的加载时间。

要按 先后顺序(时间维度) 梳理 Web Vitals,可以从网页加载的生命周期出发,把每个指标放入其发生时机对应的阶段中。这样更利于理解用户体验的演变和指标采集的逻辑。


🧭 一、加载过程的五大阶段

[1] 网络响应阶段
[2] 首次渲染阶段
[3] 内容加载阶段
[4] 用户交互阶段
[5] 页面稳定阶段

📊 二、Web Vitals 指标按时间顺序梳理

阶段指标名含义时机
1️⃣ 网络响应TTFB (Time to First Byte)首字节到达浏览器请求后,接收到第一个响应字节
2️⃣ 首次渲染FCP (First Contentful Paint)首次绘制文字/图像页面开始有内容渲染(非白屏)
3️⃣ 主内容加载LCP (Largest Contentful Paint)最大可视内容渲染完成用户感知“页面加载完”
4️⃣ 用户首次交互FID (First Input Delay)用户首次点击的响应延迟用户第一次交互,直到浏览器处理事件的延迟
5️⃣ 页面稳定CLS (Cumulative Layout Shift)布局跳动页面是否因为图片/广告等加载而抖动

🧬 三、时间线图(逻辑顺序)

00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s 00.000 s DNS & TCP/SSL TTFB(首字节返回) FCP(首内容绘制) CLS(累积布局偏移) Paint & 字体加载 LCP(最大内容绘制) 用户输入(点击等) FID(首次输入延迟) 网络层 页面初渲 主体内容加载 用户交互 页面稳定性

时间单位为毫秒。TTFB 最早,CLS 贯穿整个加载过程。


🔁 四、简洁记忆顺序口诀

💡「先 TTFB,见 FCP;看大图,用 LCP;首操作,测 FID;别乱跳,查 CLS


🛠 五、指标采集时机小贴士

指标采集方式推荐 API
TTFBperformance.timing.responseStart - navigationStartNavigation Timing
FCPPerformanceObserver 监听 paintPerformancePaintTiming
LCPPerformanceObserver 监听 largest-contentful-paintLCP Entry
FID真实用户交互产生的事件延迟Event Timing API
CLSPerformanceObserver 监听 layout-shiftLayoutShift Entry

🧭 六、总结为时序流图(Mermaid)

User Browser Server 输入 URL 发起请求 返回首字节 (TTFB) 渲染第一屏内容 (FCP) 渲染最大元素 (LCP) 第一次点击或输入 记录 FID(输入延迟) 页面渲染抖动时记录 CLS User Browser Server
TTFB ≤ 800ms
FCP ≤ 1.8s
LCP ≤ 2.5s
FID ≤ 100ms
CLS ≤ 0.1
TBT ≤ 200ms

在这里插入图片描述

在这里插入图片描述

指标监控

PerformanceObserver

PerformanceObserver 是 Performance API 中用于监听性能条目变化的核心工具。它可以在网页运行过程中,异步捕获新生成的性能条目,而不是一开始就调用 performance.getEntries() 拿“旧数据”。


一、PerformanceObserver 的作用

它允许开发者:

  • 监听网页运行中出现的性能条目(如资源加载、绘制、打点、长任务等)
  • 做出动态响应(如打日志发送埋点数据
  • 支持指定监听的 entryTypes,如 ["resource"], ["mark", "measure"]

二、使用方式

1. 创建实例
const observer = new PerformanceObserver((list, observer) => {
  const entries = list.getEntries();
  for (const entry of entries) {
    console.log(entry.name, entry.entryType, entry.startTime, entry.duration);
  }
});
2. 启动监听
observer.observe({
  entryTypes: ['mark', 'measure', 'resource']
});

entryTypes 是监听的条目类型数组。


三、常用方法

方法说明
observe(options)开始监听性能条目
disconnect()停止监听
takeRecords()获取当前缓冲区的所有性能条目并清空缓冲区

四、选项说明

observe(options)
observer.observe({
  entryTypes: ['resource', 'paint']
});

或使用过时写法(不推荐):

observer.observe({
  type: 'resource',
  buffered: true
});
参数说明:
  • entryTypes: 性能条目的类型(推荐)
  • type: 单一类型(不推荐)
  • buffered: 是否包括已存在的历史条目(true 会包含之前的记录)

五、支持的 entryType(性能条目类型)

类型含义
resource外部资源加载耗时
mark用户自定义打点
measure用户定义的测量点
paint首次绘制(first-paint, first-contentful-paint)
navigation页面导航
longtask长任务(如 JS 卡顿)
element关键可视元素曝光(需要配置)
largest-contentful-paint最大内容绘制时间
layout-shift布局偏移(CLS)

六、典型使用场景

  • 监听资源加载情况(如 img、script)
  • 监听 FCP、LCP、CLS、Long Tasks,用于 Web Vitals 性能分析
  • 异步获取自定义打点结果
  • 在 SPA 页面做性能埋点

七、注意事项

  • PerformanceObserver异步的:不会立即收到记录。
  • 使用 buffered: true 可获取已经发生的记录(旧数据),用于首次加载打点。
  • 页面进入后台或关闭时,需要调用 takeRecords() 收集剩余数据。
  • 一些条目需要在支持的浏览器中开启对应实验性特性(如 longtask)。

八、Mermaid 类图详解 PerformanceObserver

在这里插入图片描述

九、具体实现

在这里插入图片描述

import { lazyReportBatch } from '../report';
const originalFetch = window.fetch;
function overwriteFetch() {
    window.fetch = function  newFetch(url, config) {
        const startTime = Date.now();
        const reportData = {
            type: 'performance',
            subType: 'fetch',
            url,
            startTime,
            method: config.method,
        }
        return originalFetch(url, config).then((res) => {
            const endTime = Date.now();
            reportData.endTime = endTime;
            reportData.duration = endTime - startTime;
            const data = res.clone();
            reportData.status = data.status;
            reportData.success = data.ok;
            // todo 上报数据
            lazyReportBatch(reportData);
            return res;
        }).catch((err) => {
            const endTime = Date.now();
            reportData.endTime = endTime;
            reportData.duration = endTime - startTime;
            reportData.status = 0;
            reportData.success = false;
            // todo 上报数据
            lazyReportBatch(reportData);
        });
    }
}
export default function fetch() {
    overwriteFetch();
}
//监控FP
import { lazyReportBatch } from '../report';
export default function observerPaint() {
    const entryHandler = (list) => {
        for (const entry of list.getEntries()) {
            if (entry.name === 'first-paint') {
                observer.disconnect();
                const json = entry.toJSON();
                console.log(json);
                const reportData = {
                    ...json,
                    type: 'performance',
                    subType: entry.name,
                    pageUrl: window.location.href,
                }
                // 发送数据 todo;
                lazyReportBatch(reportData);
            }
        }
    
    }
    // 统计和计算fp的时间
    const observer = new PerformanceObserver(entryHandler);
    // buffered: true 确保观察到所有paint事件
    observer.observe({type: 'paint', buffered: true});
    
    
}
//监控FCP
import { lazyReportBatch } from '../report';
export default function observerFCP() {
    const entryHandler = (list) => {
        for (const entry of list.getEntries()) {
            if (entry.name === 'first-contentful-paint') {
                observer.disconnect();
                const json = entry.toJSON();
                console.log(json);
                const reportData = {
                    ...json,
                    type: 'performance',
                    subType: entry.name,
                    pageUrl: window.location.href,
                }
                // 发送数据 todo;
                lazyReportBatch(reportData);
            }
        }

    }
    // 统计和计算fcp的时间
    const observer = new PerformanceObserver(entryHandler);
    // buffered: true 确保观察到所有paint事件
    observer.observe({type: 'paint', buffered: true});
}
//监控LCP
import { lazyReportBatch } from '../report';
export default function observerLCP() {
    if (
        typeof PerformanceObserver === 'undefined' ||
        !PerformanceObserver.supportedEntryTypes.includes('largest-contentful-paint')
      ) {
        console.warn('LCP not supported in this browser.');
        return;
      }
    const entryHandler = (list,observer) => {
        if (observer) {
            observer.disconnect();
        } 
        for (const entry of list.getEntries()) {
            const json = entry.toJSON();
            //console.log(json);
            const reportData = {
                ...json,
                type: 'performance',
                subType: entry.name,
                pageUrl: window.location.href,
            }
            console.log(reportData);
            // 发送数据 todo;
            //lazyReportBatch(reportData);
        }

    }
    // 统计和计算lcp的时间
    const observer = new PerformanceObserver(entryHandler);
    // buffered: true 确保观察到所有paint事件
    observer.observe({type: 'largest-contentful-paint', buffered: true});
}



import { lazyReportBatch } from '../report';
export default function observerLoad () {
    window.addEventListener('pageShow', function (event) {
        requestAnimationFrame(() =>{
            ['load'].forEach((type) => {
                const reportData = {
                    type: 'performance',
                    subType: type,
                    pageUrl: window.location.href,
                    startTime: performance.now()- event.timeStamp
                }
                // 发送数据
                lazyReportBatch(reportData);
            });

        }, true);
    });
}



import { lazyReportBatch } from '../report';
export const originalProto = XMLHttpRequest.prototype;
export const originalSend = originalProto.send;
export const originalOpen = originalProto.open;

function overwriteOpenAndSend() {
    originalProto.open = function newOpen(...args) {
        this.url = args[1];
        this.method = args[0];
        originalOpen.apply(this, args);

    }
    originalProto.send = function newSend(...args) {
        this.startTime = Date.now();
        const onLoaded = () => {
            this.endTime = Date.now();
            this.duration = this.endTime - this.startTime;
            const { url, method , startTime, endTime, duration, status} = this;
            const reportData = {
                status,
                duration,
                startTime,
                endTime,
                url,
                method: method.toUpperCase(),
                type: 'performance',
                success: status >= 200 && status < 300,
                subType: 'xhr'
            }
            // todo 发送数据
            lazyReportBatch(reportData);
            this.removeEventListener('loadend', onLoaded, true);
        }
        this.addEventListener('loadend', onLoaded, true);
        originalSend.apply(this, args);

    }

}
export default function xhr() {
    overwriteOpenAndSend();
}


十、其他实现:Web Vitals

其他实现:Web Vitals 是 Google 提出的一组衡量网站用户体验关键质量的指标,特别关注 加载性能、交互响应、视觉稳定性。
在这里插入图片描述

监控上报(⭐)

数据上报
三种上报方式:

  1. imgRequest:以图片打点的方式
  2. beaconRequest:通过 navigator.sendBeacon 发送
  3. xhrRequest:使用 XMLHttpRequest(兼容方式)

在这里插入图片描述

如果使用 lazyReportBatch,则会缓存数据并按批量上传。多数请求都通过 requestIdleCallback 实现性能友好的空闲发送
在这里插入图片描述

import config from './config';
import {generateUniqueId} from './utils';
import {addCache, getCache, clearCache} from './cache';
export const originalProto = XMLHttpRequest.prototype;
export const originalOpen = XMLHttpRequest.prototype.open;
export const originalSend = XMLHttpRequest.prototype.send;
export function isSupportSendBeacon() {
    return 'sendBeacon' in navigator;
}
export function report(data) {
    if (!config.url) {
        console.error('请设置上传 url 地址');
    }
    const reportData = JSON.stringify({
        id: generateUniqueId(),
        data,
    });
    // 上报数据,使用图片的方式
    if (config.isImageUpload) {
        imgRequest(reportData);
    } else {
        // 优先使用 sendBeacon
        if (window.navigator.sendBeacon) {
            return beaconRequest(reportData);
        } else {
            xhrRequest(reportData);
        }
    }
}
// 批量上报数据
export function lazyReportBatch(data) {
    addCache(data);
    const dataCache = getCache();
    console.log('dataCache', dataCache);
    if (dataCache.length && dataCache.length > config.batchSize) {
        report(dataCache);
        clearCache();
    }
    //
}
// 图片发送数据
export function imgRequest(data) {
    const img = new Image();
    // http://127.0.0.1:8080/api?data=encodeURIComponent(data)
    img.src = `${config.url}?data=${encodeURIComponent(JSON.stringify(data))}`;
}
// 普通ajax发送请求数据
export function xhrRequest(data) {
    if (window.requestIdleCallback) {
        window.requestIdleCallback(
            () => {
                const xhr = new XMLHttpRequest();
                originalOpen.call(xhr, 'post', config.url);
                originalSend.call(xhr, JSON.stringify(data));
            },
            { timeout: 3000 }
        );
    } else {
        setTimeout(() => {
            const xhr = new XMLHttpRequest();
            originalOpen.call(xhr, 'post', url);
            originalSend.call(xhr, JSON.stringify(data));
        });
    }
}

// const sendBeacon = isSupportSendBeacon() ? navigator.sendBeacon : xhrRequest
export function beaconRequest(data) {
    if (window.requestIdleCallback) {
        window.requestIdleCallback(
            () => {
                window.navigator.sendBeacon(config.url, data);
            },
            { timeout: 3000 }
        );
    } else {
        setTimeout(() => {
            window.navigator.sendBeacon(config.url, data);
        });
    }
}

Lighthouse

Lighthouse 是 Google 提供的一个开源自动化网站审计工具,主要用于评估 Web 页面在性能、可访问性、最佳实践、SEO 和 PWA(渐进式 Web 应用)等方面的表现。它可以直接在 Chrome 浏览器的 DevTools(开发者工具)中使用,也可以通过 Node.js 命令行运行,甚至集成到 CI/CD 流程中。

下面是对 Lighthouse 工具的详解:


🔧 一、Lighthouse 使用方式

1. Chrome DevTools 中使用

  1. 打开 Chrome 浏览器
  2. 按 F12 或右键 → 检查,打开开发者工具
  3. 切换到 “Lighthouse” 标签页
  4. 选择你要评估的维度(Performance、Accessibility、Best Practices、SEO、PWA)
  5. 选择设备类型(Mobile 或 Desktop)
  6. 点击 “Analyze page load” 开始分析
    在这里插入图片描述

2. 命令行工具

安装 Node.js 后执行:

npm install -g lighthouse
lighthouse https://example.com --view

📊 二、Lighthouse 的评估维度详解

1. 📈 Performance(性能)

评估页面加载速度和交互体验。核心指标包括:

  • First Contentful Paint (FCP):首屏内容出现时间
  • Largest Contentful Paint (LCP):最大内容元素加载时间
  • Speed Index:页面可见内容加载速度
  • Time to Interactive (TTI):页面完全可交互的时间
  • Total Blocking Time (TBT):页面阻塞时间
  • Cumulative Layout Shift (CLS):视觉稳定性变化程度

👉 建议:压缩资源、懒加载图片、使用缓存、减少 JS 体积等


2. ♿ Accessibility(可访问性)

检测网站对残障人士的友好程度:

  • 图像是否有合适的 alt 标签
  • 表单元素是否有标签
  • 颜色对比度是否足够
  • 使用 ARIA 属性

👉 建议:为每个交互元素提供语义标签、颜色对比度符合标准


3. 📐 Best Practices(最佳实践)

检测网站是否符合现代 Web 开发规范:

  • 使用 HTTPS
  • 避免使用过时的 API
  • 图片格式是否优化
  • 是否防止 XSS

👉 建议:尽量使用现代 Web API、安全连接和资源优化策略


4. 🔍 SEO(搜索引擎优化)

评估页面对搜索引擎的友好程度:

  • 页面是否有 titlemeta description
  • 使用语义化 HTML 标签
  • 页面是否可爬取
  • viewport 是否设置

👉 建议:符合基础 SEO 规范,并确保结构良好


5. 📦 Progressive Web App(PWA)

检测是否符合 PWA 应用标准(如可离线使用、安装到桌面):

  • 是否注册了 Service Worker
  • 是否提供 Web App Manifest
  • 是否支持离线缓存

👉 建议:适合构建高可靠性、接近原生体验的 Web 应用场景


📁 三、Lighthouse 报告详解

生成报告后包含如下信息:

  • 分数评分:每个维度都是 0-100 分
  • 诊断信息:详细列出存在的问题
  • 建议改进:如何提升每项得分
  • 详细资源信息:如阻塞时间的脚本、加载顺序等

🔄 四、常见优化建议

问题建议优化方式
FCP 慢使用 CDN、预加载字体、图片压缩
LCP 慢懒加载、预渲染关键内容
TTI 高减少 JS 文件大小、优化主线程执行时间
CLS 高给图片/iframe 设置固定尺寸,避免动态插入内容

🧪 五、集成到 CI/CD 中

可使用 lighthouse-ci 进行自动化测试:

npm install -g @lhci/cli
lhci autorun

可将分数设置为门槛,发布前必须达到指定分值。


🧠 总结

模块目的分数建议
Performance用户体验核心≥90
Accessibility对所有用户友好≥90
Best Practices遵循标准≥90
SEO搜索可见性≥90
PWA应用体验≥70(视业务而定)

六、案例: 个人网站

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2397629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React-native的新架构

本文总结: 文章主要介绍了 React Native 的新架构&#xff0c;包括以下几个方面的内容&#xff1a;&#x1f4f1;✨ 如何抹平 iOS 和 Android 样式差异&#xff0c;提升跨平台一致性&#xff1b; 分析了旧架构中存在的问题&#xff0c;如通信瓶颈、启动慢、维护复杂等&#x…

Git 全平台安装指南:从 Linux 到 Windows 的详细教程

目录 一、Git 简介 二、Linux 系统安装指南 1、CentOS/RHEL 系统安装 2、Ubuntu/Debian 系统安装 3、Windows 系统安装 四、安装后配置&#xff08;后面会详细讲解&#xff0c;现在了解即可&#xff09; 五、视频教程参考 一、Git 简介 Git 是一个开源的分布式版本控制系…

Tree 树形组件封装

整体思路 数据结构设计 使用递归的数据结构&#xff08;TreeNode&#xff09;表示树形数据每个节点包含id、name、可选的children数组和selected状态 状态管理 使用useState在组件内部维护树状态的副本通过deepCopyTreeData函数进行深拷贝&#xff0c;避免直接修改原始数据 核…

AI书签管理工具开发全记录(五):后端服务搭建与API实现

文章目录 AI书签管理工具开发全记录&#xff08;四&#xff09;&#xff1a;后端服务搭建与API实现前言 &#x1f4dd;1. 后端框架选型 &#x1f6e0;️2. 项目结构优化 &#x1f4c1;3. API路由设计 &#x1f9ed;分类管理书签管理 4. 数据模型定义 &#x1f4be;分类模型&…

netTAP 100:在机器人技术中将 POWERLINK 转换为 EtherNet/IP

工业机器人服务专家 年轻的 More Robots 公司成立仅一年多&#xff0c;但其在许多应用领域的专业技术已受到广泛欢迎。这是因为More Robots提供 360 度全方位服务&#xff0c;包括从高品质工业机器人和协作机器人到咨询和培训。这包括推荐适合特定任务或应用的机器人&#xff0…

多模态大语言模型arxiv论文略读(九十八)

Accelerating Pre-training of Multimodal LLMs via Chain-of-Sight ➡️ 论文标题&#xff1a;Accelerating Pre-training of Multimodal LLMs via Chain-of-Sight ➡️ 论文作者&#xff1a;Ziyuan Huang, Kaixiang Ji, Biao Gong, Zhiwu Qing, Qinglong Zhang, Kecheng Zhe…

EXCEL--累加,获取大于某个值的第一个数

一、函数 LET(data,A1:A5,cumSum,SCAN(0,data,LAMBDA(a,b,ab)),idx,MATCH(TRUE,cumSum>C1,0),INDEX(data,idx)) 二、函数拆解 1、LET函数&#xff1a;LET(name1, value1, [name2, value2, ...], calculation) name1, name2...&#xff1a;自定义的变量名&#xff08;需以字…

本地部署 DeepSeek R1(最新)【从下载、安装、使用和调用一条龙服务】

文章目录 一、安装 Ollama1.1 下载1.2 安装 二、下载 DeepSeek 模型三、使用 DeepSeek3.1 在命令行环境中使用3.2 在第三方软件中使用 一、安装 Ollama 1.1 下载 官方网址&#xff1a;Ollama 官网下载很慢&#xff0c;甚至出现了下载完显示 无法下载&#xff0c;需要授权 目…

win主机如何结束正在执行的任务进程并重启

最近遇到一个问题&#xff0c;一个java入库程序经常在运行了几个小时之后消息无法入库&#xff0c;由于已经没有研发人员来维护这个程序了&#xff0c;故此只能每隔一段时间来重启这个程序以保证一直有消息入库。 但是谁也不能保证一直有人去看这个程序&#xff0c;并且晚上也不…

maven中的maven-resources-plugin插件详解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 一、插件定位与核心功能 maven-resources-plugin是Maven构建工具的核心插件之一&#xff0c;主要用于处理项目中的资源文件&#xff08;如…

ROS云课基础篇-01-Linux-250529

ROS云课基础篇收到了很多反馈&#xff0c;正面评价比例高&#xff0c;还有很多朋友反馈需要写更具体一点。 ROS云课基础篇极简复习-C、工具、导航、巡逻一次走完-CSDN博客 于是&#xff0c;有了这篇以及之后的案例&#xff0c;案例均已经测试过8年&#xff0c;但没有在博客公…

深入了解 C# 异步编程库 AsyncEx

在现代应用程序开发中&#xff0c;异步编程已经成为提升性能和响应能力的关键&#xff0c;尤其在处理网络请求、I/O 操作和其他耗时任务时&#xff0c;异步编程可以有效避免阻塞主线程&#xff0c;提升程序的响应速度和并发处理能力。C# 提供了内建的异步编程支持&#xff08;通…

Vulhub靶场搭建(Ubuntu)

前言&#xff1a;Vulhub 是一个开源的漏洞靶场平台&#xff0c;全称是 Vulhub: Vulnerable Web Application Environments&#xff0c;主要用于学习和复现各类 Web 安全漏洞。它的核心特征是通过 Docker 环境快速搭建出带有特定漏洞的靶场系统&#xff0c;适合渗透测试学习者、…

C++:参数传递方法(Parameter Passing Methods)

目录 1. 值传递&#xff08;Pass by Value&#xff09; 2. 地址传递&#xff08;Pass by Address&#xff09; 3. 引用传递&#xff08;Pass by Reference&#xff09; 数组作为函数参数&#xff08;Array as Parameter&#xff09; 数组作为函数返回值 什么是函数&#xff…

大语言模型的推理能力

2025年&#xff0c;各种会推理的AI模型如雨后春笋般涌现&#xff0c;比如ChatGPT o1/o3/o4、DeepSeek r1、Gemini 2 Flash Thinking、Claude 3.7 Sonnet (Extended Thinking)。 对于工程上一些问题比如复杂的自然语言转sql&#xff0c;我们可能忍受模型的得到正确答案需要更多…

Redis的安装与使用

网址&#xff1a;Spring Data Redis 安装包&#xff1a;Releases tporadowski/redis GitHub 解压后 在安装目录中打开cmd 打开服务&#xff08;注意&#xff1a;每次客户端连接都有先打开服务&#xff01;&#xff01;&#xff01;&#xff09; 按ctrlC退出服务 客户端连接…

2024年数维杯国际大学生数学建模挑战赛C题时间信号脉冲定时噪声抑制与大气时延抑制模型解题全过程论文及程序

2024年数维杯国际大学生数学建模挑战赛 C题 时间信号脉冲定时噪声抑制与大气时延抑制模型 原题再现&#xff1a; 脉冲星是一种快速旋转的中子星&#xff0c;具有连续稳定的旋转&#xff0c;因此被称为“宇宙灯塔”。脉冲星的空间观测在深空航天器导航和时间标准维护中发挥着至…

C# 控制台程序获取用户输入数据验证 不合规返回重新提示输入

在 C# 控制台程序中实现输入验证并循环重试&#xff0c;可以通过以下方式实现高效且用户友好的交互。以下是包含多种验证场景的完整解决方案&#xff1a; 一、通用输入验证框架 public static T GetValidInput<T>(string prompt, Func<string, (bool IsValid, T Val…

TDengine 运维——巡检工具(安装前检查)

简介 本文档旨在介绍 TDengine 安装部署前后配套的巡检工具。 相关工具的功能简介&#xff1a; 工具名称功能简介安装前检查部署前对 TDengine 安装部署的依赖要素进行安装前检查安装前预配置部署前对 TDengine 安装部署的依赖要素进行安装前预配置安装部署指定环境安装部署…

【Linux】权限chmod命令+Linux终端常用快捷键

目录 linux中权限表示形式 解析标识符 权限的数字序号 添加权限命令chmod 使用数字表示法设置权限 使用符号表示法设置权限 linux终端常用快捷键 &#x1f525;个人主页 &#x1f525; &#x1f608;所属专栏&#x1f608; 在 Linux 系统里&#xff0c;权限管理是保障系…