前端常用性能优化方向

2023-05-27 0 1,028

该文整理于 20 年写的 操控性强化该文,现加进补充和详细说明;

用于复试、也可提防他们日常生活开发都是个不错的选择;

一、 vue 路径

v-if 和 v-showv-if 会引致重画异构化, 从 DOM 树中删掉、成本很大;适应于如上所述图形先期无此变化的 DOM;v-show 控制的是 DOM 式样, 防止了重画异构化, 适用于频繁转换显示、暗藏 的 DOM;v-for 中一定要用 keyv-for 图形条目时,遵从就地F83E43Se策略;他会根据 key 值去判断某一值与否修正,如果修正,则重新图形这一项,否则F83E43Se之前的元素;千万别采用 index 检索作为 key, index 会改变;尽可能采用统计数据唯一值;v-for 和 v-if 千万别一起采用v-for 的错误率高于 v-if ; 狸尾豆继续执行完 v-for 才会继续执行 v-if 方法论, 会增加 DOM图形技术难度;用 template 包一层替代;computed 计算特性替代 watch路由器懒读取 和 KeepAlive防止进入主页就读取全部的后端天然资源造成CM3时间太长;动态网页(引导页、协议、介绍等网页)可设置 KeepAlive 包覆,缓存起来;事件的封存 – 释放缓存addEventListener 要有相关联的 removeEventListener 封存setTimeout\setInterval 要有相关联的 clearTimeout\clearIntervalvue 长条目操控性强化Vue 会对统计数据展开挟持,实现单向统计数据存取,但有的是时候就说单纯的统计数据展现,所以应防止vue动态统计数据展开挟持, Object.freeze 方法来注销两个第一类,一旦被注销的第一类就再也不会被修正了相片懒读取 和 相片预读取的用时才开始读取,不用不读取;相片懒读取适用于于 批量相片展现的情景;提前读取到时候所需相片,相片预读取能够使得使用者在下载时不会出现相片读取一半引致下载不简洁的情况;应用程序的按需导入和权衡(你与否真的须要)比如说 UI 库, 常常都是比较大的,很占天然资源,应当采用按需导入;比如说工具类 loadsh, 常常你只是须要两个 HDR、IIS,这时他们写两个也很简单,就没必要导入了;伺服器端图形 和 预图形伺服器端图形 SSR (vue-server-renderer) 由伺服器端帮你渲染完成直接返回给下载器,提高了使用者新体验,能快速的下载的所需网页、SEO 亲善;减低了下载器阻力,但相应的造成了伺服器的阻力;预图形 (prerender-spa-plugin) 利用了 Puppeteer 的爬取网页的功能,在 Webpack 构筑阶段的最后,会邻近地区启动两个 Puppeteer 的服务,出访配置了预图形的路由器,然后将 Puppeteer 中图形的网页输入到 HTML 文件中,并建立路由器相关联的产品目录;

二、 react 路径

操控性主要耗费在于update阶段的diff算法,因此操控性强化也主要针对diff算法

减少diff算法触发次数(实际上减少update流程的次数);

注:父组件的render必然会触发子组件进入update阶段(无论props与否更新)。

合并setStatesetState 机制是批更新策略,已经降低了update过程的触发次数;尽可能无论统计数据处理多么复杂,保证最后只调用一次setState, 合并 setState 的调用;memomemo会对state和prop展开浅比较控制与否刷新;memo会缓存组件本身,站在全局的角度展开强化, 类似PureComponent、shouldComponentUpdate适当采用 useCallbackuseCallback缓存的是两个函数,是对两个单独的props值展开缓存, 返回上一次的函数引用, 可以保证依赖的值未发生改变的时候,不触发函数引用的改变;在向子组件传递函数props时,每次 render 都会创建新函数,引致子组件不必要的图形;useCallback 可以保证,无论 render 多少次,我们的函数都是同两个函数,减小不断创建的开销;但是给所有钩子都用 useCallback包覆, 是不对的,因为多数情况下无效,还引致代码可读性变差;需结合 memo 配套采用;useMemouseMemo 缓存的是两个值,可以保证依赖的值未发生改变的时候,不触发值改变;会根据依赖的值计算出结果,当依赖的值未发生改变的时候,不触发状态改变;会在图形的时候继续执行, 不是图形之后继续执行, 不建议有副作用相关的方法论;类组PureComponent / shouldComponentUpdateshouldComponentUpdate 的返回值用于判断 React 组件的输入与否受当前 state 或 props 更改的影响,当 props 或 state 发生变化时,shouldComponentUpdate 会在图形继续执行之前被调用;PureComponent / shouldComponentUpdate;会展开props和state的浅比较来判断组件与否须要更新( 浅比较:只会比较到两个第一类的 ownProperty 与否符合 Object.is() ,不会递归地去深层次比较);**慎用 forceUpdate **forceUpdate 会强制更新网页,直接进入componentWillUpdate阶段,且无法拦截, 跳过强化手段(shouldComponentUpdate), 直接进入render;建议少用;正确采用 diff 算法 – 状态更新不采用跨层级移动节点的操作对于条件图形多个节点时,尽可能采用暗藏等方式转换节点,而不是替换节点;尽可能防止将后面的子节点移动到前面的操作,当节点数量较多时,会产生一定的操控性问题;其他相片的懒读取、预读取、应用程序的按需导入和vue相同原理

