《一》前端页面的生命周期
多进程浏览器
- 浏览器主进程
- GPU进程
- 插件进程
- 网络进程
- 渲染进程:js引擎线程,事件触发线程,定时触发器线程,异步Http线程
1.DNS解析
将url上的host转换为ip地址
浏览器缓存-系统自身dns缓存-系统hosts文件查找-本地域名服务器-根域名服务器/COM顶级域名服务器/权限域名服务器-找不到报错
原理和优化
DNS解析拿到ip地址,建立网络连接【此时数据链路层和网络层打通,需要通过传输层建立端到端的连接,发起http请求,即需要tcp协议的“三次握手”和“四次挥手”】
2.前后端交互
反向代理服务器,如nginx
- 负载均衡
- 安全防火墙
- 加密和ssl加速
- 数据压缩
- 跨域
- 静态资源缓存 其他优化空间:
http协议
- http1.0 短连接
- http1.1 长连接,connection:keep-alive,服务器配置持续化时间,优化:雪碧图
- http2.0 多复用特性,http头部压缩,设置请求优先级,服务器主动推送 浏览器缓存
- 强缓存:cache-control:max-age 200
- 协商缓存:if-none-match和服务端的e-tag是否匹配,比http1.0的last-modified更准确。304
3.经历网络请求过程,从服务器获取到的页面文件,将其渲染出来
《二》资源压缩和合适的文件格式选型
矢量图:svg,放大不失真 位图:jpg,png,gif,jpeg
- jpeg:使用glup将images进行渐进式编程
- gif:内容长的用video代替
- png:npm引入插件,对多余块进行删除压缩
- webp:用window.navigater.userAgent处理兼容性问题
- img的srcset和picture
《三》加载优化
图片,视频加载
传统懒加载
- class,src,data-src属性
- 利用事件监听scrool,resize回调事件
- 判断图片是否在视窗內img.getBoundClientReact.top < window,innerHeight
- 请求赋值
- 图片加载完,取消监控 优化:节流200ms但重复调用setTimeout,200ms时间不精准等依旧存在性能问题。 代码:p54
intersection onserver方式
intersection onserver:每当页面滚动,target与数据交集时,会触发intersection onserver回调函数。 存在兼容性问题,polyfill插件
css类名方式 css的background-image .one.visible高清 .one低清
entry.target.classList.add('visible')
chrome 75自带的loading=“lazy”
if('loading' in HTMLImageElement.prototype){
// loading=“lazy”
}else{
// 传统方式
}
视频加载
video preload 请求连接数6,preload=none/metadate
注意事项
- 要设置缓存区,提前加载,如intersection onserver方式中的rootMargin
- 资源占位:不用导致位移,回流
- 图片加载失败,用image.onerror回调重新加载
资源优先级
预加载
link ref="preload" as="style" 对单个文件进行预加载,快也有缓存。缺点:在浏览器和服务器中发生额外的往返请求。解决办法:http2推送
预连接
link ref="preconnect"
link ref="dns-prefetch"
预提取
link ref="prefetch"
《四》书写高性能代码
条件语句:
- 1,2条用if else
- 2-10条用switch
- 超过10条,借助策略模式,用数组索引或对象属性方式查找 循环语句:
- for-in
for(let props in array){
if(object.hasOwnProperty(props)){}
}
可遍历json课枚举属性,但要检测原型,性能比较慢
- foreach 比较直观,也慢
- for-of es6新加的,相对比较快,但没有常规循环快
- 三种常规循环:
for/while/do-while递归
缺失或不明确递归的终止条件会造成卡顿。,通过空间换时间,有内存开销。由于浏览器有限制调用栈大小,超出限制的递归无效。可改成迭代的方式,性能慢点,不过不在限制于浏览器对js调用栈的限制。 优化:利用闭包避免重复操作,存在问题:函数闭包延长了局部变量的存活率,数据量大又不能回收,会存在内存溢出。
字符串处理
《五》构建优化
css和js的压缩合并
合并: 优点:减少网络丢包严重现象
缺点:
- 合并文件大,加载完在渲染,首次渲染慢
- 存在缓存失效问题【md5戳,标识发生改变更新】 建议:
合并公共库,改动不频繁
webpack优化【不太全】
-
webpack采用局部安装+npx
-
loader上配置exclude,如排除node-modules,减少loader的执行,可配置缓存:
loader:“babel-loader?cacheDirectory=true” -
配置压缩插件,
resolve中alias参数 -
使用dllplugin拆分配置第三方包,如react,react-dom,lodash等。存在就获取,不存在就在node-modules中获取所需模块
《六》渲染优化
实现动画效果
css:transition/animation html:canvas js:setTimeout
- 因为setTimeout事件执行机制,需要等待主线程执行完,会比延迟时间晚些,与屏幕刷新时间不同步,出现丢帧卡顿现象
- 用requestAnimataionFrame:将回调函数的执行时间由系统决定,与屏幕刷新时间同步
恰当的使用web worker
节流与防抖(代码p124)
以闭包的形式包裹回调函数,通过自由变量缓存计时器信息,最后用setTimeout控制事件触发的频率来实现
节流:第一次触发,如scrool事件,懒加载
return(params)->{
if(now-last>=time){
claaback(params)
}
}
防抖:最后一件事件【需要设置一条延迟等待的时间地线】
return(params)->{
// 判断事件触发时间是否超出节流时间间隔
if(now-last<time){
clearIimeout(timer)
timer = setTimeout(()=>{
last=now;
claaback(params)
})
}
}
css计算样式优化
- 用标签选择器替代通配符 css选择器匹配从右到走,如.list li{},是先匹配全部li,在找对应的 .list 。我们需要在li设置为 .litag,减少查找标签元素的范围,少用通配符。
- 降低选择器的复杂性 如设置class类名
- 使用BEM规范 建议使用单一的类选择器,不仅结构清晰,而且渲染阶段的样式计算性能提升
页面布局
页面布局:js执行-样式计算-页面布局-绘制-合成
-
使用类名对样式合并修改
-
缓存对敏感属性的计算
let top=list.offsetTop; -
使用requestAnimationFrame控制渲染帧
-
will-change / transform:translate(0)