【面试题】前端性能优化

参考文章:
前端性能优化 24 条建议
前端必会!四步带你吃透浏览器渲染基本原理
大公司里怎样开发和部署前端代码?
前端性能优化的七大手段
和面试官吹嘘一下我的Vue项目性能优化

优化原理

1、网络:
请求次数:合并文件(抽取公共库),@import会增加请求次数、减少重定向、雪碧图与base64
文件大小:各种静态资源(三剑客和流数据)压缩、gzip、webp、去除空格consolelog注释并混乱变量、轻量的文件类型比如iconfont代替图
缓存:协商缓存、强缓存、CDN缓存、DNS缓存,浏览器预读取(阅读模式?)
连接:长连接(http1.1)、并行连接(http1.1 最大并行6)、多路复用(http2)
2、渲染:
异步下载:script的defer(html解析后执行)和async、防抖与节流(尤其是滚动条)、防止重绘与重排、css头js尾(如果是布局相关的js也要放在头)
按需加载:懒加载、webpack按需加载
服务端渲染
vue的v-if和v-show
3、机器资源:
首屏、白屏时间
内存:减少闭包、垃圾回收、事件代理
CPU:选择器、CSS动画
4、工程化(打包)
打包公共代码
剔除无用代码:tree shaking
公用代码内联至index.html

一、输入url到页面呈现的过程

解析URL
浏览器本地缓存
DNS解析
建立TCP/IP连接
发送HTTP请求
服务器处理请求并返回HTTP报文
浏览器根据深度遍历的方式把html节点遍历构建DOM树
遇到CSS外链,异步加载解析CSS,构建CSS规则树
遇到script标签,如果是普通JS标签则同步加载并执行,阻塞页面渲染,如果标签上有defer / async属性则异步加载JS资源
将dom树和CSS DOM树构造成render树
渲染render树

1、域名解析及请求
用户输入浏览器后,浏览器核心会将url进行拆分解析。会把domain(域名,比如www.alibaba.com)发送给DNS服务器,DNS服务器会根据domain查询到对应的ip,然后将ip返回给浏览器。浏览器拿到ip后,将ip放到协议中,携带请求相关参数发送到网络中,经过局域网、交换机、路由器、主干网络,最终发送到服务端。服务端拿到数据后会返回响应。
2、浏览器解析文档
浏览器拿到响应后,会进行如下操作:
在这里插入图片描述
DOM:浏览器解析html,生成DOM树
CSSOM:浏览器解析css规则(css文件和标签中的style),形成CSSOM树
Render:通过DOM和CSSOM合成Render树
Layout:计算出Render树的节点具体位置,进行布局
Painting:通过显卡GPU绘制Layout
Reflow、repaint
以上步骤是一个渐进的过程,为了提高用户体验,渲染引擎试图尽可能快的把结果显示给最终用户。它不会等到所有HTML都被解析完才创建并布局渲染树
在这里插入图片描述

二、屏幕刷新率

大多数设备的刷新频率是60Hz,也就说是浏览器对每一帧画面的渲染工作要在16ms内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验

优化思路:

1、网络方面:Dns缓存、减少http请求、减小http请求大小、浏览器端缓存、CDN。
2、文件方面:源代码、图片、多媒体数据。
3、异步加载:script标签async和defer、懒加载、服务端渲染等等
4、代码层面:CSS、JS编程风格

具体优化

一、网络方面

建议学习:半个小时搞懂HTTP、HTTPS、HTTP2
1、减少HTTP请求
一个完整的 HTTP 请求需要经历 DNS 查找,TCP 握手,浏览器发出 HTTP 请求,服务器接收请求,服务器处理请求并发回响应,浏览器接收响应等过程。
在这里插入图片描述
Queueing: 在请求队列中的时间。
Stalled: 从TCP 连接建立完成,到真正可以传输数据之间的时间差,此时间包括代理协商时间。
Proxy negotiation: 与代理服务器连接进行协商所花费的时间。
DNS Lookup: 执行DNS查找所花费的时间,页面上的每个不同的域都需要进行DNS查找。
Initial Connection / Connecting: 建立连接所花费的时间,包括TCP握手/重试和协商SSL。
SSL: 完成SSL握手所花费的时间。
Request sent: 发出网络请求所花费的时间,通常为一毫秒的时间。
Waiting(TFFB): TFFB 是发出页面请求到接收到应答数据第一个字节的时间。
Content Download: 接收响应数据所花费的时间。
从这个例子可以看出,真正下载数据的时间占比为 13.05 / 204.16 = 6.39%,文件越小,这个比例越小,文件越大,比例就越高。这就是为什么要建议将多个小文件合并为一个大文件,从而减少 HTTP 请求次数的原因。
简单来讲,其实很多关于传输的问题,连接都会占到很大一部分时间,比如数据库的连接请求和释放连接,HTTP的三次握手连接,都会占到很大的时间。如果将多个请求合并成一个请求,就会省去很多连接时间,让用户有更好的体验。