三、 webpack / vite 路径

vite 自身已经做了很大程度的强化,所以主要的还是 webpack 路径;

生产环境关闭 sourceMapSourceMap 建立错误-代码之间的映射,方便代码调试;适用于于开发阶段;SourceMap 占体积大头;关闭之后你会发现项目小了很多;对相片展开压缩image-webpack-loader 应用程序cdn读取框架、应用程序天然资源vue|react|UI框架|可视化应用程序等;通过cdn的方式在script标签中直接采用,减少打包体积,提高读取速度;webpack-bundle-analyzer 构筑结果分析webpack-bundle-analyzer 打包后会生产两个邻近地区服务,清楚的展现打包文件的包含关系和大小;比较大参照组件拆分思想,展开拆分;和相关联应用程序或者工具类按需导入;vite 相关联的是 rollup-plugin-visualizer 应用程序, 功能类似DllPlugin 提取公用库开发过程中,我们经常须要导入大量第三方库,这些库并不须要随时修正或调试,我们可以采用DllPlugin和DllReferencePlugin单独构筑它们,配置webpack.dll.config.jscompression-webpack-plugin 开启 gzip 压缩

: gzipNginx 配置如下// nginx配置开启gzip压缩,nginx会根据配置情况对指定的类型文件展开压缩

gzip on; #开启或关闭gzip on offgzip_disable “msie6”#不采用gzip IE6gzip_min_length 100k; #gzip压缩最小文件大小,超出展开压缩(自行调节)gzip_buffers 4 16k; #buffer 不用修正gzip_comp_level 8;#压缩级别:1-10,数字越大压缩的越好,时间也越长gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;#  压缩文件类型

gzip_vary off;

Happypack 将 loader 由单进程转为多进程webpack 的缺点是单线程的,我们可以采用 Happypack 把任务分解给多个子进程去并发继续执行,大大提升打包效率;配置的方法是把 loader 的配置转移到 HappyPack 中去;HardSourceWebpackPlugin 构筑缓存为模块提供中间缓存步骤, 能做到第二次打包速度倍数提升;babel-loader给 loader 减低负担babel-loader 允许采用 Babel 和 webpack 转译 JavaScript 文件;cacheDirectory 指定的产品目录将用来缓存 loader 的继续执行结果。后面的构筑将会尝试读取缓存,来防止在每次继续执行时,可能产生的、高操控性消耗的 Babel 重新编译过程, babel-loader 提速至少两倍;cache-loader 也能达到相同强化目的babel-plugin-transform-runtime / tree-shaking 减少冗余代码webpack2 默认已经支持 tree-shakingspeed-measure-webpack-plugin 构筑速度分析很清楚的知道哪个模板构筑花了多少秒, 针对性的强化

四、 Http 路径

DNS 预解析通过 Html meta 标签来告知下载器, 当前网页要做DNS预解析;<meta http-equiv=“x-dns-prefetch-control” content=“on”

 />

网页header中采用link标签来强制对DNS预解析<link rel=“dns-prefetch” href=“http://bdimg.share.baidu.com”

 />

