加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

前端性能优化不完全手册 【已更新至React】

发布时间:2019-04-14 10:35:48 所属栏目:优化 来源:Jerry谭金杰
导读:副标题#e# 性能优化是一门大学问,本文仅对个人一些积累知识的阐述,欢迎下面补充。 抛出一个问题,从输入url地址栏到所有内容显示到界面上做了哪些事? 1.浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址; 2.建立TCP连接(三次握手); 3.浏览
副标题[/!--empirenews.page--]

 前端性能优化不完全手册 【已更新至React】

性能优化是一门大学问,本文仅对个人一些积累知识的阐述,欢迎下面补充。

抛出一个问题,从输入url地址栏到所有内容显示到界面上做了哪些事?

  •  1.浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
  •  2.建立TCP连接(三次握手);
  •  3.浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
  •  4.服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;
  •  5.浏览器将该 html 文本并显示内容;
  •  6.释放 TCP连接(四次挥手);

上面这个问题是一个面试官非常喜欢问的问题,我们下面把这6个步骤分解,逐步细谈优化。

一、DNS 解析

  •  DNS`解析:将域名解析为ip地址 ,由上往下匹配,只要命中便停止
    •   走缓存
    •   浏览器DNS缓存
    •   本机DNS缓存
    •   路由器DNS缓存
    •   网络运营商服务器DNS缓存 (80%的DNS解析在这完成的)
    •   递归查询

优化策略:尽量允许使用浏览器的缓存,能给我们节省大量时间。

二、TCP的三次握手

  •  SYN (同步序列编号)ACK(确认字符)
    •   第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等 待Server确认。
    •   第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
    •   第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

三、浏览器发送请求

优化策略:

  •  1.HTTP协议通信最耗费时间的是建立TCP连接的过程,那我们就可以使用HTTP Keep-Alive,在HTTP 早期,每个HTTP 请求都要求打开一个TCP socket连接,并且使用一次之后就断开这个TCP连接。 使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少TCP连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高http服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用
  •  2.但是,keep-alive并不是免费的午餐,长时间的TCP连接容易导致系统资源无效占用。配置不当的keep-alive,有时比重复利用连接带来的损失还更大。所以,正确地设置keep-alive timeout时间非常重要。(这个keep-alive_timout时间值意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接),如果想更详细了解可以看这篇文章keep-alve性能优化的测试结果
  •  3.使用webScoket通信协议,仅一次TCP握手就一直保持连接,而且他对二进制数据的传输有更好的支持,可以应用于即时通信,海量高并发场景。webSocket的原理以及详解
  •  4.减少HTTP请求次数,每次HTTP请求都会有请求头,返回响应都会有响应头,多次请求不仅浪费时间而且会让网络传输很多无效的资源,使用前端模块化技术 AMD CMD commonJS ES6等模块化方案将多个文件压缩打包成一个,当然也不能都放在一个文件中,因为这样传输起来可能会很慢,权衡取一个中间值
  •  5.配置使用懒加载,对于一些用户不立刻使用到的文件到特定的事件触发再请求,也许用户只是想看到你首页上半屏的内容,但是你却请求了整个页面的所有图片,如果用户量很大,那么这是一种极大的浪费
  •  6.服务器资源的部署尽量使用同源策略

四、服务器返回响应,浏览器接受到响应数据

五、浏览器解析数据,绘制渲染页面的过程

  •  先预解析(将需要发送请求的标签的请求发出去)
  •  从上到下解析html文件
  •  遇到HTML标签,调用html解析器将其解析DOM树
  •  遇到css标记,调用css解析器将其解析CSSOM树
  •  link 阻塞 - 为了解决闪屏,所有解决闪屏的样式
  •  style 非阻塞,与闪屏的样式不相关的
  •  将DOM树和CSSOM树结合在一起,形成render树
  •  layout布局 render渲染
  •  遇到script标签,阻塞,调用js解析器解析js代码,可能会修改DOM树,也可能会修改CSSOM树
  •  将DOM树和CSSOM树结合在一起,形成render树
  •  layout布局 render渲染(重排重绘)
  •  script标签的属性
    •   async 异步 谁先回来谁就先解析,不阻塞
    •   defer 异步 按照先后顺序(defer)解析,不阻塞
    •   script标签放在body下,放置多次重排重绘,能够操作dom

性能优化策略:

  •  需要阻塞的样式使用link引入,不需要的使用style标签(具体是否需要阻塞看业务场景)
  •  图片比较多的时候,一定要使用懒加载,图片是最需要优化的,webpack4中也要配置图片压缩,能极大压缩图片大小,对于新版本浏览器可以使用webp格式图片webP详解,图片优化对性能提升最大。
  •  webpack4配置 代码分割,提取公共代码成单独模块。方便缓存   
  1. /*  
  2.     runtimeChunk 设置为 true, webpack 就会把 chunk 文件名全部存到一个单独的 chunk 中,  
  3.     这样更新一个文件只会影响到它所在的 chunk 和 runtimeChunk,避免了引用这个 chunk 的文件也发生改变。  
  4.     */  
  5.     runtimeChunk: true,   
  6.     splitChunks: {  
  7.       chunks: 'all'  // 默认 entry 的 chunk 不会被拆分, 配置成 all, 就可以了  
  8.     }  
  9.   }  
  10.     //因为是单入口文件配置,所以没有考虑多入口的情况,多入口是应该分别进行处理。 
  •  对于需要事件驱动的webpack4配置懒加载的,可以看这篇webpack4优化教程,写得非常全面
  •  一些原生javaScript的DOM操作等优化会在下面总结

六、TCP的四次挥手,断开连接

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读