【技术背景】
前端性能优化是前端工程领域的核心任务之一,对于网页和应用程序的用户体验和业务成功至关重要。通过性能优化,我们可以实现以下目标:
1.提升用户体验:通过优化加载速度和响应时间,我们可以提供更快、更流畅的用户体验。这将增加用户满意度、降低流失率,并提高转化率与用户参与度。
2.改善搜索引擎排名:搜索引擎对网页加载速度有较高的要求,因此性能优化可以改善网页在搜索引擎结果页面(SERP)中的排名。通过提高性能,我们可以获得更多曝光和流量,为业务带来更多机会。
3.节省带宽和服务器成本:性能优化可以减少数据传输量,从而节省带宽和降低服务器负载。通过优化资源加载、压缩文件大小和利用缓存等技术手段,我们可以有效地提高网络效率并降低运行成本。
4.支持移动设备和低带宽环境:移动设备和低带宽网络环境具有特殊的挑战,而性能优化可以帮助我们更好地支持这些场景。通过减少数据传输量、采用响应式设计和加载策略等措施,我们可以确保在移动设备上提供更好的用户体验。
然而,优化的前提是性能检测和评估。通过性能检测,我们可以了解当前的性能状况、发现性能瓶颈,并为优化工作提供目标和参考。业界主流的前端性能检测工具包括Lighthouse(灯塔)、WebPageTest等,这两款工具的基本介绍如下:
1.Lighthouse(灯塔)[1]:
1)基本信息:由Google开发的开源工具,研发人员可以通过Chrome浏览器DevTools的Lighthouse面板进行使用,也可以通过Chrome浏览器的扩展程序运行,同时还可以通过NPM命令行工具运行。研发人员提供一个需要审查的网址,Lighthouse将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告,包括页面加载时间、性能指标(如First Contentful Paint和Time to Interactive)、可访问性、最佳实践等指标。
2)使用方式:主要有3种方式:
方式1:打开Chrome浏览器DevTools,选择Lighthouse面板,点击“Analyze page load”,如下图1所示:
图1
方式2:打开Chrome浏览器,访问Chrome应用商店chrome.google.com/webstore?ut…
方式3:安装Node 18 LTS (18.x)或者更高版本的Node,执行npm install -g lighthouse全局安装lighthouse,执行lighthouse xxx.com审查站点。
3)呈现方式:以页面性能报告的方式告知研发人员该站点的相应性能指标存在哪些问题,如下图2所示。
图2
2.WebPageTest[2]:
1)基本信息:由Google开发的开源工具PHP站点,其官方网址如下:www.webpagetest.org/。用户输入网址、地点、…
2)使用方式:输入站点,选择访问该站点的地理位置和浏览器,点击“开始检测”。如下图3所示。
图3
3)呈现方式:以页面性能报告的方式展示相关性能指标。如下图4所示。
图4
【技术背景存在问题】
前端研发的步骤一般分为6步,如下图5所示。
图5
Lighthouse(灯塔)和WebPageTest进行性能检测的切入点在上图5的②,也就是在前端项目打包构建生成静态文件产物并部署至服务器之后,通过请求相应域名站点发起网络请求从而进行分析。该方式的优点在于:
1)基于网络请求静态文件的方式比较贴合用户交互,较容易复现用户请求该域名站点遇到的性能问题,从而可以针对性地提出优化建议。
2)便于测定一系列的性能指标,同时可以定量化给某个站点的性能打分。
但上述方案对研发人员不够直观和友好。在前端研发中,研发人员通常通过编写HTML、CSS和JavaScript来进行开发。对于企业级大型项目,常会采用主流的前端框架(如Vue.js、React、Angular)和打包构建工具(如Webpack、Vite)来加速开发过程。因此,针对研发人员而言,对前端项目源码进行检测并提出优化建议更加直观,也更容易让研发人员有目的地优化代码。
前端项目源码性能检测大师就是这样一款基于前端项目源码的性能检测工具,其进行性能检测的切入点在上图5的****①。它类似于电脑管家或杀毒软件对电脑文件进行扫描,但前端项目源码性能检测大师则对前端项目源码进行分析。它通过采取一系列的检测策略,对诸如:图片资源、HTML、CSS、JavaScript(TypeScript)以及主流前端框架(如Vue.js、React、Angular)等文件进行评估分析,并提供精准的性能评估和相关的优化改进建议。这将帮助研发人员更有针对性地优化自己的前端项目代码,提升性能水平。
【工具优势】
**1.****友好的用户界面:**该工具提供直观的操作界面和信息展示,使得研发人员轻松上手并快速获取评估和建议信息。
**2.****精准评估与优化建议:**工具通过对前端项目源码的分析,能够精准评估项目的性能状况。基于评估结果,它会给出具体的优化改进建议,帮助研发人员有针对性地优化代码,以提升项目的性能水平。
**3.****策略和框架扩展性:**该工具的评估策略和框架具备良好的扩展性。不仅支持检测策略模块的扩展,还支持前端框架(如Vue.js、React、Angular)检测模块,以及其他前端相关技术栈的扩展。这使得工具在适应各种项目和技术需求时更加灵活可扩展。
【技术方案】
1.方案架构图
图6
2.时序图
图7
3.方案设计说明:
1)前端项目源码性能检测大师是一款NPM命令行工具,其安装及使用的前提是需要在电脑上先安装Node.js,且需安装Node.js版本 >= 10.5.0。
2)研发人员直接接触到的是指令层,除了常规的查看版本号和帮助信息的指令外,工具的核心指令就是检测源码指令inspect。
3)当研发人员执行该指令时,就会进入执行层的检测模块,包含四个步骤:清空目录(执行检测前需要先清空控制台、报告目录、存放项目的目录);安装NPM依赖(需要将工具的NPM依赖安装在执行指令的目标目录下,方便执行指令时可以找到NPM依赖包);拉取需要分析评估的git项目以及对应的分支;对已拉取的项目进行分析评估。
4)项目的分析评估包含两个步骤:遍历项目下所有文件并按扩展名进行归类后过检测策略;输出检测报告。
5)检测策略属于策略层,主要有两大模块:静态资源策略模块和前端框架策略模块。注意:这里检测的前提是待检测项目不存在明显的报错且可以在线上正常运行。
6)静态资源策略模块是通过制定一系列针对静态资源文件诸如:图片,HTML,CSS(包括css文件、sass文件、less文件、stylus文件),JavaScript,TypeScript的策略并对其进行分析,输出分析结果至sr(静态资源英文缩写)开头的临时文件。
7)图片检测策略包括:
- 图片资源过大检测策略【图片资源过大在弱网情况下会导致接口阻塞;这里图片资源的阈值默认是100KB,研发人员可通过命令工具传入指定阈值,若检测出某项图片资源大小大于阈值,会在检测报告中展示】;
- 等。
8)HTML检测策略包括:
- 检测是否包含favicon.ico【如果不设置favicon.ico控制台会报错;若检测出某项HTML文件缺少favicon.ico,会在检测报告中展示】;
- 检测
标签是否设置width或height属性【未设置width或height属性会引起浏览器重新布局影响页面加载速度;若检测出某项HTML文件存在未设置width或height属性的
标签,会在检测报告中展示】;
- 检测script脚本放置位置和是否使用async或defer属性【script脚本应该放在HTML文件底部,如果放在标签中就需要使用async或defer属性(异步或延迟加载script脚本),否则其加载、解析、执行的过程会阻塞HTML页面后续元素的正常渲染;若检测出某项HTML文件script脚本放置在标签中但没有使用async或defer属性,会在检测报告中展示】;
- 检测是否存在过深的DOM嵌套【过深的DOM嵌套会影响HTML页面加载性能,应尽量避免;这里嵌套深度的阈值是10,若检测出某项HTML文件存在超过10层的DOM嵌套,会在检测报告中展示】;
- 检测是否存在使用错误的DOM节点或冗余标签【错误的DOM节点或冗余标签会影响HTML页面加载性能,应尽量避免;冗余标签检测原则:该标签可以直接存放文本且子节点只有1个,这个子节点只包含文本;错误的DOM节点包括空或者不可访问的标签;若检测出某项HTML文件存在使用错误的DOM节点或冗余标签,会在检测报告中展示】;
- 等。
9)CSS检测策略包括:
- 检测文件是否使用@import规则【使用"@import"会造成等待所有import的CSS加载完成再进行其他操作,这就会造成其他CSS、JavaScript加载的阻塞;若检测出某项CSS文件使用@import,会在检测报告中展示】;
- 检测是否存在属性值使用!important【使用!important会降低代码可读性差、维护困难、难以定位问题,影响性能,应尽量避免;若检测出某项CSS文件使用!important,会在检测报告中展示】;
- 检测是否存在过深的CSS样式层级【过深的CSS样式层级会影响性能,应尽量避免;这里CSS样式层级深度的阈值是4,若检测出某项CSS文件使用的样式选择器样式层级超过4层,会在检测报告中展示】;
- 检测是否使用昂贵的CSS属性和样式规则【昂贵的CSS属性和样式规则会影响性能,应谨慎使用;昂贵的CSS属性和样式规则有:position: fixed、nth-child伪类、box-shadow、text-shadow、border-radius、filter、transform、transition、animation、perspective、transform-style、text-indent、opacity、@keyframes动画中是否使用昂贵的CSS属性和样式规则;若检测出某项CSS文件使用昂贵的CSS属性和样式规则,会在检测报告中展示】;
- 等。
10)JavaScript检测策略包括:
- 检测是否存在频繁操作DOM的场景【频繁操作DOM和重新渲染会导致性能问题,这里简化为通过检测JavaScript文件是否存在innerHTML关键字,如果存在会给出谨慎使用的提醒,会在检测报告中展示】;
- 检测是否存在不合理循环和迭代【不合理的循环和迭代可能导致性能问题,通过检测JavaScript文件是否存在for、while、do-while循环关键字,如果存在会给出谨慎使用的提醒,会在检测报告中展示】;
- 检测是否存在过多的事件监听器【过多的事件监听器可能导致性能下降,通过检测JavaScript文件中addEventListener使用次数,若超过阈值10次,则给出谨慎使用的提醒,会在检测报告中展示】;
- 检测是否存在使用了ES Modules模块import加载的方式但缺乏代码分割和按需加载【将所有代码一次性加载到页面可能导致加载时间过长,使用代码分割和按需加载会提升性能;通过检测JavaScript文件是否使用import from关键字,给出谨慎使用的提醒,会在检测报告中展示】;
- 检测是否使用eval【使用eval会导致代码存在安全风险和性能问题,不是最佳实践;若检测出某项JavaScript文件使用了eval,会在检测报告中展示】;
- 检测是否使用JavaScript API绘制动画【JavaScript绘制动画会带来性能问题、浏览器兼容性的问题以及一些安全问题;JavaScript API绘制动画的场景有:Canvas、SVG、Web Animation API 等;若检测出某项JavaScript文件存在绘制动画的代码,会在检测报告中展示】;
- 检测使用CommonJS模块加载之处并建议替换成ES Modules模块加载的方式【ES Modules是 ECMAScript 6(ES6)引入的模块系统,更适合在浏览器端使用,CommonJS虽然也可以在浏览器端使用,但其更适合在Node.js中使用;ES Modules相对于CommonJS的好处是:①静态导入,允许编译器在编译时构建静态依赖关系图从而很好地静态分析和优化(Tree Shaking)②使用import()函数进行异步加载,对于按需加载或懒加载很有帮助③支持命名导入导出④对循环依赖处理有更好的支持⑤更严格的模式;若检测出某项JavaScript文件使用了require关键字加载模块,说明其使用的是CommonJS的方式,这时就可以建议替换成ES Modules的方式加载,会在检测报告中展示】;
- 等。
11)TypeScript检测策略包括:
- 检测类型定义名称长度是否过长【名称过长会导致代码可读性差、维护困难、难以定位问题;需要先使用typescript npm包将TypeScript代码转化为TypeScript抽象语法树(AST),若检测出名称长度超过阈值30个字符,则给出谨慎使用的提醒,会在检测报告中展示】;
- 检测类型嵌套深度是否过深【嵌套深度过深会导致代码可读性差、维护困难、难以定位问题;需要先使用typescript npm包将TypeScript代码转化为TypeScript抽象语法树(AST),若检测出对象类型字面量的节点嵌套数超过阈值5层,则给出谨慎使用的提醒,会在检测报告中展示】;
- 检测类型定义的复杂度【类型复杂度过高会导致代码可读性差、维护困难、难以定位问题;类型定义复杂度衡量指标包括泛型参数数量、类型节点宽度(即成员数量)、是否包含联合类型或交叉类型;各指标数量乘以相应的权重,相加总和就是总复杂度,总复杂度超过阈值20就判定为类型定义复杂过高;需要先使用typescript npm包将TypeScript代码转化为TypeScript抽象语法树(AST),若检测出某项TypeScript文件存在类型定义复杂度过高,则给出谨慎使用的提醒,会在检测报告中展示】;
- 等。
- 其余策略复用“JavaScript检测策略”。因为TypeScript是JavaScript的超集,意味着任何有效的 JavaScript 代码都是有效的 TypeScript 代码,所以JavaScript检测策略一样适用于TypeScript。
12)前端框架策略模块是通过制定针对Vue.js、React(待建)、Angular(待建)等主流前端框架的策略对其进行分析,其检测策略包含了所有静态资源策略的模块,还加上框架定制化的策略,最后输出分析结果至fw(框架英文缩写)开头的临时文件。
13)Vue.js框架的检测策略:除了静态资源策略,主要是框架特定的.vue文件的检测策略。.vue文件检测策略包括:
- 使用vue-template-compiler npm包检测.vue文件是否过大,默认.vue文件大小阈值是20KB,文件过大说明缺乏代码拆分和按需加载,建议拆分成多个组件从而进行按需加载,减小初始加载时间;
- 基于eslint、vue-eslint-parser、eslint-plugin-vue等npm包分析文件中同一元素是否同时使用 v-if 和 v-for(Vue Eslint规则1),若同时使用则报错;
- 基于eslint、vue-eslint-parser、eslint-plugin-vue等npm包分析文件在v-for循环中是否使用v-bind:key(Vue Eslint规则2),若未使用则报错提示使用,因为这样做可以提高列表渲染性能;
- 基于eslint、vue-eslint-parser、eslint-plugin-vue等npm包分析文件是否在模板中使用v-bind:key(Vue Eslint规则3),若使用则报错,因为这样做会导致不必要的重复渲染,影响性能;
- 基于eslint、vue-eslint-parser、eslint-plugin-vue等npm包分析文件是否存在定义但未使用的变量(Vue Eslint规则4),若存在则报错建议删除,因为这会导致不必要的性能损耗;
- 基于eslint、vue-eslint-parser、eslint-plugin-vue等npm包分析文件是否直接使用v-html(Vue Eslint规则5),若使用则报错建议使用其他方式代替,因为这会引入安全性问题;
- 基于eslint、vue-eslint-parser、eslint-plugin-vue等npm包分析文件在计算属性中是否使用具有副作用的函数或方法(Vue Eslint规则6),若使用则报错建议使用其他方式代替,因为这样做会导致计算属性的性能下降;
- 等。
14)输出检测报告是通过遍历报告目录下的临时文件(sr开头和fw开头的文件),读取文件内容并转换成HTML字符串内容,然后嵌入HTML报告模板中生成HTML格式的报告文件,最后使用默认浏览器打开报告。
15)上图6所示指令层、执行层、策略层均是灵活可扩展的,其中策略层的静态资源策略模块和前端框架策略模块内的策略也是可扩展的。通用层为上面三层提供底层支撑的能力。
【技术关键点】
**1.**性能检测分析工具
1)基于对前端项目源码进行的解析和静态分析从而提供评估建议。
2)通过NPM命令行工具界面(CLI)提供用户友好的交互方式,方便在终端中执行性能检测分析。
**2.**静态资源策略模块
1)支持针对图片、HTML、CSS、JavaScript、TypeScript等静态文件的检测与分析。
2)根据不同类型的静态文件,执行相应的性能优化规则。
**3.**前端框架策略模块
1)针对Vue.js、React(待建)和Angular(待建)等主流前端框架,实现相应的策略模块,用于检测和分析与框架相关的性能问题。
2)除了检测所有静态资源策略的模块,还有框架特有文件检测的策略,借助相关npm包分析该文件给出代码性能优化的建议。
**4.**生成性能检测报告,提供给研发人员参考。
**5.**工具安装使用简单
1)将工具封装成易于安装和使用的NPM命令行工具。
2)提供清晰的文档和示例,指导用户如何正确安装和配置工具,并展示基本的使用方法。
3)设计直观友好的用户界面(UI),提供交互式操作和可视化的结果展示,以便研发人员轻松理解和分析性能问题。
【工具效果】
1.测试项目源码性能检测报告如下图8-12所示:
图8
图9
图10
图11
图12
【参考文献】
[1]如何使用Lighthouse性能检测工具:juejin.cn/post/695085…
[2]【性能优化】性能测量工具-WebPageTest:juejin.cn/post/695913…