2、使用HTTP2
核心优势(相对HTTP1.1):多路复用、首部压缩、服务器推送、二进制传输
(1)二进制传输(解析速度快)
服务器解析 HTTP1.1 的请求时,必须不断地读入字节,直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦,因为 HTTP2 是基于帧的协议,每个帧都有表示帧长度的字段。
(2)多路复用
HTTP1.1 如果要同时发起多个请求,就得建立多个 TCP 连接,因为一个 TCP 连接同时只能处理一个 HTTP1.1 的请求。
在 HTTP2 上,多个请求可以共用一个 TCP 连接,这称为多路复用。同一个请求和响应用一个流来表示,并有唯一的流 ID 来标识。 多个请求和响应在 TCP 连接中可以乱序发送,到达目的地后再通过流 ID 重新组建。
(3)首部压缩
请求响应头部有很多数据都是重复的。如果可以把相同的首部存储起来,仅发送它们之间不同的部分,就可以节省不少的流量,加快请求的时间。
(4)服务器推送
HTTP2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。换句话说,除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求。
例如当浏览器请求一个网站时,除了返回 HTML 页面外,服务器还可以根据 HTML 页面中的资源的 URL,来提前推送资源。
(5)优先级
HTTP2 可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后,可以优先处理。
(6)流量控制
由于一个 TCP 连接流量带宽(根据客户端到服务器的网络带宽而定)是固定的,当有多个请求并发时,一个请求占的流量多,另一个请求占的流量就会少。流量控制可以对不同的流的流量进行精确控制
注意:在开发者工具中,protocol字段为h2的就是使用了http2协议
在这里插入图片描述
3、服务端渲染(SSR,Server Side Render)
建议阅读:服务端渲染
(1)两种渲染方式的定义
客户端渲染(浏览器端渲染,CSR,Client Side Render): 获取 HTML 文件,根据需要下载 JavaScript 文件,运行文件,生成 DOM,再渲染。
服务端渲染:服务端返回 HTML 文件,客户端只需解析 HTML。
优点:首屏渲染快,SEO 好。
缺点:配置麻烦,增加了服务器的计算压力。
(2)两种渲染方式的过程
客户端渲染过程
访问客户端渲染的网站。
服务器返回一个包含了引入资源语句和

的 HTML 文件。
客户端通过 HTTP 向服务器请求资源,当必要的资源都加载完毕后,执行 new Vue() 开始实例化并渲染页面。
服务端渲染过程(感觉有点像JSP架构)
A 访问服务端渲染的网站。
B 服务器会查看当前路由组件需要哪些资源文件,然后将这些文件的内容填充到 HTML 文件。如果有 ajax 请求,就会执行它进行数据
预取并填充到 HTML 文件里,最后返回这个 HTML 页面。
C 当客户端接收到这个 HTML 页面时,可以马上就开始渲染页面。与此同时,页面也会加载资源,当必要的资源都加载完毕后,开始
执行 new Vue() 开始实例化并接管页面。
从上述两个过程中可以看出,区别就在于第二步。客户端渲染的网站会直接返回 HTML 文件,而服务端渲染的网站则会渲染完页面再返回这个 HTML 文件。
(3)服务端渲染的优势
是更快的内容到达时间 (time-to-content)。
假设你的网站需要加载完 abcd 四个文件才能渲染完毕。并且每个文件大小为 1 M。
这样一算:客户端渲染的网站需要加载 4 个文件和 HTML 文件才能完成首页渲染,总计大小为 4M(忽略 HTML 文件大小)。而服务端渲染的网站只需要加载一个渲染完毕的 HTML 文件就能完成首页渲染,总计大小为已经渲染完毕的 HTML 文件(这种文件不会太大,一般为几百K,我的个人博客网站(SSR)加载的 HTML 文件为 400K)。这就是服务端渲染更快的原因。

