初始阶段->加载优化
1.首页加载慢优化
原因:首页图片过多、首页请求量过多,首页请求静态资源(html,css,js,图片过多,过大)
优化方向
图片:
图片懒加载处理非首屏(第一次代开网页的可视区)的图片,减少首页图片的加载量
纯色系图标可以使用iconfont,
彩色系小图片使用精灵图(雪碧图)。
请求量:
-- 通过浏览器的network可以确定首页加载的资源和请求数量
requests:请求数量
resources:前端总资源大小
DOMContentLoaded:浏览器已经完全加载了HTML,其他静态资源(js,css,图片等),并没有加载完成(能够看到页面,但不能使用)
load:浏览器已经加载所有静态资源(能够使用了)
-- 通过浏览器更多里有一个converge 来查看代码使用情况
该项只针对css和js
可以看出哪些代码加载但是没有执行
没有执行的代码是否可以考虑懒加载。
对一些大的第三方库,可以进行按需加载。
资源文件:css,js,图片等分开处理
– css和js可以通过webpack来进行混淆和压缩
混淆:将js代码进行字符串加密(最大程度减少代码,比如将常变量变成单个字母等)
压缩:去除注释行,空行,及console 等调试代码
– 图片压缩
可以通过自动化工具(熊猫站:智能压缩png和jpg的网站:无损压缩:通过减少颜色数量及不必要的数据来实现压缩。可以通过npm安装,因为这个网站开放了)来压缩图片
对图片进行转码->base64格式(会增大文件体积:可以使用webpack的url-loader进行图片策略配置,将小图转换为base64格式,因为base64格式的图片是减少资源请求的数量,转换为base64就可以减少请求数量,但是base64格式的图片会增大图片原有体积,所以不建议将大图转换为base64)
使用webp格式(根据Goole测试,同等条件等比例无损压缩后的webp比png格式的文件少26%的体积,并且图片越多,压缩的体积优势越明显)
-- 通过开启gzip进行全部资源压缩
gzip是一种文件压缩格式,可以对任何文件进行压缩
可以通过nginx 服务器配置进行开启
2.优化图片
减少图片请求–懒加载图片
减少图片大小
3.实现webpack打包优化
从webpack4开始,会根据你选择的mode选执行不同的优化,不过所有的优化还是可以手动配置重写。
development:不混淆,不压缩,不优化
production:混淆+压缩,自动内置优化
只需将mode改成production即可
打包策略:
我们通常把包分为两类: 第三方包(node——modules里)
自己实现的代码(src里)
及公共的和非公共的
我们可以把第三方打成一个包,公共代码打成一个包
第三方包:改动频率小
非公共代码包:改动频率大
结合缓存来优化:
对于不需要经常变动的资源(第三方包)。可以使用cache-control:max-age=31536000 (缓存一年),并配合协商缓存(Etag一旦文件变动才会下载新的文件)
对于需要平缓变动的资源,可以使用cache-control:nocache并配合Etag使用,表示该资源已被缓存,但是每次都会询问资源是否更新。
4.实现CDN加速(内容分发网络:存放静态资源的服务器,可以用好加速静态资源的下载,cdn之所以能够加速,是因为会在很多地方部署cdn服务器,如果用户需要下载资源,会自动选择最近的节点下载,同时由于cdn服务器的地址一般跟主服务器的地址不同,所以可以破除浏览器对同一个域名发送请求的限制)
运行阶段->渲染阶段
资源已经加载完成
针对代码进行优化
渲染数据不卡顿
为什么会造成浏览器卡顿
1.无论是dom还是bom,还是nodejs它们都是基于JavaScript引擎之上开发出来的。
2.dom和bom处理最终都是要被转换成JavaScript引擎能够处理的数据。
3.这个转换过程很耗时
4.所以在浏览器中最消耗性能的操作就是dom
所以最终目标就是减少操作dom
怎么优化渲染很多数据:
思路:懒加载思路 – 分段渲染,一次渲染一屏的数量,可以定义要分多少端渲染,一次渲染 每次渲染的数据 = 总数据 / 分多少段
假如我们现在要加载十万条数据
在不进行优化的情况下(我在goole测试大概要4s左右)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
//监听dom是否渲染完成
let stateCheck = setInterval(()=>{
if(document.readyState === 'complete'){
clearInterval(stateCheck)
console.timeEnd()
}
},100)
</script>
</head>
<body>
<ul></ul>
<script>
console.time()
//插入十万条数据
const total = 100000
let ul = document.querySelector('ul')
function add(){
//创建虚拟节点,使用document.createDocumentFragment() 不会触发渲染
const fragment = document.createDocumentFragment()
//循环十万次
for(let i = 0; i < total; i++){
const li = document.createElement('li')
li.innerText = Math.floor(Math.random() * total)
fragment.appendChild(li)
}
// 把虚拟节点append 到ul 上
ul.appendChild(fragment)
}
add()
</script>
</body>
</html>
优化懒加载情况下(大概100ms左右)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
//监听dom是否渲染完成
let stateCheck = setInterval(()=>{
if(document.readyState === 'complete'){
clearInterval(stateCheck)
console.timeEnd()
}
},100)
</script>
</head>
<body>
<ul></ul>
<script>
console.time()
//插入十万条数据
const total = 100000
let ul = document.querySelector('ul')
//懒加载思路 分段渲染。
// 1.一次渲染一屏
const once = 20
//2. 全部渲染完需要多少次,循环时使用
const loopCount = total / once
// 3.已经渲染了多少次
let countHasRender = 0
function add(){
//创建虚拟节点,使用document.createDocumentFragment() 不会触发渲染
const fragment = document.createDocumentFragment()
//循环十万次
for(let i = 0; i < once; i++){
const li = document.createElement('li')
li.innerText = Math.floor(Math.random() * total)
fragment.appendChild(li)
}
// 把虚拟节点append 到ul 上
ul.appendChild(fragment)
// 4.已渲染次数+1
countHasRender += 1
loop()
}
// 核心部分
function loop(){
// 5.如果还没渲染完,那么window.requestAnimationFrame来继续渲染
if(countHasRender < loopCount) {
// window.requestAnimationFrame 叫做逐帧渲染,类似于setTimeout(add,16)
// 帧,一秒钟播放多少张图片,一秒钟播放多少张图片越多,画面(动画)越流畅
// 1000/60 = 16 帧:fps 人眼一秒钟能播放60张图片就是比较流畅的
// requestAnimationFrame 默认就是16毫秒
window.requestAnimationFrame(add)
}
}
loop()
</script>
</body>
</html>