采用HTTP2解析速度快伺服器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段多路F83E43SeHTTP1.1 的 Pipelining 技术会有阻塞的问题,处理请求响应是按照顺序的,也就是后发的请求有可能被先发的阻塞住;HTTP/2的多路F83E43Se可以粗略的理解为非阻塞版的Pipelining。即可以同时通过两个HTTP连接发送多个请求,谁先响应就先处理谁,这样就充分的压榨了TCP这个全双工管道的操控性;首部压缩HTTP2 提供了首部压缩功能;HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽天然资源;减少HTTP请求数量HTTP会经历4 大步骤客户端连接到Web伺服器发送HTTP请求伺服器接受请求并返回HTTP响应释放连接TCP链接;HTTP请求建立和释放须要时间, 并且随着网络情况而变化,网路差花费的时间将更长;不阻塞情况下异步预先请求 或者合并请求;采用 http缓存充分利用好 http缓存 能有效减低伺服器、下载器阻力(须要后台配合);原理:http缓存都是在第二次请求开始的,第一次伺服器会在天然资源返回的响应中携带上四个常用的响应头,下载器会通过判别这些响应值来决定天然资源缓存的状态,再次请求的时候下载器会带上这些响应头;**Memory Cache**(缓存缓存) 是下载器最先尝试命中的缓存,也是响应最快的缓存。但是存活时间最短的,当进程结束后,tab 标签关闭后,缓存就不存在了,因为缓存空间比较小,通常较小的天然资源放在缓存缓存中,比如说 base64 相片等天然资源**Service Worker**(离线缓存) Service Worker 是一种独立于主线程之外的 Javascript 线程。它脱离于下载器窗体,因此无法直接出访 DOM。**Disk Cache**(磁盘缓存) 缓存的优先性,引致大文件不能缓存到缓存中,那么磁盘缓存则不同。虽然存储效率比缓存缓存慢,但是存储容量和存储市场有优势。Push Cache(推送缓存)它是最后一道缓存向下载器发送两个统计数据上次被修正的时间;下载器就知道了该统计数据最后被修正的时间,先期请求中,会和伺服器展开时间的比较,如果伺服器上的时间比邻近地区时间要新,说明统计数据有更改,下载器须要重新下载统计数据;缺点:当伺服器响应中有 Expires 或者 Cache-Control 设置了 max-age 响应头的时候,下载器不会向服务要更新;须要注意的是,ETag只有在邻近地区缓存已过期(Expires)或者缓存模式设置为 no-cache(Cache-Control)的时候,才会被下载器携带上伺服器端的值展开判别;标记了统计数据的过期时间,超过其中规定的时间后,缓存会被定义为过期,错误率Cache-Control的max-age > Expires可以携带多个响应值,这些值可以设置缓存时间、状态和验证状态;public: 所有内容都将被缓存包括客户端、代理cdn节点private: 只缓存到客户端,不缓存到代理伺服器no-cache: 须要先与伺服器确认no-store: 所有内容都不被缓存max-age: 在多少秒之后失效Cache-Control (强缓存)Expires (强缓存)ETag(协商缓存)–> 值是两个字符串(统计数据的哈希值),每个统计数据都有两个单独的标志Last-Modified (协商缓存)缓存的位置按优先采用get请求get请求不须要预检和交互; 频繁刷新下载器不会对下载器、伺服器造成太大的阻力,无伤;采用 CDN 伺服器端缓存加快出访速度 (俗称边缘计算)据缓存时间;例子:网站中大量的css,html,js等文件、大文件的下载(相片、视频、音频等),将这些动态内容推送到CDN节点;构成:如上所述伺服器,分布于各个节点的缓存伺服器,重定向DNS伺服器和内容交换伺服器主要技术:内容分发技术(构筑网络,将链接到IP网络上的内容,快速的传输到使用者终端)内容存储技术 (内容源的存储、内容在cache节点中的分布式存储);负载均衡;缺点:当源伺服器天然资源更新后,如果 CDN 节点上缓存统计数据还未过期,使用者出访到的依旧是过期的缓存天然资源,这会引致使用者最终出访出现偏差。因此,开发者须要手动刷新相关天然资源,使 CDN 缓存保持为最新的状态减少 DNS 查找次数DNS用于映射主机名和IP地址, DNS解析有代价,一般一次解析须要20~120毫秒。下载器在DNS查询完成前不会下载任何东西,所以下载器会想办法对DNS的查找结果展开缓存减少域名主机可减少DNS查询的次数,最理想的方法就是将所有的是内容天然资源都放在同两个域(Domain)下面,这样出访整个网站就只须要展开一次DNS查找,这样可以提高操控性。在HTTP /1.1中放在同个域下面会带来一定数量的并行度(它的建议是2),那么就会出现下载天然资源时的排队现象,这样就会降低操控性,推荐客户端针对每个域在两个网站里面采用至少2个域,但不多于4个域请求返回体的压缩、分页、缓存当两个请求返回统计数据比较多(如统计数据字典、相片、execl表格、pdf、音频、视频)时;优先和后台协商采用缓存、分页、切片等方案;并且异步请求放到请求队尾, 当接收统计数据很大时,你会发现下载器会进入卡死状态;