4、静态资源使用CDN
建议阅读:CDN是什么
(1)CDN原理
内容分发网络(CDN)是一组分布在多个不同地理位置的 Web 服务器。我们都知道,当服务器离用户越远时,延迟越高。CDN 就是为了解决这一问题,在多个位置部署服务器,让用户离服务器更近,从而缩短请求时间。
(2)CDN查找过程和普通DNS方式的
当用户访问一个网站时,如果没有 CDN,过程是这样的:
A 浏览器要将域名解析为 IP 地址,所以需要向本地 DNS 发出请求。
B 本地 DNS 依次向根服务器、顶级域名服务器、权限服务器发出请求,得到网站服务器的 IP 地址。
C 本地 DNS 将 IP 地址发回给浏览器,浏览器向网站服务器 IP 地址发出请求并得到资源。
在这里插入图片描述
如果用户访问的网站部署了 CDN,过程是这样的:
A 浏览器要将域名解析为 IP 地址,所以需要向本地 DNS 发出请求。
B 本地 DNS 依次向根服务器、顶级域名服务器、权限服务器发出请求,得到全局负载均衡系统(GSLB)的 IP 地址。
C 本地 DNS 再向 GSLB 发出请求,GSLB 的主要功能是根据本地 DNS 的 IP 地址判断用户的位置,筛选出距离用户较近的本地负载均衡
系统(SLB),并将该 SLB 的 IP 地址作为结果返回给本地 DNS。
D 本地 DNS 将 SLB 的 IP 地址发回给浏览器,浏览器向 SLB 发出请求。
E SLB 根据浏览器请求的资源和地址,选出最优的缓存服务器发回给浏览器。
F 浏览器再根据 SLB 发回的地址重定向到缓存服务器。
G 如果缓存服务器有浏览器需要的资源,就将资源发回给浏览器。如果没有,就向源服务器请求资源,再发给浏览器并缓存在本地。
在这里插入图片描述
5、将 CSS 放在文件头部,JavaScript 文件放在底部
所有放在 head 标签里的 CSS 和 JS 文件都会阻塞渲染。如果这些 CSS 和 JS 需要加载和解析很久的话,那么页面就空白了。所以 JS 文件要放在底部,等 HTML 解析完了再加载 JS 文件。
那为什么 CSS 文件还要放在头部呢?
因为先加载 HTML 再加载 CSS,会让用户第一时间看到的页面是没有样式的、“丑陋”的,为了避免这种情况发生,就要将 CSS 文件放在头部了。
另外,JS 文件也不是不可以放在头部,只要给 script 标签加上 defer 属性就可以了,异步下载,延迟执行。

6、使用字体图标 iconfont 代替图片图标
字体图标就是将图标制作成一个字体,使用时就跟字体一样,可以设置属性,例如 font-size、color 等等,非常方便。并且字体图标是矢量图,不会失真。还有一个优点是生成的文件特别小。

7、使用缓存,不重复加载相同的资源
强缓存、协商缓存等等

8、压缩文件

9、图片优化
(1)延迟加载(懒加载)
web 前端图片懒加载实现原理
在页面中,先不给图片设置路径,只有当图片出现在浏览器的可视区域时,才去加载真正的图片,这就是延迟加载。对于图片很多的网站来说,一次性加载全部图片,会对用户体验造成很大的影响,所以需要使用图片延迟加载。
首先可以将图片这样设置,在页面不可见时图片不会加载:

<img data-src="https://avatars0.githubusercontent.com/u/22117876?s=460&u=7bd8f32788df6988833da6bd155c3cfbebc68006&v=4">

等页面可见时,使用 JS 加载图片:

const img = document.querySelector('img')
img.src = img.dataset.src

(2)响应式图片
响应式图片的优点是浏览器能够根据屏幕大小自动加载合适的图片。
通过 picture 实现

<picture>
    <source srcset="banner_w1000.jpg" media="(min-width: 801px)">
    <source srcset="banner_w800.jpg" media="(max-width: 800px)">
    <img src="banner_w800.jpg" alt="">
</picture>

通过 @media 实现

@media (min-width: 769px) {
    .bg {
        background-image: url(bg1080.jpg);
    }
}
@media (max-width: 768px) {
    .bg {
        background-image: url(bg768.jpg);
    }
}

(3)调整图片大小
例如,你有一个 1920 * 1080 大小的图片,用缩略图的方式展示给用户,并且当用户鼠标悬停在上面时才展示全图。如果用户从未真正将鼠标悬停在缩略图上,则浪费了下载图片的时间。
(4). 降低图片质量
例如 JPG 格式的图片,100% 的质量和 90% 质量的通常看不出来区别,尤其是用来当背景图的时候。
(5). 尽可能利用 CSS3 效果代替图片
有很多图片使用 CSS 效果(渐变、阴影等)就能画出来,这种情况选择 CSS3 效果更好。
(6). 使用 webp 格式的图片
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都相当优秀、稳定和统一。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值