我认为一个好的前端工程师不是能完成各种需求和交互,而是能够将信**息快速并且以一种友好的方式**传递给用户。
所以当用户输入网址后,我们的战斗就开始了。
在战斗开始之前,先让我们一起来了解一下一次完整的请求都有哪些过程,只有这样,我们才能知道仗该怎么打。
复制代码
文章最后有彩蛋~
第一个过程: DNS解析 当用户输入网址后,机器首先会把网址转化成计算机能识别的地址,即IP地址。 DNS解析过程是一个递归查询的过程。 它首先会在本地域名服务器中查询IP地址,如果没有找到,本地域名服务器会向根域名服务器发送一个请求,如果再没有还会往上查找,直到找到对应的IP地址。
第二个过程:准备HTTP请求 这个过程就是构建HTTP请求报文并通过TCP协议发送到服务器指定端口。一个请求报文分为三个部分: 请求行,请求头和请求正文。 这里就不详细介绍HTTP请求了,不了解的可以参考《图解HTTP》一书,相当不错!
第三个过程:TCP连接 当客户端HTTP请求准备完毕之后,接下来就是发送给服务器端,而HTTP协议依赖于TCP作为其传输层协议的。这里简单说下互联网协议分为四层: 应用层(HTTP协议就在这一层) 传输层 网络层 数据链路层 HTTP请求会从应用层往上走,直到服务器端,然后服务器端会反向将响应数据传回客户端,这些《图解HTTP》都会讲到。
第四个过程:服务器端处理请求并返回HTTP报文
这部分主要是后端一块的事,有兴趣的可以了解一下。
复制代码
第五个过程:浏览器解析并渲染页面
这个过程可以说是我们前端的最主要的战场,也是我们必须要了解的过程!
浏览器在收到服务器返回的数据里,一般会包含HTML,CSS和JS文件。那么,浏览器是如何完成解析渲染的呢?
首先,需要明确一点:浏览器是边解析边渲染的。
关于HTML,CSS,JS文件,浏览器解析顺序完全是根据返回数据来决定的。
一般情况下,大家都会把CSS放在HTML的前面,而JS放在最后面,因为CSS会定义HTML标签的样式,所以要在前面,而JS放在后面的原因是,当浏览器解析引擎解析JS时,HTML的渲染过程会被暂停,因为JS有可能会修改DOM结构,这就意味着JS执行完成前,后面的wHTML渲染是没有意义的,有可能会被重构。这就是JS会影响HTML渲染的根本原因。直到JS文件解析完毕,这样对用户体验伤害极大。
再说下,当浏览器解析HTML和CSS文件时,会分别构建DOM树和渲染树,等到渲染树构建完成后,浏览器开始绘制屏幕,这个过程涉及到两个比较重要的概念:就是reflow(回流)和repain(重绘)。
DOM节点中的各个元素都是以盒模型的形式存在的,盒模型简单理解即:content,padding,border,margin。而每个盒模型都有它的大小和位置,这些都需要浏览器去计算得出,这个计算的过程就是reflow(回流);当盒模型确定下来之后,浏览器就会开始绘制盒模型里面的内容,即content,这个过程就称为repain(重绘)。页面在首次加载时必然会经历这两个过程,而这两个过程是非常消耗性能的,所以我们应该尽可能的减少reflow和repain。
再讲下JS的解析过程:
JS的解析是由浏览器的JS解析引擎完成的,我们都知道,JavScript是单线程运行的。也就是说,一次只能做一件事,所有的事情都必须排队,一个一个的进行,但是当某些事情比较麻烦,会耽搁较多时间的时候,这样就会造成线程阻塞,为了解决这个问题,JavaScript的执行机制引入了同步任务和异步任务,这样,就相当于在Javascript的单线程(也称为执行栈)的旁边加了任务队列(task queue)。同步任务会放在执行栈上去执行,在执行过程中如果遇到了异步代码(如setTimeout,Promise,ajax等),浏览器会将这些代码放到一个幕后线程中去等待,不阻塞主线程的执行,主线程继续走,当幕后线程准备好了,会将它的回调函数放到任务队列中等待执行。当主线程执行完所有代码后,它就会回头检查任务队列是否有任务要执行,如果有就将任务放到执行栈中执行,如果没有,它就会进入循环等待任务到来。这就是事件循环(event loop)。
当任务队列有多个任务,执行顺序问题: 其实js有两个任务队列:
Macrotask Queue:主要是处理宏任务(如seTimeout,setInterval,用户交互操作,UI渲染等) Microtask Queue:主要处理微任务(如Promise,process.nextTick(nodejs)) 执行顺序是先检查两个队列,先从Macrotask队列执行等待最长的任务,然后执行Microtask队列等待最长的,依次循环执行。
浏览器在解析过程中,如果遇到需要请求外部资源时(如图片,JS文件等),浏览器将重复上面的过程,请求过程是异步的,不会影响HTML文档的加载。
有一点忘记说了,就是CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。因为JS代码可能会涉及到对DOM里面元素样式的修改。所以
JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。
最后给兄弟们分享下《图解HTTP》的电子版:链接: pan.baidu.com/s/1SGxQLZbl… 提取码:w0r9