引言: 转前端一年了,期间工做较忙,也没时间整理一些知识体系,此系列文章是对前端基础的一些回顾与总结。本文主要介绍浏览器工做的原理以及一些优化手段。
以chorme为例:php
须要注意的是,NPAPI是指浏览器对系统或外部的一些程序的调用接口,好比播放视频的 flash 插件,而Pepper实际上是基于NPAPI改进的插件架构。css
主流的浏览器内核主要有2种,Webkit 和 Geoko ,虽然 chorme 如今的内核更换为 blink ,但其实 blink是基于webkit的,差别不大。其渲染过程分别以下:html
这两个内核的渲染流程大同小异,主要的过程能够总结为下列5个:前端
使用chorme浏览器的开发者工具,咱们很容易看到这5个过程的时间线,下面是segmentfault主页的渲染截图:vue
能够看到上述流程的耗时,甚至能够统计到每一帧的耗时分布,从而对影响渲染性能的代码精肯定位。其中黄色为JS,紫色为Style和Layout,绿色为Paint和Composite部分,选中每一个部分会显示各自的花费时间等信息,能够看出这个图片中JS运行的时间太长。目前的显示设备通常刷新率是60FPS,因此理想中每帧的时间最好为16毫秒。html5
须要注意的一点是,这里的步骤执行并无特定的顺序,为保证渲染的速度,浏览器一开始接收到html时就开始执行解析的过程,而且遇到须要重绘和重排的时候会重复执行这些步骤,下面咱们详细介绍一下这5个过程。node
浏览器在接收到html文件后即开始解析和构建DOM树,在碰到js代码段时,因为js代码可能会改变dom的结构,因此为避免重复操做,浏览器会中止dom树构建,先加载并解析js代码。而对于css,图片,视频等资源,则交由资源加载器去加载,这个过程是异步的,并不会阻碍dom树的生成。这个过程须要注意的点是:react
display:none
的元素、注释存在于dom树中async
或 defer
浏览器在碰到<link>
和 <style>
标签时,会解析css生成cssom , 固然,link标签须要先将css文件加载完成才能解析。
须要注意的是:webpack
在cssom 和dom 树都构建完成后,浏览器会将他们结合,生成渲染对象树,渲染树的每个节点,包含了可见的dom节点和节点的样式 。
须要注意的是:git
display:none
是不会放入渲染树的。visibility: hidden
的元素在Render Tree中这一步是浏览器遍历渲染对象树,并根据设备屏幕的信息,计算出节点的布局、位置,构建出渲染布局树(render layout)。渲染布局树输出的就是咱们常说的盒子模型,须要注意的是:
float
, absolute
, fixed
的元素的位置会发生偏移浏览器对生成的布局树进行绘制,由用户界面后端层将每一个节点绘制出来。此时,Webkit内核还须要将渲染结果从Renderer进程传递到Browser进程。
前面讲到,js代码能够访问和修改dom节点和css,因此在解析js的过程当中会致使页面从新布局和渲染,这就是重绘(repaint)和回流(reflow)。
重绘是指css样式的改变,但元素的大小和尺寸不变,而致使节点的从新绘制。
任何对元素样式,如background-color
、border-color
、visibility
等属性的改变。css 和 js 均可能引发重绘。
回流(reflow)是指元素的大小、位置发生了改变,而致使了布局的变化,从而致使了布局树的从新构建和渲染。
固然,咱们的浏览器不会每一次reflow都马上执行,而是会积攒一批,这个过程也被成为异步reflow,或者增量异步reflow。可是有些状况浏览器是不会这么作的,好比:resize窗口,改变了页面默认的字体,等。对于这些操做,浏览器会立刻进行reflow。
优化并非无目的的,而是经过分析页面各个维度,找到亟待优化的方向或者具体到某段代码。下面就讨论一下如何对页面作性能分析和测速监控。
chorme得devtools相信全部的前端开发者都用过,它不只提供了平常开发中极强的调试能力,同时也具有着极强的页面分析能力。
通常来讲,咱们打开一个页面,指望的是页面的响应和呈现速度和流畅的交互体验。因此,页面的测速指标能够大体归纳为: 白屏时间,首屏时间,可交互时间。
window.performance是w3c提供的用来测量网页和Web应用程序的性能api。其中performance timing提供了延时相关的性能信息,能够高精度测量网站性能。timing的总体结构以下图所示:
关于性能优化,涉及的方向太广了,从网络请求到数据库,整条链路都有其可优化的地方。这里我只总结一下前端比较须要关注的一些优化点。这里从两个个维度进行讨论:
从上文可知,浏览器渲染网页的前提是下载相关的资源,html文档、css文档、图片资源等。这些资源是客户端基于HTTP协议,经过网络请求从服务器端请求下载的,你们都知道,有网络,一定有延迟,而资源加载的网络延迟,是页面缓慢的一个重要因素。因此,如何使资源更快、更合理的加载,是性能优化的必修课。
因为HTTP的限制,在创建一个tcp请求时须要一些耗时,因此,咱们对资源进行合并、压缩,其目的是减小http请求数和减少包体积,加快传输速度。
segmentfault.com 的雪碧图图标
将一些静态资源文件托管在第三方CDN服务中,一方面能够减小服务器的压力,另外一方面,CDN的优点在于,CDN系统可以实时地根据网络流量和各节点的链接、负载情况以及到用户的距离和响应时间等综合信息将用户的请求从新导向离用户最近的服务节点上,保证资源的加载速度和稳定性。
缓存的范围很广,好比协议层的DNS解析缓存、代理服务器缓存,到客户端的浏览器本地缓存,再到服务端的缓存。一个网络链路的每一个环节都有被缓存的空间。缓存的目的是简化资源的请求路径,好比某些静态资源在客户端已经缓存了,再次请求这个资源,只须要使用本地的缓存,而无需走网络请求去服务端获取。
segmentfault 的主页的一些静态资源使用了缓存,上面是一些控制缓存的header首部字段
分片指得是将资源分布到不一样的主机,这是为了突破浏览器对同一台主机创建tcp链接的数量限制,通常为6~8个。现代网站的资源数量有50~100个很常见,因此将资源分布到不一样的主机上,能够创建更多的tcp请求,下降请求耗时,从而提高网页速度。
从segmentfault 的主页请求能够看出,网站将静态js文件和图片都放在了不一样的子域名下。
能够升级咱们的网络协议,好比使用HTTP2,quic 之类的,代替以前的http1.1,从协议层优化资源的加载。能够参考我以前的文章。
虽然作好了静态数据的加载优化,可是仍是会出现一种情景,即静态数据已经加载完毕,但页面仍是在转菊花,页面尚未进入可交互状态,这是由于现现在的网站开发模式,先后端分离已经成为主流,再也不由php或jsp服务端渲染前端页面,而是前端先加载静态数据,再经过ajax异步获取服务器的数据,进而从新渲染页面。这就致使了异步从接口获取数据也是网页的一个性能瓶颈。响应缓慢,不稳定的接口,会致使用户交互体验极差,页面渲染速度也不理想。好比点击一个提交数据的按钮,接口速度慢,页面上菊花须要转很久才能交换完数据。
为了提高用户体验,咱们认为首屏的渲染速度是极为重要的,用户进来页面,首页可见区域的加载能够由服务端渲染,保证了首屏加载速度,而不可见的部分则能够异步加载,甚至作到子路由页面的预加载。业界已经有不少同构直出的方案,好比vue的nuxt , react的beidou等。
前端常常有这样的场景,完成一个功能须要先请求第一个接口得到数据,而后再根据数据请求第二个接口获取第二个数据,而后第3、第四...前端一般须要经过promise或者回调,一层一层的then下去,这样显然是很消耗性能的
一般后台接口都按必定的粒度存在的,不可能一个接口知足全部的场景。这是不可避免的,那么如何作到只发送一个请求就能实现功能呢?有一种不错的方案是,代理服务器实现请求合并,即后台的接口只须要保证健壮和分布式,而由nodejs(固然也可使用其余语言)建设一层代理中间层,流程以下图所示:
前端只须要按找约定的规则,向代理服务器发起一次请求,由代理服务器向接口服务器发起三次请求,再将目标数据返回给客户端。这样作的好处是:一方面是代理服务器代替前端作了接口合并,减小了前端的请求数量;另外一方面代理服务器能够脱离HTTP的限制,使用更高效的通讯协议与服务器通讯;
页面中的css 和 js 会阻塞html的解析,由于他们会影响dom树和render树。为了不阻塞,咱们能够作这些优化:
defer
和 async
属性告诉浏览器能够异步加载,不阻塞解析重绘和回流在实际开发中是很难避免的,咱们能作的就是尽可能减小这种行为的发生。
fixed
或 absolute
的 position
,那么修改他们的 CSS 是不会 Reflow 的。display:none
,再修改属性,这里只发生一次回流。transform
来作形变和位移,不会形成回流这最能体现一个前端工程师的水平了,高性能的代码能在实现功能的同时,还兼顾性能。下面是一些好的实践:
debounce
和 throttle
这两个函数。好比scroll
和touch
事件...
优化没有正确答案,优化的手段也层出不穷,这里也没法归纳全面,只列举了一些我了解过的。其实除了前端,后端也有许多可优化的地方,好比接口缓存啊,数据库缓存啊等等。这个本骚年就了解的不深了。
性能一直是前端开发很重要的一个课题。性能优化也是一条不见尽头的路,任重而道远啊~
参考文章:
https://segmentfault.com/a/11...
https://sylvanassun.github.io...
https://www.html5rocks.com/zh...
https://juejin.im/post/5a966b...
https://juejin.im/post/59672f...
https://tech.meituan.com/perf...
https://segmentfault.com/a/11...
https://www.jianshu.com/p/268...