31、性能优化
初始阶段(加载优化)
首页加载优化
解答
对于首页加载过慢的问题,一般是由于首页加载资源过多并且资源过大导致,所以应对的策略一般是减少资源的数量以及减少资源的大小
对于图片可以进行懒加载,减少首屏图片加载量,以及对于小图标和小图片分别可以使用Iconfont和雪碧图来解决,最大程度的减少首屏图片渲染量,提高首屏加载速度
对于其他资源可以通过打包(nginx combo资源合并或者webpack打包)来合并资源,或者通过路由懒加载的方式来减少首页js加载的数量
同时可以在服务器配置nginx开启gzip打包来最大化压缩静态资源体积,达到优化首页加载的目的
问题分析(资源多、大)
1、首页加载图片过多
1、总结:
通过懒加载的方式处理非首屏图片
对于小图标可以使用Iconfont的方式来解决
对于小图片可以使用雪碧图的方式来解决
Q&A
Q:首页加载图片过多怎样处理
懒加载:监听滚动条事件,如果滚动条的高度距离浏览器顶部的高度等于或者接近于图片到浏览器顶部的高度,那么就将data-src的属性赋值到src上
Q:首页设置的小图标很多,比如有很多的小icon怎么办
对于纯色小图标可以用Iconfont来解决(减少资源请求)
设置font-famliy的css属性
对于一些彩色的小图标可以使用雪碧图
把所有小图标拼接到一张大图片上(减少资源请求)
并使用background-position的css属性来修改图片坐标
2、首页请求过多
2、总结(首页请求量过多,可以通过一些手段来减少资源的请求量)
通过nginx服务器来做静态资源的合并或者通过webpack等打包工具进行物理的打包
在代码层面,对于u 一些需要引入大型的第三方库进行按需加载,比如可以按照babel来进行
还可以通过react lazy等动态导入方案进行前端路由层面的动态加载,从而减少首页的js和css加载的大小
可以通过减少资源请求量
通过nginx服务器(可用来做CDN,处理静态资源)用来做文件合并combo—将多个js、css合并成一个。逻辑上打包,通过拼接请求链接,将多个资源链接合并到一起
通过打包工具(webpack)来做资源文件的物理打包。没有第一种灵活。
Q&A
Q:只有合并资源的方式才能减少资源请求吗?
对于引用一些大型的第三方库,比如antd、elementui等,可以使用按需加载的方式进行解决。一般都是使用babel插件来实现
针对SPA单页应用,在路由层面,可以使用前端路由懒加载的方式,从而减小首页js和css的大小
使用React.lazy进行路由的加载(react16.6以上才可以使用,16.6以下版本可以使用react-loadable)
Q:为什么React lazy可以进行路由懒加载?
首先react lazy是使用了动态加载(dynamic import)的一个标准,webpack只要遇到了动态加载就会把import的内容单独打一个包
由于动态加载返回的是一个promise,所以可以利用promise的流程来做渲染流程的控制
如果当前promise是pending状态,那么就渲染loading组件,如果是resolve状态那么就渲染动态导入的组件
动态导入:代码执行到import这一行的时候才开始去下载组件。并且webpack会将其单独打包成一个文件
lazy懒加载
结论:
import('xxx')返回的是一个promise
webpack只要遇到了import('xxx')就会把括号里引入的内容单独打一个包
3、首页请求的静态资源(html、css、js)过大
分析
要分资源文件、js、css等分开处理
css和js可以通过webpack进行混淆和压缩
混淆:将js代码进行字符串加密(最大程度减少代码,比如将变量名称程度单个字母等)
压缩:去除注释空行以及console.log等调试代码
图片的压缩
自动化工具来压缩图片
图片进行转码,转成base64格式
使用webP格式
通过开启gzip进行全部资源的压缩
gzip是一种压缩文件资源的格式,可以对任何文件进行压缩(类比于文件压缩),通过nginx服务器配置开启
优化图片的做法
解答:图片优化业主要是从两个方面来进行,太多和太大
通过懒加载减少加载图片请求,或者通过雪碧图来合并图片,以及将小图转化成base64格式减少图片请求
图片过大问题可以通过图片自动化压缩工具或者使用webp格式的图片
问题分析:
减少图片加载请求
减少图片大小
Q&A
Q:用什么自动化工具对图片进行压缩?
Q:还有什么其他方式吗
将图片转码为base64,会增大图片体积,因此不建议把大图片转成base64格式,但是建议把小图片转成base64格式,因为它直接写在代码中,可以减少一个图片的请求
使用webp格式
实现webpack打包优化
解答:多&大
可以设置mode=production来默认实现webpack对代码的混淆和压缩,从而最大程度减少代码体积
使用webpack+dynamic import(动态加载)并结合路由的入口文件动态加载做拆包处理
并且可以设置一定的打包策略(分包压缩,node_modules、常改动、不常改动公共组件),配合网络缓存(cache-control等)进行加载性能优化
问题分析
少:使用webpack进行物理打包
小:使用webpack进行混淆和压缩,所有与webpack相关的配置都在optimization这个配置项进行管理
Q&A
Q:打包怎样小怎样少?
A:使用webpack对代码进行混淆和压缩,并且可以使用react lazy进行拆包,结合路由进行按需加载
Q:对文件进行拆包处理,那么文件肯定会增多,会不会跟减少资源请求数量矛盾呢?
A:并不矛盾,因为我们按需加载之后,拆包的文件不可能同时加载,所以不会造成同一时间请求过多的问题
打包策略
实现CDN加速
解答:
CDN服务器主要是用来做静态资源的服务器,可以用来加速静态资源的下载
CDN之所以能够加速是因为在很多地方都部署了CDN服务器,如果用户需要下载静态资源,会自动选择最近的资源节点进行下载
同时由于CDN的服务器地址一般都跟主服务器不同,所以可以破除http1.0中对同一个域名同时发送的请求的限制问题
问题分析
什么叫做CDN(内容分发网站)
放静态资源服务器(JS、CSS、图片、字体..)。
为什么CDN可以实现加速?
因为里我们近。CDN服务器就是在里用户较近的地方放置一台服务器,把所有的静态资源放到这台服务器上,以后访问优先从这个网站上访问。CDN是一种解决方案,一般是用nginx实现。
为什么要进行CDN呢?
HTTP1.1。因为对于同一个协议、同一个域名、同一个端口,浏览器允许最多同时打开六个TCP连接(最多同时发送六个请求)。通过CDN可以绕过浏览器对这个请求的限制
http2:引入了多路复用的机制,可最大化发送请求数量。(没有了http1的六个TCP请求限制)
运行阶段(渲染优化)
思路:
导致卡顿的远影一般都是dom操作太多太频繁
如果想要渲染哦很多数据又不造成浏览器卡顿,那么肯定是要减少dom的操作。比如react创建虚拟dom,本质上是用js来模拟真实的dom,从而减少dom的操作
还有在插入多个dom节点时候,可以使用document.createDocumentFragment先创建虚拟节点,再一次性插入
也可以采取分段式渲染的方式requestAnimation来进行逐帧渲染
渲染十万条数据不造成卡顿?
结论:
可以使用document.createDocumentFragment创建虚拟节点来避免不必要的渲染
当所有的li都创建完成之后,再一次吧虚拟节点中的li全部渲染出来
可以采用分段渲染的方式,比如一次只渲染一屏的数据
最后使用
普通方式:
优化渲染(分段渲染 )
补充:requestAnimation逐帧渲染。1000/60=16,也就是16ms渲染一次。requestAnimation要保证浏览器是60帧,所以默认是16ms一次渲染。 拓展:服务器类别
应用服务器:弹性计算,存放运行后端代码等
存储服务器:存储文件
CDN服务器:处理静态资源,做资源文件的合并。做静态资源分发
数据库服务器