JavaScript性能优化实战(13):性能测试与持续优化

在前面的系列文章中,我们探讨了各种JavaScript性能优化的方法和实战案例。然而,优化工作不应仅是一次性的努力,而应当成为开发流程中的常态。本篇将聚焦于如何建立系统化的性能测试体系,并实现持续的性能优化机制,确保应用长期保持出色的性能表现。

前端性能测试体系构建

随着前端应用日益复杂,系统性能对用户体验和业务成功的影响越来越大。然而,许多团队仍然采用临时性的、非系统化的方式进行性能测试和优化。建立一个完善的前端性能测试体系,对于持续交付高性能应用至关重要。

性能测试的核心维度

完整的前端性能测试体系应当覆盖以下几个核心维度:

  1. 加载性能:衡量应用从请求到可用所需的时间
  2. 运行时性能:评估应用在用户交互过程中的响应性和流畅度
  3. 内存使用:监控应用的内存占用情况和潜在的内存泄漏
  4. 网络效率:测量应用的网络请求数量、体积和时序
  5. 能耗性能:特别是在移动设备上,应用对电池寿命的影响

建立性能指标体系

性能测试的第一步是确定关键指标,这些指标应当既有技术维度的客观数据,也有用户体验的主观反映。

核心Web Vitals指标

Google的Core Web Vitals提供了衡量用户体验的标准化指标:

