前端面试(1)-页面渲染-性能优化

TCP——传输控制协议

  • 是一种面向连接的、可靠的、基于字节流的传输层通信协议。
  • 类似——电话之间的通信;
  • 双方建立一次TCP连接,需经过三个步骤:
    • 客户端发送SYN包到服务器,并且自身进入SYN_SEND状态,等待服务器确认
    • a给b拨打电话,a等待b接听电话。
    • 服务器收到SYN包,确认客户端的SYN包之后,自己也发送一个SYN包,也就是SYN+ACK包,自身进入SYN_RECV状态。
    • b听到电话响起,拿起电话。
    • 客户端收到服务器的SYN_ACK包,向服务器发送确认包ACK,发送完毕之后,客户端和服务器就进入连接状态(ESTABLISHED),最后完成三次握手。
    • a确定是b之后,双方开始讲话。
  • 备注:
    • SYN-建立联机
    • ACK-确认
    • SYV_SENV请求连接
    • SYN_RECV服务器接收到客户端SYN,并发送ACK的状态
    • ESTABLISHED双方连接已建立
    • tcp三次握手不携带任何数据

HTTP协议——超文本传输协议

  • 应用层协议、基于TCP协议、用于包装数据,程序使用它进行通信,可以进行简单高效的处理通信中数据的传输和识别。
  • TCP是传输层上的一种协议,用于在网络中传输数据。
  • http连接,客户端发起请求,服务器响应请求之后,连接会自动断开,不会一直保持。

URL——统一资源定位符

  • 标识具体资源的地址-https://www.baidu.com/index.html
  • URL = 协议(https协议)+ 服务器地址/ip(www.baidu.com) + 路径 + 文件名(index.html包含路径和文件名)
  • http使用url建立连接和传输数据

DNS——域名服务器

  • 域名和IP地址转换的服务器,使用域名映射IP地址
  • 用户输入https:www.baidu.com回车,经过下面几个步骤:
    • 浏览器会根据地址在本身的缓存中查找DNS解析记录,如果有,直接返回IP地址,没有的话,浏览器会查找操作系统中host文件是否有该域名的dns解析记录,有则返回。
    • 若上述两个地方都没有记录,或者已经过期,此时向域名服务器发起请求来解析这个域名。
    • 请求先到LDNS(本地域名服务器),让它尝试解析该域名,如果解析不了,直接到根域名解析器请求解析。
    • 根域名服务器给LDNS返回一个可查询的主域名服务器的地址-gTIDServer
    • LDNS向主域名服务器gTID发起解析请求
    • gTID服务器接收到解析请求后查找并返回此域名对应的Name Server域名服务器地址,通常为你注册的域名服务器,比如:阿里DNS
    • Name Server域名服务器会查询存储域名和IP的映射关系表,将得到的目标IP记录和TTL值返回给LDNS域名服务器
    • LDNS会缓存这个域名和IP对应关系,缓存时间有TTL值控制
    • 把解析结果返给用户,用户根据TTL值缓存在本地系统中,域名解析过程结束。

HTTP请求发起和响应

  • 用户输入URL,浏览器呈现页面,经历 什么过程。
    • 用户输入、浏览器获取到URL
    • 浏览器进行DNS解析(若输入IP,可跳过)
    • 根据解析后的ip地址和端口,浏览器发起http请求,请求中携带(header、body)。
      • header——请求方法、协议、目标Url、cookie之类
      • body——请求的内容(参数)
      • 请求过程
        • 到达传输层,tcp协议为传输报文提供可靠的字节流传输服务,它通过三次握手等手段来保证传输过程中的安全可靠。通过对大块数据的分割成一个个报文段的方式提供给大量数据的便携传输。
        • 到达网络层,网络层通过ARP寻址得到接收方的Mac地址,IP协议把在传输层被分割成一个个数据包传送接收方。
        • 数据到达数据链路层,请求阶段完成
    • 接收方【在数据链路层】收到数据包之后,层层传递到应用层,接收方应用程序就获得到请求报文。
    • 接收方收到发送方的HTTP请求之后,进行请求文件资源(如HTML页面)的寻找并响应报文。
    • 发送方收到响应报文后,如果报文中的状态码表示请求成功,则接受返回的资源(如HTML文件),进行页面渲染。preview
    • 页面渲染过程:
      • 浏览器通过HTML parser (html解析器),根据深度遍历的原则把html解析成DOM tree
      • 通过CSS parser将css解析成CSSOM Tree
      • 利用CSSOM Tree 和DOM Tree来构造render Tree
      • layout——根据得到的render Tree来计算所有节点在屏幕的位置
      • paint——遍历render树,并调用硬件图形api来绘制每个节点。

