浏览器渲染机制,前端性能优化

  • List item

######js会阻塞页面的渲染和解析;link标签会阻塞渲染但不阻塞解析;

关于css阻塞:

​ 声明:只有link引入外部css才能够产生阻塞

1.style标签中的样式:

​ (1). 由html解析器进行解析;

​ (2). 不阻塞浏览器渲染(可能会产生“闪屏现象”)。

​ (3). 不阻塞DOM解析

  1. link引入的外部css样式(推荐使用的方式):

  2. (1) 由css解析器进行解析。

    (2) 阻塞浏览器渲染(可以利用这种阻塞变“闪屏现象‘)

    (3) 阻塞其后面的js语句执行

    (4) 不阻塞DOM的解析

  3. 优化核心理念:尽可能快的提高外部css加载速度

    (1) 使用CDN节点进行外部资源加速。

    (2) 对css进行压缩(利用打包工具,比如webpack,gulp)

    (3) 减少http请求书,将多个css文件合并

    (4) 优化样式表的代码

关于js阻塞

  1. 阻塞DOM解析

    ​ 原因:浏览器不知道后续脚本的内容,如果先去了解下面的dom,随后的js除了后面所有的DOM,

    ​ 那么浏览器就坐了无用功,浏览器无法预估脚本里面具体做了什么操作,例如像document.write

    ​ 这种操作,索性全部停住,等脚本执行完了浏览器再继续向下解析DOM。

  2. 阻塞页面悬案:

    ​ 原因:js中也可以给DOM设置样式,浏览器同样等该脚本执行完毕,再继续干活,避免做无用功、

  3. 阻塞后续js的执行:

    ​ 原因:维护依赖关系,例如:必须引入jQuery再引入bootStrap

备注

  1. css的解析和js的执行是互斥的,css解析的时候js停止执行,js执行的时候css停止解析。

  2. 无论css阻塞,还是js阻塞,都不会阻塞浏览器加载外部资源(图片、视频、样式、脚本等)

    原因:浏览器时钟处于一种:“先把请求发出去”的工作模式,只要是设到网络请求的内容,

    由浏览器自己协调,这种做法效率很高。

    1. webkit 和 firefox 都进行了【预解析】这项优化,在执行js脚本时,浏览器的其他线程会解析文档的其余部分,
找出并加载需要通过网络加载的其他资源,用过这种方式,资源可以在并行链接上加载,

从而提高总体速度。请注意,预解析器不会修改DOM树

在上述过程中,网页的加载和渲染过程中会触发DOMContentloadedh和onload事件

分别是在DOM树构建(解析)完成之后,以及DOM树构建完并且网页所依赖的资源都加载完成之后

重绘不一定触发重排;重排(回流)一定触发重绘;

移动浏览器窗口大小和开发者选项页面;都会引起页面重排重绘

成本比较高的操作

  1. 当你增加、删除、修改DOM节点时,会导致Reflow(重排),Repaint(重绘)

  2. 当你移动DOM的位置

  3. 当你Resize窗口的时候(移动端没有这个问题,因为移动端的缩放没有影响布局窗口)

  4. 当你修改网页的默认字体时

  5. 获取某些属性时(width,height…)

    注:display:none 会触发Reflow,而Visibility:hidden 只会触发Repaint,因为没有发生位置变化

优化方案

​ 如果我们需要使得动画或其他节点渲染的性能提高,需要做的就是减少浏览器在运行时所需要的做的工作(尽量减少1234步)

  1. 计算需要被加载到节点上的样式结果(Recalculate style–样式重计算)
  2. 为每个节点生成图形和位置(layout–回流和重布局)
  3. 将每个节点填充到图层中(paint setup和paint—重绘)
  4. 组合土城到页面上(composite Layers–图层重组)

一、元素位置移动变换时尽量使用css3的tranform来代替top left等的操作

​ 变换(transform)和透明度(opacity)的改变仅仅影响图层的组合

