前端性能优化

122 阅读7分钟

前端性能优化

减少整体加载时间:减小文件体积、减少http请求、使用预加载

使网站尽快可用:仅加载首屏内容,其他内容根据需要进行懒加载

平滑和交互性:使用css替代js动画、减少ui重绘

感知表现:耗时操作要给用户反馈,比如加载动画、进度条、骨架屏等

性能测定:性能指标、性能测试、性能监控持续优化

第一部分 性能评判的标准(性能指标)

RAIL性能模型

响应(response):应该尽可能快的响应用户,100ms内响应用户输入;

动画(animation):动画的每一帧应该以16ms渲染,配合当今大部分设备的60帧,避免卡顿;

空闲(idle):在使用js主线程的时候,应该把任务划分到执行时间小于50ms的片段中去,这样可以释放线程以进行用户交互

加载(load):应该在小于1s的时间内加载完你的网站,并且可以进行交互

基于用户体验的性能指标

First Contentful Paint(FCP) 浏览器首次绘制来自DOM内容的时间

内容必须是文本、图片、背景图、非白色的canvas或svg,以及正在加载中的web字体的文本

0--2s--4s--

LCP (largest Con Pain。。。)可视区域最大的内容元素呈现到屏幕上的时间

主要考虑到的元素有:/内的/

0--2.5s--4s--

FID (First Input Delay) 首次输入延迟

从用户第一次与页面交互到浏览器的实际能够响应交互的时间。

输入延迟是因为浏览器的线程在做别的事情,所以不能响应用户,此时浏览器正在解析和执行javascript;

哪些内容会受FID影响:

 - 文本输入框、复选框、单选按钮
 - 选择下拉菜单
 - 链接

0--100ms--300ms--

TTI (Time to Interactive) 网页第一次完全达到可交互状态的时间点

0--3.8s--7.3s--

TBT (Total Block Time) 总阻塞时间

所有长任务超出时间的总和

0--300ms--600ms--

CLS (Cumulative Layout Shift) 累计布局偏移

0--0.1s--0.25s--

Speed  Index 后面详解

Web Vitals

chrome提出的一个指标方案,将上面的好多指标简化为三个指标:

LCP/FID/CLS

只需要把这三个指标做好,性能就算是好的优化

第二部分 性能测试以及性能测试的工具

首先必须要有一个观念:不要通过单一指标来判定性能

Lighthouse 灯塔工具

可以直接在chrome调试工具中使用

检测得分

90 以上就是不错的

性能指标

在检测得分结果出来后,点击See calculator,有每个指标的详细评分以及占比情况,建议优先优化占比较高的

优化建议Opportunity和诊断结果

在检测结果出来后,下方Opportunity里会有优化建议,主要有以下方面

移除阻塞渲染的资源

预连接所要请求的源

降低服务端响应时间

适当调整图片大小

移除未使用的css

等等 具体看具体报告内容

仅供参考,具体话还得考虑生命周期匹配正确的优化方案

WebPageTest 网站

云服务器,提供了多个节点,支持多地点的测试结果

Chrome DevTools

第三部分 网站的整个生命周期

浏览器收到URL,开启网络请求线程;

发出完整的http请求

dns解析

就是将输入的URL解析出来,并且通过查找,将域名转换为ip地址

通信链路的建立

建立TCP连接,三次握手。关闭时四次挥手

在服务器收到请求之前,往往加入了反向代理服务器

服务器收到请求并具体处理

  • 验证环节,如跨域验证、安全校验拦截等
  • 通过验证之后,进入后台代码执行阶段,如具体的计算、数据库的查询等
  • 完成计算后,以http响应数据的形式发送回请求的前端,结束本次请求

前后台之间的http交互和缓存相关机制

  • 浏览器缓存等等

浏览器接收到数据包后的关键渲染路径(crp)

构建对象模型

首先浏览器会通过解析HTML和CSS文件,来构建DOM(文档对象模型)和CSSOM(层叠样式表对象模型)

之后将DOM和CSSOM合并渲染,Render Tree

js的解析过程

第四部分 优化方案

一、请求和响应优化

1、DNS解析优化

减少dns请求次数

dns-prefetch 预获取

比如在HTML文件最后有,这里是在处理完HTML之后要去请求dns,则可以在内加入 来进行dns的预获取

注意:仅在跨域时使用,不要指向自身;慎用,多页面重复预解析会增加查询次数;

更多dns优化,更多与后端相关

  • 延长dns缓存时间
  • 使用cdn加速域名
  • 自己搭建dns服务

2、HTTP请求

  • 减少请求数量

    • 合并脚本和样式表
    • 将图片嵌入css代码

3、避免重定向

4、压缩传输的数据资源

5、HTTP缓存(都是在服务端设置的,或者node中台设置,静态资源大部分是ngix设置的)

http缓存主要分为强制缓存和协商缓存,二者的主要区别在于判断缓存命中时,浏览器是否需要向服务端进行询问以协商缓存的相关信息,进而判断是否需要就响应内容进行重新请求。

《1》强制缓存

        如果浏览器判断所请求的目标资源有效命中,就可以直接从强制缓存中返回请求响应,无需与服务器进行任何通信

        实现:服务端在响应头里设置 'Cache-Control':'max-age=num'  num就是设置的多久过期,单位是秒,此时,只要在过期时间内,发出的相同的请求都会走缓存,而不会去请求服务器

《2》协商缓存

        在使用本地缓存之前,需要向服务器端发起一次GET请求,与之协商当前浏览器保存的本地缓存是否已经过期

        实现:在响应头里的字段'Cache-Control':'no-cache'表示走协商缓存,'last-modified':'时间',表示这个资源的最后修改时间是什么时候。下次请求时,如果服务器判断未过期,则返回一个304响应码,便直接走缓存;如果过期,则返回新的资源

       补充:可以在响应头中添加'etag':'基于文件内容生成的密码戳',以此来规避这个问题:当文件内容没变,但是文件名改变了,进而导致的走请求不走缓存。

      补充:浏览器在请求时,将最后修改时间和etag带给服务端,服务端判断。前端基本无需操作。

《3》缓存决策

      在规划缓存决策时,一般是以下步骤:

    是否使用缓存?默认no-----如果使用缓存?是否进行协商缓存?是--设置no-cache/否-----是否会被代理服务器缓存?是--public/否--private(具体的查一查)----------配置强制缓存过期时间-----------配置协商缓存的etag

     一般的缓存策略:

     - 因为HTML文件因为内容会发生修改,设置为协商缓存;
     - 图片文件:因为网站对图片基本都是更改,所以设置为强制缓存,且强制缓存的时间不宜过长。cache-control:max-age:86400
     - style.css文件,也设置为强制缓存,但是为了触发更新,当文件改变时,文件名要发生改变。(这也是为什么打包工具会根据内容打包出不同的文件名),过期时间可以延长到一年  max-age:31536000
     - 最后是js脚本,类似style.css设置,但其中因为有较多的用户私人信息,不想让中间代理缓存,则可为cache-control添加pravite属性

6、Service Worker缓存

   实现离线弱网络环境下的页面加载以及页面的预加载,基于web weoker ,调用一些api,具体实现方法查文档;

   也能实现请求不到资源时快速跳转到错误页面,而不会等待很久的白屏时间

   开源框架:Workbox、sw-toolbox(封装了一些缓存策略)

7、CDN缓存

8、Push缓存

9、使用服务端渲染

ssr、react中的nextjs,vue中的nuxtjs

10、使用预渲染

二、渲染优化

三、资源加载优化

四、图片优化

五、构建优化