前端性能优化的终极奥义

前端性能优化的终极奥义

浏览器输入url按回车键,到完成页面加载可交互的过程

这是一个很常见的面试问题,面试官主要想考察的有几个点:

  • 1 初步判断:是否熟悉网络的请求过程
  • 2 涉及知识点:缓存、dns解析、http请求过程,浏览器的解析代码的过程与原理
  • 3 终极目的:在各个节点有哪些可以性能优化的方案
客户端发送请求
  1. 解析输入:判断是搜索内容还是请求的url地址,如果是搜索内容调用搜索引擎,如果是url地址,开始构建请求,浏览器会构建请求行信息,构建好后,准备发起网络请求。
  2. 查找缓存:如果缓存中存有副本,会拦截请求,返回缓存资源,直接结束请求。如果缓存查找失败,就会进入网络请求过程了。
  3. DNS域名解析,先查找localDNS缓存(80%都能找到),直接请求。
  4. 三次握手建立TCP连接,如果是https请求,还要建立TLS安全连接。
  5. 发送HTTP请求,请求头和请求体的方式来告诉服务器我们的“诉求”
    下图是Chrome DevTools截取的一个https请求耗时图:
    在这里插入图片描述
服务端响应

服务端通过接收客户端的请求,进行一些列的验证,解析,处理,将准备好的数据通过发送响应行、响应头和响应体的方式返回客户端,关闭TCP连接,客户端接收数据

浏览器接收数据
  1. HTML通过HTML Parser解析成DOM,解析过程中遇到css,image,js去加载资源,js会阻塞解析,因为js可以操作dom,所以解析js时候回DOM停止解析,img的src属性不会停止渲染,不影响页面加载
  2. Style Sheets通过CSS Parser解析成CSSOM,描述每个元素具体的位置和大小
  3. DOM+CSSOM渲染成RenderTree 此时就相当于DOM和CSS混合在一起的数,不需要显示的去掉(如display:node的节点会被去掉)
  4. Layout创建绘制记录,确定绘制顺序
  5. Paint开始绘制,此过程会涉及reflow(回流)和repain(重绘)
  6. Composite混合层级,将页面拆分图层树,构建图层树,像素化每个图层创建一个复合帧,形成当前可见的画面
    以上为页面解析到可见,到能够交互还需要js文件通过加载 => 解析和编译 => 执行完成后才可以交互
  7. js解析和编译(Evaluate Script&Compile Script)
    v8解析js过程:Parse it => AST => Bytecode => Machine Code 比较耗时。(需要优化增强)
  8. js代码执行,先进行变量提升(var和function),然后代码自上而下执行,先执行当前队列的宏任务,再执行微任务,之后开始执行下一个队列的宏任务和微任务,进行事件循环。
  9. 此时可交互
    js操作dom会触发一下流程:
    JavaScript(触发事件变化)=> style(重计算)=> layout=> paint=> composite

前端性能优化

  1. 合理使用缓存:包括强缓存Expires(http1.0) 和 Cache-Control(http1.1优先级高),协商缓存Last-Modified(http1.0)和ETag(http1.1优先级高),webpck打包加个[contenthash]后缀及时清除缓存
  2. 减少请求次数:合并代码,使用base64压缩小图片、使用雪碧图
  3. 减小资源体积:压缩代码,压缩图片,Gzip压缩传输
  4. 静态资源使用CDN加速,提高访问速度
  5. 使用http2传输数据:http2基于https开启,进行二进制传输(安全),请求头压缩减小体积,多路复用传输数据快,支持server push。请求量高的情况下速度提高明显
  6. HTML优化:压缩空白字符以及注释(html-minifier),减少iframe使用,有加载过程,延迟加载,避免深层次嵌套,避免使用table布局,css和js外链,读写分离,进行批量读写,防止强制回流(fastDom)

HTML最佳实践:
css在head里引
body中html5的语义化标签
不需要闭合img is self-closing:no closing slash
li 标签也可以不写闭合的符号
js放到尾部加载防止影响dom加载,尽早执行js,用DOMContentLoaded触发

  1. CSS优化:压缩&合并:减少http请求,减少请求资源的大小
    降低css对渲染的阻塞,首屏以外的css可以延迟加载
    动画可以gpu加速 不需要布局和重绘,tramslate做位移,不回流,只触发composite混合
    flex布局:优化加载的顺序
    ul li {contain:layout}告诉浏览器li内部的变化和外部没有布局的关系不影响其他的地方,浏览器会单独处理,避免布局计算
    字体加载显示优化使用font-display属性
  2. JS优化:压缩混淆,代码拆分,按需加载,treeshaking代码减重,减少主线程的工作量,避免长任务,使用raf和ric进行时间调度,行间脚本不要超过1kb,减少行内样式,因为浏览器对行间脚本优化较少,可以使用async/defer属性对js异步加载,避免乱用闭包。
    v8引擎对函数默认懒解析(lazyParse用的时候在解析函数),对于申明完很快调用的函数可以使用()将表达式包起来触发饥饿解析engerparse

DOM操作相关优化:
1)对DOM进行缓存,存在一个变量里操作
2)将频繁的DOM操作,合并到一起插入DOM结构中
3)使用虚拟DOM
针对浏览器的机制对对象相关操作优化:
1)以相同顺序初始化对象成员,避免隐藏类调整
2)实例化后避免添加新属性
3)尽量使用Array代替array-like对象,类数组转化成数组执行效率高
4)避免超过数组的长度
5)避免类型的转化const arr=[1,2,3];arr.push(4.4) 同一类型浏览器会有优化,类型不同 优化会降级
图片的加载优化:懒加载lazy-load,使用img的sizes和srcset属性适配不同屏幕图片
preload:调整加载顺序,可以提前加载较晚但很重要的资源,
prefetch:有空闲时预加载后边需要的资源

  1. 优化首屏加载:优先加载最小可交互资源,其余延时加载
    SSR:提高首屏加载,搜索引擎排名,问题:牺牲TTFB(Time To First Byte)来补救FirstPaint;
    预渲染页面(react-snap): 通过hidechrome(看不到的chrome)预先爬取页面的内容,前端打包时候就已经组织好页面的嵌入,防止闪屏需要配置css内联
  2. 列表优化:windowing(窗口化) 提高列表的渲染性能,只渲染可见区域的内容留出预留,如:react-window可配置一维的list列表 ,二维列表Grid,配置滚动到指定元素
  3. 骨架组件:减少布局移动(layout shift),起到占位作用,如react-placeholder
  4. webpack优化:提取公共代码,css代码抽离,base64编码,加hash后缀,懒加载

production:自动进行压缩混淆,tree-shaking,Scope Hosting
构建优化(dev):
自动刷新:整个页面刷新,状态丢失
热更新:新代码生效,页面不刷新,状态不丢失
DllPlugin:动态链接库,将大的不常换版本的库打包出dll文件引用,提高开发效率
构建优化(prod):
babel-loader开启缓存
IgnorePlugin:直接不引入,在代码中导入相应需要的模块
noParse:对于已经是.min后缀的文件引入但不打包
happyPack:多进程打包
ParallelUgligyPlugin:多进程压缩JS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值