// 使用Web Vitals库收集核心指标
import {getCLS,getFID,getLCP,getFCP,getTTFB
} from 'web-vitals';// 发送性能数据到分析服务
function sendToAnalytics({name, delta, value, id}) {const analyticsData = {metric: name,value: delta, // 增量值finalValue: value, // 最终值id: id, // 唯一标识符page: window.location.pathname,timestamp: Date.now()};// 发送到分析服务navigator.sendBeacon('/analytics', JSON.stringify(analyticsData));
}// 监测并报告各项指标
getCLS(sendToAnalytics);  // 累积布局偏移
getFID(sendToAnalytics);  // 首次输入延迟
getLCP(sendToAnalytics);  // 最大内容绘制时间
getFCP(sendToAnalytics);  // 首次内容绘制时间
getTTFB(sendToAnalytics); // 首字节时间
自定义业务相关指标

除了标准化指标外,还应针对业务特点建立自定义指标,例如:

  • 关键业务流程性能:如电商网站的商品浏览到下单完成的全流程时间
  • 特定交互响应性:如复杂数据可视化应用中图表渲染和交互的响应时间
  • 长任务频率:应用中阻塞主线程超过50ms的任务数量和分布
// 自定义业务流程性能监测
class BusinessFlowPerformance {constructor(flowName) {this.flowName = flowName;this.steps = {};this.startTime = 0;this.endTime = 0;}startFlow() {this.startTime = performance.now();console.log(`Flow ${this.flowName} started`);}recordStep(stepName) {this.steps[stepName] = performance.now() - this.startTime;console.log(`Step ${stepName} completed at ${this.steps[stepName]}ms`);}endFlow() {this.endTime = performance.now();const totalDuration = this.endTime - this.startTime;console.log(`Flow ${this.flowName} completed in ${totalDuration}ms`);// 发送完整流程数据this.sendFlowData({flowName: this.flowName,totalDuration,steps: this.steps});}sendFlowData(data) {// 发送到数据分析服务fetch('/api/performance/business-flow', {method: 'POST',body: JSON.stringify(data),headers: { 'Content-Type': 'application/json' }});}
}// 使用示例
const checkoutFlow = new BusinessFlowPerformance('checkout');
checkoutFlow.startFlow();// 在各关键步骤调用
// 用户点击结算按钮
checkoutFlow.recordStep('cart_to_checkout');// 地址填写完成
checkoutFlow.recordStep('address_completed');// 支付方式选择完成
checkoutFlow.recordStep('payment_selected');// 订单确认
checkoutFlow.recordStep('order_confirmed');// 流程完成
checkoutFlow.endFlow();

性能测试环境构建

有效的性能测试需要在标准化、可控的环境中进行,以确保结果的可重复性和可比性。

实验室测试环境设置

实验室测试环境应模拟真实的用户设备和网络条件:

// 使用Puppeteer进行性能测试的示例配置
const puppeteer = require('puppeteer');async function runPerformanceTest(url, devicePreset, networkPreset) {// 启动浏览器const browser = await puppeteer.launch({headless: true,args: ['--no-sandbox', '--disable-setuid-sandbox']});// 创建新页面const page = await browser.newPage();// 设置设备模拟await page.emulate(puppeteer.devices[devicePreset]);// 模拟网络条件const client = await page.target().createCDPSession();await client.send('Network.enable');// 预设的网络配置const networkConfigs = {'3G': {'offline': false,'downloadThroughput': 750 * 1024 / 8,'uploadThroughput': 250 * 1024 / 8,'latency': 100},'4G': {'offline': false,'downloadThroughput': 4 * 1024 * 1024 / 8,'uploadThroughput': 2 * 1024 * 1024 / 8,'latency': 50}};await client.send('Network.emulateNetworkConditions', networkConfigs[networkPreset] || networkConfigs['4G']);// 收集性能指标await page.evaluateOnNewDocument(() => {window.performanceMetrics = {FCP: 0,LCP: 0,CLS: 0,TTI: 0};// 首次内容绘制new PerformanceObserver((entryList) => {const entries = entryList.getEntries();const fcpEntry = entries[entries.length - 1];window.performanceMetrics.FCP = fcpEntry.startTime;}).observe({ type: 'paint', buffered: true });// 最大内容绘制new PerformanceObserver((entryList) => {const entries = entryList.getEntries();const lcpEntry = entries[entries.length - 1];window.performanceMetrics.LCP = lcpEntry.startTime;}).observe({ type: 'largest-contentful-paint', buffered: true });// 累积布局偏移new PerformanceObserver((entryList) => {let cumulativeScore = 0;for (const entry of entryList.getEntries()) {// 只计算没有用户输入的布局偏移if (!entry.hadRecentInput) {cumulativeScore += entry.value;}}window.performanceMetrics.CLS = cumulativeScore;}).observe({ type: 'layout-shift', buffered: true });});// 访问目标页面并等待网络空闲const response = await page.goto(url, {waitUntil: 'networkidle2'});// 等待页面完全加载并可交互await page.waitForSelector('#main-content', { visible: true });// 提取性能指标const metrics = await page.evaluate(() => {// 等待TTI计算完成return new Promise(resolve => {// 模拟TTI计算setTimeout(() => {const navigationStart = performance.timing.navigationStart;const loadEventEnd = performance.timing.loadEventEnd;window.performanceMetrics.TTI = loadEventEnd - navigationStart;resolve(window.performanceMetrics);}, 1000);});});// 截图以备记录await page.screenshot({ path: `${devicePreset}-${networkPreset}.png` });// 关闭浏览器await browser.close();return {url,devicePreset,networkPreset,metrics,statusCode: response.status()};
}// 使用实例
async function runBatchTests() {const results = [];// 测试不同设备和网络组合const devices = ['iPhone X', 'Pixel 2', 'Desktop Chrome'];const networks = ['3G', '4G'];const urls = ['https://example.com','https://example.com/products','https://example.com/checkout'];for (const url of urls) {for (const device of devices) {for (const network of networks) {const result = await runPerformanceTest(url, device, network);results.push(result);}}}// 生成性能测试报告generatePerformanceReport(results);
}#### 真实用户监测(RUM)设置实验室测试需要与真实用户数据相结合,才能全面反映应用性能:```javascript
// 真实用户监测脚本示例
(function() {// 避免在非浏览器环境运行if (typeof window === 'undefined') return;// 确保Performance API可用if (!window.performance || !window.performance.timing || !window.performance.getEntriesByType) {console.warn('Performance API不完全支持,RUM数据可能不完整');}// 基础配置const config = {sampleRate: 0.1, // 采样率10%beaconEndpoint: '/analytics/rum',appVersion: '1.2.3',environment: 'production'};// 只对采样用户进行监测if (Math.random() > config.sampleRate) return;// 收集设备和浏览器信息const deviceInfo = {userAgent: navigator.userAgent,viewport: {width: window.innerWidth,height: window.innerHeight},devicePixelRatio: window.devicePixelRatio || 1,connection: navigator.connection ? {effectiveType: navigator.connection.effectiveType,downlink: navigator.connection.downlink,rtt: navigator.connection.rtt} : null};// 收集导航性能数据function collectNavigationTiming() {// 使用Performance Timeline APIconst navEntry = performance.getEntriesByType('navigation')[0];if (navEntry) {return {startTime: navEntry.startTime,domContentLoaded: navEntry.domContentLoadedEventEnd,loadTime: navEntry.loadEventEnd,domInteractive: navEntry.domInteractive,redirectCount: navEntry.redirectCount,redirectTime: navEntry.redirectEnd - navEntry.redirectStart,dnsTime: navEntry.domainLookupEnd - navEntry.domainLookupStart,tcpTime: navEntry.connectEnd - navEntry.connectStart,ttfb: navEntry.responseStart - navEntry.requestStart,responseTime: navEntry.responseEnd - navEntry.responseStart,domBuildingTime: navEntry.domComplete - navEntry.domInteractive,};}// 回退到旧APIconst timing = performance.timing;return {startTime: 0,domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,loadTime: timing.loadEventEnd - timing.navigationStart,domInteractive: timing.domInteractive - timing.navigationStart,redirectCount: 0,redirectTime: timing.redirectEnd - timing.redirectStart,dnsTime: timing.domainLookupEnd - timing.domainLookupStart,tcpTime: timing.connectEnd - timing.connectStart,ttfb: timing.responseStart - timing.requestStart,responseTime: timing.responseEnd - timing.responseStart,domBuildingTime: timing.domComplete - timing.domInteractive,};}// 收集并发送性能数据function sendPerformanceData() {const performanceData = {timestamp: Date.now(),page: window.location.pathname,referrer: document.referrer,deviceInfo,navigationTiming: collectNavigationTiming(),metrics: window.performanceMetrics || {},sessionId: getSessionId(),appVersion: config.appVersion,environment: config.environment};// 使用信标API发送数据if (navigator.sendBeacon) {navigator.sendBeacon(config.beaconEndpoint, JSON.stringify(performanceData));} else {// 回退到XHRconst xhr = new XMLHttpRequest();xhr.open('POST', config.beaconEndpoint, true);xhr.setRequestHeader('Content-Type', 'application/json');xhr.send(JSON.stringify(performanceData));}}// 获取或创建会话IDfunction getSessionId() {let sessionId = sessionStorage.getItem('performance_session_id');if (!sessionId) {sessionId = generateUUID();sessionStorage.setItem('performance_session_id', sessionId);}return sessionId;}// 生成UUIDfunction generateUUID() {return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {const r = Math.random() * 16 | 0;const v = c === 'x' ? r : (r & 0x3 | 0x8);return v.toString(16);});}// 页面内容加载完毕后发送数据window.addEventListener('load', () => {// 延迟发送,等待其他指标收集完成setTimeout(sendPerformanceData, 1000);});// 页面卸载前尝试再次发送数据window.addEventListener('beforeunload', sendPerformanceData);
})();

性能测试工具集成

构建完整的前端性能测试体系需要集成多种专业工具,形成协同工作的工具链。

核心工具选择

不同的性能测试场景需要匹配相应的工具:

测试类型推荐工具主要场景
页面加载性能Lighthouse, WebPageTest整体页面加载分析和评分
运行时性能Chrome DevTools, PuppeteerJavaScript执行和渲染性能分析
内存分析Chrome Memory Panel, Heap Snapshot内存泄漏和占用分析
真实用户监测Google Analytics, New Relic, Sentry生产环境中的性能数据收集
压力测试k6, Artillery高负载下的前端性能表现测试
工具链自动化集成

将这些工具整合到自动化测试流程中:

// 集成Lighthouse到CI/CD流程的示例脚本
const { exec } = require('child_process');
const lighthouse = require('lighthouse');
const chromeLauncher = require('chrome-launcher');
const fs = require('fs');
const path = require('path');// 定义性能预算
const performanceBudgets = {'first-contentful-paint': 1800,  // ms'largest-contentful-paint': 2500, // ms'cumulative-layout-shift': 0.1,'total-blocking-time': 300,      // ms'speed-index': 3000,             // ms'interactive': 3500,             // ms'max-js-size': 350 * 1024,       // bytes'max-css-size': 70 * 1024,       // bytes'max-total-size': 1500 * 1024    // bytes
};async function runLighthouseTest(url, options = {}) {// 启动Chromeconst chrome = await chromeLauncher.launch({chromeFlags: ['--headless', '--disable-gpu', '--no-sandbox']});// 设置Lighthouse选项const opts = {port: chrome.port,output: 'json',logLevel: 'info',...options};// 运行Lighthouse测试const results = await lighthouse(url, opts);// 关闭Chromeawait chrome.kill();return results;
}async function checkPerformanceBudgets(results, budgets) {const { audits } = results.lhr;const violations = [];// 检查FCPif (audits['first-contentful-paint'].numericValue > budgets['first-contentful-paint']) {violations.push({metric: 'First Contentful Paint',value: Math.round(audits['first-contentful-paint'].numericValue),budget: budgets['first-contentful-paint'],unit: 'ms'});}// 检查LCPif (audits['largest-contentful-paint'].numericValue > budgets['largest-contentful-paint']) {violations.push({metric: 'Largest Contentful Paint',value: Math.round(audits['largest-contentful-paint'].numericValue),budget: budgets['largest-contentful-paint'],unit: 'ms'});}// 检查CLSif (audits['cumulative-layout-shift'].numericValue > budgets['cumulative-layout-shift']) {violations.push({metric: 'Cumulative Layout Shift',value: audits['cumulative-layout-shift'].numericValue.toFixed(3),budget: budgets['cumulative-layout-shift'],unit: ''});}// 检查TBTif (audits['total-blocking-time'].numericValue > budgets['total-blocking-time']) {violations.push({metric: 'Total Blocking Time',value: Math.round(audits['total-blocking-time'].numericValue),budget: budgets['total-blocking-time'],unit: 'ms'});}// 检查Speed Indexif (audits['speed-index'].numericValue > budgets['speed-index']) {violations.push({metric: 'Speed Index',value: Math.round(audits['speed-index'].numericValue),budget: budgets['speed-index'],unit: 'ms'});}// 检查TTIif (audits['interactive'].numericValue > budgets['interactive']) {violations.push({metric: 'Time to Interactive',value: Math.round(audits['interactive'].numericValue),budget: budgets['interactive'],unit: 'ms'});}// 检查JS大小const jsSize = audits['resource-summary'].details.items.find(item => item.resourceType === 'script').transferSize;if (jsSize > budgets['max-js-size']) {violations.push({metric: 'JavaScript Transfer Size',value: Math.round(jsSize / 1024) + ' KB',budget: Math.round(budgets['max-js-size'] / 1024) + ' KB',unit: ''});}// 检查CSS大小const cssSize = audits['resource-summary'].details.items.find(item => item.resourceType === 'stylesheet').transferSize;if (cssSize > budgets['max-css-size']) {violations.push({metric: 'CSS Transfer Size',value: Math.round(cssSize / 1024) + ' KB',budget: Math.round(budgets['max-css-size'] / 1024) + ' KB',unit: ''});}// 检查总资源大小const totalSize = audits['resource-summary'].details.items.find(item => item.resourceType === 'total').transferSize;if (totalSize > budgets['max-total-size']) {violations.push({metric: 'Total Transfer Size',value: Math.round(totalSize / 1024) + ' KB',budget: Math.round(budgets['max-total-size'] / 1024) + ' KB',unit: ''});}return violations;
}// 主测试流程
async function runPerformanceTest() {try {console.log('启动性能测试...');// 测试环境URLconst targetUrl = process.env.TEST_URL || 'https://staging.example.com';// 运行Lighthouse测试const results = await runLighthouseTest(targetUrl, {onlyCategories: ['performance']});// 保存测试报告const reportPath = path.join(__dirname, 'lighthouse-report.json');fs.writeFileSync(reportPath, JSON.stringify(results.lhr, null, 2));console.log(`测试报告已保存至: ${reportPath}`);// 验证性能预算const violations = await checkPerformanceBudgets(results, performanceBudgets);if (violations.length > 0) {console.error('性能预算违反警告:');violations.forEach(v => {console.error(`  - ${v.metric}: ${v.value}${v.unit} (预算: ${v.budget}${v.unit})`);})<

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

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

相关文章

《告别低效签约!智合同如何用AI重构商业“契约时代”》​​——解析智能合约技术的爆发与行业变革

在数字化浪潮奔涌的当下&#xff0c;合同作为商业活动的核心枢纽&#xff0c;正经历着智能化的深度变革。智合同-合同智能应用这一创新模式&#xff0c;犹如一颗璀璨的新星&#xff0c;在商业领域的天空中绽放出独特光芒&#xff0c;深刻改变着人们对合同管理与应用的认知和实践…

塔防战争:动态寻径与成长系统的控制论架构

目录 塔防战争:动态寻径与成长系统的控制论架构引言第一章 炮塔成长系统1.1 属性升级模型1.2 分支进化树第二章 动态路径规划2.1 JPS优化算法2.2 实时障碍更新第三章 敌人行为系统3.1 多波次生成3.2 智能绕障策略第四章 经济平衡系统4.1 资源流动方程4.2 动态定价模型第五章 特…

快速刷机Android10+Root

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、下载android10源码 1.确认手机可刷机范围 比如我的Piexel3机型&#xff0c;支持刷android9-android12 Android源码。 https://de…

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(24):受身形

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(24):受身形 1、前言(1)情况说明(2)工程师的信仰2、知识点(1)うけみけい 受身形(2)復習(ふくしゅう):3、单词(1)日语(2)日语片假名单词4、相近词练习5、单词辨析记录6、总结1、前言 (1)情况说明 自己在今…

Ankr:Web3基础设施的革新者

在Web3技术蓬勃发展的今天&#xff0c;去中心化基础设施的重要性日益凸显。Ankr作为这一领域的佼佼者&#xff0c;凭借其强大的分布式云计算能力和创新的技术解决方案&#xff0c;正在成为推动Web3发展的关键力量。本文将深入探讨Ankr的技术亮点、应用场景以及其在区块链生态中…

【NLP 75、如何通过API调用智谱大模型】

事事忘记&#xff0c;事事等待&#xff0c;事事自愈 —— 25.5.18 一、调用智谱大模型 zhipuai.model_api.invoke()&#xff1a;调用智谱 AI 的大模型&#xff08;如 ChatGLM&#xff09;进行文本生成或推理&#xff0c;支持同步请求。 参数列表 参数名类型是否必需默认值说…

【jvm第0集】jvm学习路线指南

jvm学习路线指南 分享jvm学习路线指南&#xff0c;每个模块深入学习都要花费很多时间&#xff0c;但这个是每个java程序员的必修之路&#xff0c;大家可以跟着我的文章学习&#xff0c;可以不精&#xff0c;但必须懂。因为等你需要解决jvm相关问题的时候&#xff0c;你已经知道…

企业终端设备的安全管控

企业终端设备的安全管控是信息安全体系中的重要环节&#xff0c;涉及从设备准入到数据防护的全生命周期管理。 以下是一套系统化的解决方案&#xff0c;涵盖技术、管理和人员三个维度&#xff1a; 一、终端设备全生命周期管控 设备准入控制 802.1X网络认证&#xff1a;对接企业…

Flink SQL 计算实时指标同比的实现方法

在 Flink SQL 中计算实时指标的同比(Year-on-Year),核心是通过时间窗口划分周期(如日、月、周),并关联当前周期与去年同期的指标值。以下是结合流数据处理特性的具体实现方法,包含数据准备、窗口聚合、历史数据关联等关键步骤。 一、同比的定义与场景 同比指当前周期指…

架构的设计

搭建架构的最低前提 1.设计清晰&#xff1a; 需求文档&#xff1a; 有哪些界面 每个界面提够了哪些功能 这些功能是怎样操作的 会有哪些反馈 2.技术&#xff1a; 写架构的同学&#xff1a;这次项目设计的技术 都要有料及&#xff08;用到的技术有哪些特点 有哪些缺点&…

Mysql varchar类型字段存储的数据末尾带空格,数据过滤不及预期问题

Mysql varchar类型字段存储的数据末尾带空格&#xff0c;数据过滤不及预期问题 引分析 引 最近在项目上遇到一个数据过滤问题&#xff0c;有一批数据&#xff0c;字段末尾多了一个空格&#xff0c;在最后提交的时候被java后端的equals比较校验不匹配&#xff0c;导致业务流程阻…

Debezium TableSchemaBuilder详解

Debezium TableSchemaBuilder详解 1. 类的作用与功能 1.1 核心作用 TableSchemaBuilder是Debezium中负责构建表Schema的核心类,主要功能包括: Schema构建:将数据库表结构转换为Kafka Connect的Schema定义主键处理:生成表的主键Schema值Schema处理:生成表的非主键字段Sc…

P1090 [NOIP 2004 提高组] 合并果子

P1090 [NOIP 2004 提高组] 合并果子 - 洛谷 #include <bits/stdc.h> using namespace std; int main() {int n;cin >> n;priority_queue<int, vector<int>, greater<int>> pq; //小根堆for (int i 1; i < n; i) {int x;cin >> x;pq.pu…

《量子雷达》学习(1) 2025.5.20

《量子雷达》深度解析&#xff1a;理论、技术与未来启示 一、书籍核心内容与理论框架 Marco Lanzagorta的《量子雷达》从量子力学与经典电磁理论的融合视角出发&#xff0c;系统构建了量子雷达探测的理论体系。全书以量子态的传输、散射与检测为核心&#xff0c;重新定义了雷…

支持向量存储:PostgresSQL及pgvector扩展详细安装步骤!老工程接入RAG功能必备!

之前文章和大家分享过&#xff0c;将会出一篇专栏&#xff08;从电脑装ubuntu系统&#xff0c;到安装ubuntu的常用基础软件&#xff1a;jdk、python、node、nginx、maven、supervisor、minio、docker、git、mysql、redis、postgresql、mq、ollama等&#xff09;&#xff0c;目前…

uni-app(2):页面

1 页面简介 uni-app项目中&#xff0c;一个页面就是一个符合Vue SFC规范的 vue 文件。 在 uni-app js 引擎版中&#xff0c;后缀名是.vue文件或.nvue文件。 这些页面均全平台支持&#xff0c;差异在于当 uni-app 发行到App平台时&#xff0c;.vue文件会使用webview进行渲染&…

Unity异步加载image的材质后,未正确显示的问题

简述&#xff1a; 此问题涉及到Unity的UI刷新机制 问题描述&#xff1a; 如图所示&#xff0c;想要实现在打开新的界面时候&#xff0c;通过修改材质的方式&#xff0c;修改image的显示内容。 明明已经给image添加上材质了&#xff0c;可还是一片空白&#xff1f; 先看看代…

互联网大厂Java面试场景:从缓存到容器化的技术问答

场景&#xff1a;互联网大厂Java面试之旅 面试官&#xff1a;严肃的技术专家 应聘者&#xff1a;搞笑的水货程序员明哥 第一轮&#xff1a;缓存技术与数据库优化 面试官&#xff1a;明哥&#xff0c;你能谈谈Redis的常见使用场景和一些优化技巧吗&#xff1f; 明哥&#xf…

如何分析动态采样引起的计划不稳定 | OceanBase SQL 调优实践

这篇博客涉及两个知识点&#xff0c;一个是动态采样&#xff0c;另一个是 DAS 执行。 用户的问题和相关结论 我们看看用户在OceanBase 社区论坛发帖中提出的疑问及其所得出的结论。 问题&#xff1a;收集统计信息之前&#xff0c;为什么会出现计划不稳定的情况&#xff1f; …

TypeScript 泛型讲解

如果说 TypeScript 是一门对类型进行编程的语言&#xff0c;那么泛型就是这门语言里的&#xff08;函数&#xff09;参数。本章&#xff0c;我将会从多角度讲解 TypeScript 中无处不在的泛型&#xff0c;以及它在类型别名、对象类型、函数与 Class 中的使用方式。 一、泛型的核…