当遇到一个性能问题,我们首先进行以下排查:
1、性能问题是在何时发生的;
2、性能问题持续存在的还是间断性的;
3、系统范畴的性能问题还是数据库本身的性能问题;
4、性能问题是否只存在于某一个应用;
5、性能问题是随机出现的还是必然出现的。
1,文件名做hash处理
在webpack配置中添加配置
当文件内容改变,hash值改变,文件名改变,url改变,访问新文件(否则访问旧文件,启动浏览器默认http缓存机制)
2,做cdn处理
3,后端做SSR处理
将html及其内容一次性返回,而不是前端:先加载网页,再加载数据,再渲染数据
4,懒加载
5,document.addEventListener(‘DOMContentLoaded’)
和load的区别:这个是Dom加载完毕就执行JS,但是此时视频和图片可能还没加载。
6,离线包原理
在线地址/离线地址:
首先前端申请一个offline在线地址
离线地址:https://{appId}.h5app.hupu.com/index.html?env={sit|stg|prod}
在线地址:https://offline-download.hupu.com/online/{sit|stg|prod}/{appId}/index.html
然后客户端根据离线地址找到对应的文件,如果没找到,这个时候会降级到cdn地址(在线地址)进行加载
一般前端给客户端或者后端一个在线地址,他们会自动转化为离线地址
离线包更新diff:
如果当前是A版本的离线包,现在更新成了B,用户打开app的时候如何更新离线包?
启动app/打开新webview的时候,会拉取离线包列表,客户端判断是否需要更新资源,如果最新资源和本地不一样则更新。
增量更新:两个包进行diff,差异小于60%。新包 = base包(旧资源)+差异包(新旧资源不同的地方)
全量更新:新包 = 新资源bundle
7,react-virtualized 中的 Masonry
虚拟列表,只显示可视域附近的元素
8,提升网站排名
1,m站做了seo优化
2,做voice新闻列表,方便被抓取,新闻点击的链接导向m站,以增加m站的权重
3,搜索引擎原理:
一个网站有三个按钮,只有点击按钮才会发起网络请求,数据才会展示到页面上,那么搜索引擎有不是人,不会点击按钮,就不会发起网络请求,所以需要我们在按钮上添加跳转链接,并且数据使用ssr进行获取,这样spider就可以抓到
9,浏览器渲染流程
SPA:
首先html打包后的资源代码放在A服务器,浏览器请求A服务器,A服务器返回给浏览器html文件,然后浏览器解析html之后,发现有接口请求数据,再向B服务器发送http请求,然后再浏览器端接受数据并解析渲染HTML。
SSR:
首先html打包后的资源代码放在A服务器,浏览器请求A服务器,A服务器向B服务器发起接口请求数据,B服务器返回数据给A,A解析数据生成DOM将合成后的HTML发送给浏览器,浏览器解析渲染HTML。
这里说的渲染流程无论是SPA,还是SSR都指的是浏览器渲染,是一样的:
dom生成dom树
css生成stylesheet(过滤不可见节点opcity:0,display后生成带位置的layout tree(reflow/repaint))
layout tree根据类似position进行分层(有利于reflow单独处理)并生成绘制命令
各个分层图块的绘制命令通过光栅化线程池交给 gpu 绘制并生成位图(GPU不占用渲染进程速度还快)(优先处理窗口附近的,所以如果结构太复杂会来不及导致白屏
合成层将各个分层生成的位图合并成一张位图
位图交给浏览器进程的biz组件
biz交给显示器的后缓冲区
⚠️:Dom tree需要等待stylesheet构建完毕后渲染
结论:
减少重绘重排:从以上流程可以看出来,reflow和repaint由于还在占用渲染进程,是最困难的一部分,所以尽可能减少reflow/repaint
多利用GPU硬件加速:transform3D、opacity、willchange等
10,LCP,FCP指标
LCP(最大内容绘制):可见区域可见的最大图像或者文本完成渲染的相对时间
FCP(首次内容绘制):从开始加载,到第一个元素(任何一个都行)被渲染出来的时间
TTI(用户可交互时间):页面变得完全可交互需要的时间
可以使用SSR优化FCP
11,SPA预加载性能优化方案:preload ,pre connect
SPA页面一般是把HTML请求到浏览器再去根据html中的资源链接请求对应的资源。在请求html等待响应的这段时间浏览器事都做不了,preload就是在请求HTML等待响应的这段时间,浏览器发起请求其他的资源文件。
可以把需要请求的资源文件放在preload中,具体的用法:
可以在webpack中使用preload插件,将需要进行preload预加载的资源放到这里,比如我们要预加载一个:utilities.js文件,在webpack中配置:
import(
`./utilities/divide`
/* webpackPreload: true */
/* webpackChunkName: "utilities" */
)
相当于:<link rel="preload" as="script" href="utilities.js">
12,SSR预加载性能优化方案:http103状态码Early Hints
因为SSR是在服务端加载完毕html统一发送给html的,所以用preload就没有意义。
103状态码是http2.0 server push的升级版。
13,requestAnimationFrame
文章:javascript - requestAnimationFrame 执行机制探索 - 个人文章 - SegmentFault 思否
只要js代码中包含重绘,在该函数外面包裹requestAnimationFrame可以提升性能。
requestId = requestAnimationFrame(animation);
cancelAnimationFrame(requestId);
一般用于动画。
14,接入sentry优化性能
检查后端接口时间
Js拆包并行加载(preload)
15,webpack打包优化
安装webpack-bundle-analyzer
plugins添加
process.env.ANALYSE === '1' &&
new BundleAnalyzerPlugin({
analyzerMode: 'static',
defaultSizes: 'parsed',
reportFilename: '../build/bundle_analysis.html'
}),
1,css和js分离,然后给打包的文件名加hash
[hash] [chunkhash] [contenthash]
2,splitChunks
3,babel-plugin-import按需引入的时候不再需要手动引入全部样式,会自动引入对应组件的样式
自带的vivo浏览器是Google内核的。 现在国内的浏览器使用的内核有好几种.像安卓手机所使用的浏览器内核是WebKit内核,Google浏览器使用的是Chrome内核。
uc浏览器用的是它自研发的u3内核
16,针对react。hook改变刷新页面
如果A页面map遍历循环加载某个组件b,如果b的状态hook能在组件能改变,就不要拿到A页面去变,因为如果在b组件内部改变hook,只是该组件自己刷新,而如果在A组件修改hook,会引起A页面中所有的b组件刷新,导致页面变卡顿。
17,预加载
使用<link preload />预加载比较大的图片,可以加快首屏渲染图片的速度