二、使用opacity来代替visibility

​ (1).使用visibility不触发重排,但依然重绘。

​ (2). 直接使用opacity即触发重绘,又触发重排(GPU底层设计如此!)。

​ (3). opacity配合图层使用,即不触发重绘也不触发重排。

​ 原因:

​ 透明度改变时,GPU(显卡)在绘画时知识简单的降低之前已经画好的纹理的alpha值来达到效果,并不需要整体重绘,不过这个前提是这个被修改opacity本身必须是一个图层。

三、不要用table进行布局

​ table-cell

四、将多次改变样式属性的操作合并成一次操作

​ 不要一条一条地修改DOM的样式,预定义好class,然后修改DOM的className

五、将DOM里先后再修改

​ 由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。

​ 如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示,这样只在隐藏和显示时触发2此;

六、利用文档碎片(documentFragment)----vue使用了该种方式提升性能。

七、不要吧获取某些DOM节点的属性值放在一个寻花里当成循环的变量

​ 当你请求向浏览器请求一些style信息的时候,就会昂浏览器flush队列,比如:

  1. offsetTop,offsetLeft,offsetWidth,offsetheight

  2. scrollTop/Left/Width/Height

  3. clientTop/Left/Width/Height

  4. width,height

    当你请求上面一些属性的时候,浏览器为了给你最精确的值,需要刷新内部队列,

    因为队列中可能会有影响到这些值的操作,机试你获取元素的布局和样式信息跟最近发生或改变的布局信息

    浏览器会强行刷新渲染队列

八、动画实现过程中,启用GPU硬件加速:transform:tranleteZ(0)

九、为动画元素新建图层,提高动画元素的z-index

requestAnimationFrame — 请求动画帧

​ window.requestAnimationFrame()

​ 1、window.requestAnimationFrame()

​ 说明该方法会告诉浏览器在重绘之前调用你所指定的函数

​ 1、参数:该方法使用一个回调函数作为参数,这个回调函数会在浏览器重回之前调用。

​ 回调函数会被自动传入一个参数,DOMHighResTimeStamp,标记requestAnimationFrame()

​ 2、返回值:

​ 一个long证书,也成为请求ID,是个非零值,是回调列表中唯一的标识,没别的意义。

​ 2、window.cancelAnimationFrame(requestID)

​ 取消一个先前通过调用window.requestAnimationFrame()方法添加到计划中的动画帧请求。

​ requestID是先前调用window.requestAnimationFrame() 方法时返回的ID

​ arguments 包含函数对象中的所有参数

什么是CDN?工作原理是什么?

​ 网站通常将其所有的服务器都放在同一个地方,当用户群增加时,公司就必须在多个地理位置不同的服务器上部署内容,为了缩短http请求时间,我们应该把大量的静态资源放置的离用户近一点。

​ 内容发布网络CDN(content Delivery Netwprks)

CDN是一组分布在多个不同地理位置的web服务器,能够更加有效地向用户发布内容

​ 基本思路:

​ 尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。

​ 通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,‘

​ CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息

​ 将用户的请求重新导向离用户最近的服务器节点上

基础架构:最简单的CDN网络由一个DNS服务器和几台缓存服务器组成
1、当用户点击网站页面上的内容URL,经过本地DNS系统解析,
DNS系统会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。
2、CDN的DNS服务器将CDN的全集负载均衡设备IP地址返回用户。
3、用户向CDN的全局负载均衡设备发起内容URL访问请求
4、CDN全局负载均衡设备根据用户IP地址,以及用户请求的内容URL。
选择一台用户所属区域的区域负载均衡设备,告诉用户这台设备发起请求。
5、区域负载均衡设备会为用户选择一台合适的缓存服务器提供服务,
选择的依据包括:根据用户IP地址,判断那一台服务器距用户最近;
根据用户所请求的UTL中携带的内容名称,判断哪一台服务器上有用户所需内容;

你可能感兴趣的:(js,css)