再次聊聊前端性能优化

再次聊聊前端性能优化

之前写过关于前端性能优化的文章(前端性能优化),但总觉得还是太笼统太敷衍,等到被问到为什么这样就会被绊住脚,今天就详细聊聊关于前端性能优化的点,以及到底为什么是这样。

性能优化主要分为两类:

加载时优化、运行时优化

一、加载时优化

1、减少HTTP请求

一个完整的HTTP请求需要经历DNS查找、TCP握手、、浏览器发送HTTP请求、服务器接收请求、服务器处理请求并且发回响应、浏览器接收响应等过程。
在这里插入图片描述

  • Queueing:浏览器将资源放入队列的时间
  • Stalled:因放入队列时间而发生的停滞时间
  • Proxy negotiation:与代理服务器连接进行协商所花费的时间
  • Request sent:发出网络请求所花费的时间
  • DNS Lookup:DNS解析时间
  • Initial connection:建立HTTP连接的时间
  • SSL:浏览器与服务器建立安全性连接的时间
  • TTFB:等待服务端返回数据的时间
  • Content Download:浏览器下载资源的时间

从这张图片看,真正下载数据的时间占比为 0.75/404.79,文件越小,比例越小,文件越大,比例越高。所以建议将多个小文件合并成一个大文件,从而减少HTTP请求次数。

2、使用HTTP2

HTTP2相比于HTTP1.1的优点:

  1. 解析速度快。服务器解析HTTP1.1的请求时,需要不断读入字节,直到遇到分隔符CRLF为止。而HTTP2是基于帧的协议,每个帧都有表示帧长度的字段。
  2. 多路复用。HTTP1.1如果同时发起多个请求,就得建立多个TCP连接,因为一个TCP连接同时只能处理一个HTTP1.1的请求。而在HTTP2上,多个请求可以公用一个TCP连接。同一个请求和响应用一个流来表示,并且有唯一的流ID来标识。多个请求和响应在TCP连接中可以乱序发送,到达目的地后再通过流ID重新组建。
  3. 首部压缩。HTTP2将不同请求中相同的首部存储起来,仅发送它们之间不同的部分,就可以节省不少的溜了,加快请求时间。
  4. 优先级。HTTP2可以对比较紧急的请求设置一个较高的优先级,服务器在收到这样的请求后可以优先处理。
  5. 流量控制。由于一个TCP连接流量带宽是固定的,当有多个请求并发时,一个请求占的流量多,另一个请求占的流量就少,流量控制可以对不同流的流量进行精确控制。
  6. 服务器推送。HTTP2可以对一个客户端请求发送多个响应,也就是说,除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求。

3、使用服务端渲染

  • 客户端渲染:获取HTML文件,根据需要下载JavaScript文件,运行文件,生成DOM,再渲染。
  • 服务端渲染:服务端返回HTML文件,客户端只需要解析HTML文件。

区别就是:客户端渲染的网站会直接返回HTML文件,而服务端渲染的网站则会渲染完页面再返回这个HTML文件。

这样客户端渲染的网站需要加载几个文件和HTML文件才能完成页面渲染,而服务端渲染的网站只需要加载一个渲染完成的HTML文件就能完成页面渲染。

4、静态资源使用CDN

CDN(内容分发网络):是一组分布在不同地理位置的Web服务器。当服务器离用户越远时,延迟时间越长,而CDN就是为了解决这一问题,在多个位置部署服务器,让用户离服务器更近,从而缩短请求时间。

5、将CSS放在文件头部,JavaScript放在文件底部

CSS执行会阻塞渲染,组织JS执行,而JS加载和执行会阻塞HTML解析,阻止CSSDOM创建。

若将CSS和JavaScript文件都放在HEAD标签里,这样需要很长时间去加载和解析,这就导致页面空白,为了避免这种情况发生,JS文件就要放在底部(不阻塞DOM解析,但是会阻塞渲染),等HTML解析完了再加载JS文件,尽快向用户呈现页面内容。

关于为什么将CSS文件放在头部:因为先加载HTML再加载CSS,会导致用户第一时间看到的是没有样式的页面,降低用户体验。

其实JS文件也是可以放在头部的,只要给script标签加上defer属性就可以异步下载,延迟执行。

6、善用缓存,不重复加载相同的资源

我们可以通过添加Expires或者max-age来控制浏览器缓存。

Expires设置了一个时间,只要在这个时间之前,浏览器都不会请求文件,而是直接使用缓存。而max-age是一个相对时间,建议使用max-age代替Expires。

7、压缩文件

利用webpack和gzip压缩文件,可以减少文件下载时间。

8、图片优化

(1)使用字体图标代替图片图标

字体图标iconfont将图标制作成一个字体,可以设置属性,例如font-size、color等,优点是不会失真,而且生成的文件比较小。

(2)图片延迟加载

在一个图片量很大的网页中,一次性加载全部图片会对用户体验造成很大影响,可以在页面中先不设置图片路径,只有当图片出现在浏览器的可视区域时,才加载真正的图片,即延迟加载,也叫懒加载。

(3)响应式图片

响应式图片就是能够根据屏幕大小自动加载合适的图片。

通过 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);
    }
}

(4)调整图片大小

可以使用缩略图来减少图片加载时间。
例如一些没必要展示整张大图的图片,可以选择缩略图进行占位,当用户点击或者悬浮去看大图时再进行加载。

(5)尽可能利用 CSS3 效果代替图片

有很多图片使用 CSS 效果(渐变、阴影等)就能画出来,这种情况选择 CSS3 效果更好。因为代码大小通常是图片大小的几分之一甚至几十分之一。


二、运行时优化

1、减少重绘重排

重排和重绘这两个操作都是非常昂贵的,因为 JavaScript 引擎线程与 GUI 渲染线程是互斥,它们同时只能一个在工作。

2、使用事件委托

事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。所有用到按钮的事件(多数鼠标事件和键盘事件)都适合采用事件委托技术, 使用事件委托可以节省内存。

3、查询语句

当判断条件较多时,越倾向于使用 switch 而不是 if-else。当条件语句特别多时,使用 switch 和 if-else 不是最佳的选择,这时不妨试一下查找表。查找表可以使用数组和对象来构建。

4、不要覆盖原生方法

无论你的 JavaScript 代码如何优化,都比不上原生方法。因为原生方法是用低级语言写的(C/C++),并且被编译成机器码,成为浏览器的一部分。当原生方法可用时,尽量使用它们,特别是数学运算和 DOM 操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值