四、 相片路径

优先采用雪碧图相片、图标的转换优先采用雪碧图替代、以减少体积, 提高响应速度;

采用font字体、svg、base64、JPG、JPEG、WEBP格式的相片

条目相片采用预读取、懒读取、及脱离文档流后展开DOM回收

批量相片图形是很耗下载器操控性的,并且会阻塞其他图形,这时肯定须要采用预读取、懒读取方法;对相片展开操作时,尽可能脱离文档流后展开 DOM 回收,防止重画异构化;采用http、cdn缓存、不失帧情况下对相片压缩缓存、压缩目的都是快速响应使用者操作显示相片.

五、下载器图形路径

SSR(强化主页图形时间)、骨架屏、开启gzip压缩、js混淆(无效字符及注释的删掉、码语义的缩减和强化)css的文件放在头部、css压缩、合并css天然资源减少重定向、减少外链、不滥用web字体、,js文件放在尾部或者异步(async和defer、动态脚本创建) ( 标签 preload 图形前读取,prefetch,dns-prefetch图形完成后空闲时间加载 )防止內联式样、防止html里继续执行js, 多次修正式样、结构,尽可能合并在一起修正;采用css动画、减少css表达式、采用requestAnimationFrame操作动画防止重画异构化、减少 DOM 元素个数批量操作DOM,脱离文档流后在操作;采用css3 GPU硬件加速translate3d、translateZ、rotate、scale、transform、opacity、filters等动画效果不会引起回流重画对于频繁操作采用IIS、HDRIIS:短时间内大量触发同一事件,在函数继续执行一次之后,该函数在指定的时间期限内不再继续执行,直至过了这段时间才重新生效(例如监听滚动条 scroll 事件);HDR:如果短时间内大量触发同一事件,只会继续执行一次函数(例如:input事件);长条目强化vue|raect 相关联的UI框架基本都提供了虚拟条目组件, 优先采用虚拟条目组件;采用JSON格式JSON是一种轻量级的统计数据交换格式,是理想的统计数据交换格式。同时,JSON是 JavaScript原生格式,这意味着在 JavaScript 中处理 JSON统计数据不须要任何特殊的 API 或工具包控制Cookie大小和污染Cookie是邻近地区的磁盘文件,每次下载器都会去读取相应的Cookie,所以建议去除不必要的Coockie,使Coockie体积尽可能小采用Cookie跨域操作时注意在适应级别的域名上设置coockie以便使子域名不受其影响Cookie是有生命周期的,所以请注意设置合理的过期时间,合理地Expire时间和千万别过早去清除coockie其他防止 404、减少DOM 出访、用 <link> 替代 @import、保持单个内容小于25K

六、 Chrome Performance 分析

多采用 Chrome Performance 的火焰图 查找操控性瓶颈,针对性的强化;

评测报告中FP、FCP、FMP、LCP、TTI、TTFB、FCI、FID、DCL、Speed IndexFP“首次绘制” 是第两个“时间点”,它代表下载器第一次向屏幕传输像素的时间,就是网页在屏幕上首次发生视觉变化的时间。FCP “首次内容绘制”, 代表下载器第一次向屏幕绘制 “内容” (只有首次绘制文本、相片(包含背景图)、非白色的canvas或SVG时才被算作 FCP)FP和FCP可能是相同的时间,也可能是先FP后FCP。FMP“首次有效绘制” 主要内容”开始出现在屏幕上的时间点。它是我们测量使用者读取新体验的主要指标LCP 可视区“内容”最大的可见元素开始出现在屏幕上的时间点。TTI “可交互时间”

网页第一次 完全达到可交互状态 的时间点TTFB 表示下载器接收第两个字节的时间FCI 告诉我们网页什么时候完全达到可用FID FID指的是使用者首次与产品展开交互时,我们产品可以在多长时间给出反馈DCL DomContentloaded事件触发的时间Speed Index 网页可见部分的平均时间商城、官网、博客这种网页更侧重FMP(使用者希望尽快看到有价值的内容),而类似后台管理系统或在线PPT这种产品则更侧重TTI(使用者希望尽快

    new Date().getTime() – performance.timing.navigationStart

首屏时间

部分参考:

该文

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务