前端性能优化——针对页面渲染过程

  • HTML解析
    • 在解析过程,浏览器根据HTML文件的结构从上到下解析html,HTML元素是以深度优先的方式解析,而script、link、style等标签会使解析过程产生阻塞,阻塞的情况有:
      • 外部样式会阻塞内部脚本的执行。
      • 外部样式与外部脚本并行加载,但外部样式会阻塞外部脚本执行。
      • 如果外部脚本带有async属性,则外部脚本的加载与执行不受外部样式影响
      • 如果link标签是动态创建(js生成),不管有无async属性,都不会阻塞外部脚本的加载与执行。
    • 优化:
      • 避免再HTML中直接写css代码。
      • 使用Viewport加速页面的渲染。
      • 使用语义化标签,减少css的代码,增加可读性和SEO。
      • 减少标签的使用,dom解析是一个大量遍历的过程,减少无必要的标签,能降低遍历的次数。
      • 避免src、href等的值为空。
      • 减少dns查询的次数。
  • CSS解析
    • 在对样式解析的过程中,默认CSS选择器是从右往左进行解析的。css解析器要做的事情不多,但要每个节点都要进行遍历查找计算,计算量极大,因此解析的方式是决定其性能的关键点。
    • 优化:
      • 优化选择器路径:健全的css选择器固然是能让开发看起来更清晰,然后对于css的解析来说却是个很大的性能问题,因此相比于 .a .b .c{} ,更倾向于大家写.c{}。
      • 压缩文件:尽可能的压缩你的css文件大小,减少资源下载的负担。
      • 选择器合并:把有共同的属性内容的一系列选择器组合到一起,能压缩空间和资源开销
      • 精准样式:尽可能减少不必要的属性设置,比如你只要设置{padding-left:10px}的值,那就避免{padding:0 0 0 10px}这样的写法
      • 雪碧图:在合理的地方把一些小的图标合并到一张图中,这样所有的图片只需要一次请求,然后通过定位的方式获取相应的图标,这样能避免一个图标一次请求的资源浪费。
      • 避免通配符:.a .b *{} 像这样的选择器,根据从右到左的解析顺序在解析过程中遇到通配符(*)回去遍历整个dom的,这样性能问题就大大的了。
      • 少用Float:Float在渲染时计算量比较大,尽量减少使用。
      • 0值去单位:对于为0的值,尽量不要加单位,增加兼容性
  • 脚本执行——javascript
    • 浏览器解析HTML时,当遇到<script>标签就会立即解析脚本,同时阻塞解析文档直到脚本执行完毕(你可能问为什么要这样设计,明显啊,脚本的执行是改变css和dom,会造成render tree不停的重绘和重排的),而当<script>是引入外部js文件时,会阻塞到js文件下载完成并且执行完成为止(除非加了defer或者async属性)。脚本在解析过程中将对dom或css的操作解析出来加入到DOM Tree和cssom中。
    • 优化:
      • 尽可能把script标签放到body之后,避免页面需要等待js执行完成之后dom才能继续执行,最大程度保证页面尽快的展示出来。
      • 尽可能合并script代码,
      • css能干的事情,尽量不要用JavaScript来干。毕竟JavaScript的解析执行过于直接和粗暴,而css效率更高。
      • 尽可能压缩的js文件,减少资源下载的负担
      • 尽可能避免在js中逐条操作dom样式,尽可能预定义好css样式,然后通过改变样式名来修改dom样式,这样集中式的操作能减少reflow或repaint的次数。
      • 尽可能少的在js中创建dom,而是预先埋到HTML中用display:none来隐藏,在js中按需调用,减少js对dom的暴力操作。
  • 参考:https://segmentfault.com/a/1190000016580701
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值