块的文章网上也是比较多的,但大多数都是讲解DOM树的渲染,对于页面从请求到展示的详细流程讲解还是比较少的,而且有些说的也不容易理解,下面我将以图文结合的形式给大伙讲讲。
作用
DNS 的作用就是通过域名查询到具体的 IP。
背景
因为 IP 存在数字和英文的组合(IPv6),很不利于人类记忆,所以就出现了域名。你可以把域名看成是某个 IP 的别名,DNS 就是去查询这个别名的真正名称是什么。
过程
在 TCP 握手之前就已经进行了 DNS 查询,这个查询是操作系统自己做的。当你在浏览器中想访问 www.test.com 时,会进行一下操作:
以上介绍的是 DNS 迭代查询,还有种是递归查询,区别就是前者是由客户端去做请求,后者是由系统配置的 DNS 服务器做请求,得到结果后将数据返回给客户端。
在进行完DNS解析之后,接下来就是 TCP 握手,应用层会下发数据给传输层,这里 TCP 协议会指明两端的端口号,然后下发给网络层。网络层中的 IP 协议会确定 IP 地址,并且指示了数据传输中如何跳转路由器。然后包会再被封装到数据链路层的数据帧结构中,最后就是物理层面的传输了。
TCP建立连接的三次握手
首先假设主动发起请求的一端称为客户端,被动连接的一端称为服务端。不管是客户端还是服务端,TCP 连接建立完后都能发送和接收数据,所以 TCP 是一个全双工的协议。
起初,两端都为 CLOSED 状态。在通信开始前,双方都会创建 TCB。 服务器创建完 TCB 后便进入 LISTEN 状态,此时开始等待客户端发送数据。
第一次握手
客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。
第二次握手
服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。
第三次握手
当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
第三次握手中可以包含数据,通过快速打开(TFO)技术就可以实现这一功能。其实只要涉及到握手的协议,都可以使用类似 TFO 的方式,客户端和服务端存储相同的 cookie,下次握手时发出 cookie 达到减少 RTT 的目的。
TLS 协议位于传输层之上,应用层之下,主要是对HTTP请求进行加密。首次进行 TLS 协议传输需要两个 RTT ,接下来可以通过 Session Resumption 减少到一个 RTT。
TLS 握手过程如下图:
通过以上步骤可知,在 TLS 握手阶段,两端使用非对称加密的方式来通信,但是因为非对称加密损耗的性能比对称加密大,所以在正式传输数据时,两端使用对称加密的方式通信。
数据在进入服务端之前,可能还会先经过负责负载均衡的服务器,它的作用就是将请求合理的分发到多台服务器上,这时假设服务端会响应一个 HTML 文件。
首先浏览器会判断状态码是什么,如果是 200 那就继续解析,如果 400 或 500 的话就会报错,如果 300 的话会进行重定向,这里会有个重定向计数器,避免过多次的重定向,超过次数也会报错。
浏览器解析
浏览器开始解析文件,如果是 gzip 格式的话会先解压一下,然后通过文件的编码格式去解码文件。
文件解码成功后会正式开始渲染流程,先会根据 HTML 构建 DOM 树,有 CSS 的话会去构建 CSSOM 树。如果遇到 script 标签的话,会判断是否存在 async 或者 defer ,前者会并行进行下载并执行 JS,后者会先下载文件,然后等待 HTML 解析完成后顺序执行。
如果以上都没有,就会阻塞住渲染流程直到 JS 执行完毕。遇到文件下载的会去下载文件,这里如果使用 HTTP/2 协议的话会极大的提高多图的下载效率。
CSSOM 树和 DOM 树构建完成后会开始生成 Render 树,这一步就是确定页面元素的布局、样式等等诸多方面的东西
在生成 Render 树的过程中,浏览器就开始调用 GPU 绘制,合成图层,将内容显示在屏幕上了。
总的来说,今天这篇文章主要是带着大家从 DNS 查询开始到渲染出画面完整的了解一遍过程,里面涉及到DNS、HTTP、TLS、负载均衡和浏览器渲染等等内容,算不上非常详细,但如果面试的时候能说出来这些,相信面试官也会对你刮目相看的。
语义化是指根据内容的结构化(内容语义化),选择合适的标签(代 码语义化)。通俗来讲就是用正确的标签做正确的事情。
语义化的优点如下:
对机器友好,带有语义的文字表现力丰富,更适合搜索引擎的爬虫爬 取有效信息,有利于 SEO。除此之外,语义类还支持读屏软件,根据 文章可以自动生成目录;
对开发者友好,使用语义类标签增强了可读性,结构更加清晰,开发 者能清晰地看出网页的结构,便于团队的开发与维护。
常见的语义化标签:
DOCTYPE 是 HTML5 中一种标准通用标记语言的文档类型声明,它的目 的是告诉浏览器(解析器)应该以什么样(html 或 xhtml)的文档类 行定义来解析文档,不同的渲染模式会影响浏览器对 CSS 代码甚⾄JavaScript 脚本的解析。它必须声明在 HTML⽂档的第⼀⾏。
浏览器渲染页面的两种模式(可通过 document.compatMode 获取,比 如,语雀官网的文档类型是 CSS1Compat):
CSS1Compat:标准模式(Strick mode),默认模式,浏览器使用 W3C 的标准解析渲染页面。在标准模式中,浏览器以其支持的最高标准呈 现页面。
BackCompat:怪异模式(混杂模式)(Quick mode),浏览器使用自己的 怪异模式解析渲染页面。在怪异模式中,页面以一种比较宽松的向后 兼容的方式显示。
如果没有 defer 或 async 属性,浏览器会立即加载并执行相应的脚本。它不会等待后续加载的文档元素,读取到就会开始加载和执行,这样 就阻塞了后续文档的加载。
下图可以直观地看出三者之间的区别:
其中蓝色代表 js 脚本网络加载时间,红色代表 js 脚本执行时间,绿 色代表 html 解析。
defer 和 async 属性都是去异步加载外部的 JS 脚本文件,它们都不 会阻塞页面的解析,其区别如下:
执行顺序:多个带 async 属性的标签,不能保证加载的顺序;多个带 defer 属性的标签,按照加载顺序执行;
脚本是否并行执行:async 属性,表示后续文档的加载和执行与 js 脚本的加载和执行是并行进行的,即异步执行;defer 属性,加载后 续文档的过程和 js 脚本的加载(此时仅加载不执行)是并行进行的(异步),js 脚本需要等到文档所有元素解析完成之后才执行,DOMContentLoaded 事件触发执行之前。
行内元素有:a b span img input select strong;
块级元素有:div ul ol li dl dt dd h1 h2 h3 h4 h5 h6 p;
空元素,即没有内容的 HTML 元素。空元素是在开始标签中关闭的,也就是空元素没有闭合标签:
常见的有:<br>、<hr>、<img>、<input>、<link>、<meta>;
鲜见的有:<area>、<base>、<col>、<colgroup>、<command>、<embed>、<keygen>、<param>、<source>、<track>、<wbr>。
在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问页面 ,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经 访问过页面并且资源已经进行离线存储了,那么浏览器就会使用离线 的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文 件改变了,就会重新下载文件中的资源并进行离线存储。
离线的情况下,浏览器会直接使用离线存储的资源。
(1)SVG:
SVG 可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标 记语言 XML 描述的 2D 图形的语言,SVG 基于 XML 就意味着 SVG DOM 中的每个元素都是可用的,可以为某个元素附加 Javascript 事件处 理器。在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象 的属性发生变化,那么浏览器能够自动重现图形。
其特点如下:
不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)不适合游戏应用
(2)Canvas:
Canvas 是画布,通过 Javascript 来绘制 2D 图形,是逐像素进行渲 染的。其位置发生改变,就会重新进行绘制。
其特点如下:
依赖分辨率
不支持事件处理器
弱的文本渲染能力
能够以 .png 或 .jpg 格式保存结果图像
最适合图像密集型的游戏,其中的许多对象会被频繁重绘
注:矢量图,也称为面向对象的图像或绘图图像,在数学上定义为一 系列由线连接的点。矢量文件中的图形元素称为对象。每个对象都是
一个自成一体的实体,它具有颜色、形状、轮廓、大小和屏幕位置等 属性。
dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发。
darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触 发。
drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
dragend:事件主体是被拖放元素,在整个拖放操作结束时触发。
三部分 附录(因为暂时不支持插入超链接所以部分内容无法显示)
附录一 DIV命名规范
附录二 CSS精灵
a { display:block; width:200px; height:65px; line-height:65px; /*定义状态*/ text-indent:-2015px; /*隐藏文字*/ background-image:url(button.png); /*定义背景图片*/ background-position:0 0; /*定义链接的普通状态,此时图像显示的是顶上的部分*/ } a:hover { background-position:0 -66px; /*定义链接的滑过状态,此时显示的为中间部分,向下取负值*/ } a:active { background-position:0 -132px; /*定 义链接的普通状态,此时显示的是底部的部分,向下取负值*/ }
附录三 一些tips解决方案
页面优化实践
写DIV+CSS 的一些常识
常用代码片段
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td { margin:0; padding:0; } body { background:#fff; color:#555; font-size:14px; font-family: Verdana, Arial, Helvetica, sans-serif; } td, th, caption { font-size:14px; } h1, h2, h3, h4, h5, h6 { font-weight:normal; font-size:100%; } address, caption, cite, code, dfn, em, strong, th, var { font-style:normal; font-weight:normal; } a { color:#555; text-decoration:none; } a:hover { text-decoration:underline; } img { border:none; } ol,ul,li { list-style:none; } input, textarea, select, button { font:14px Verdana,Helvetica,Arial,sans-serif; } table { border-collapse:collapse; } html { overflow-y: scroll; } .clearfix:after { content: "."; display: block; height:0; clear:both; visibility: hidden; } .clearfix { *zoom:1; }
<meta name=”viewport” content=”width=320,target-densitydpi=dpi_value,initial-scale=1, user-scalable=no”/>
table-layout: fixed; word-break: break-all;;border-collapse: collapse
<div id=”abc” style=”display:table;text-align:center;width:100%;height:100%;”> <span style=”background:#f00; display:table-cell; vertical-align:middle;”> <input type=”button” value=”item1″ /> </span> </div>
filter:alpha(opacity=50); /*1-100*/ -moz-opacity:0.5; /*0-1.0*/ -khtml-opacity:0.5; /*0-1.0*/ opacity:0.5; /*0-1.0*/
white-space:nowrap; text-overflow:ellipsis; overflow:hidden;
.fix{zoom:1;} .fix:after{ display:block; content:'clear'; clear:both; line-height:0; visibility:hidden; }
一些总结
一些概念
学习从来不是一个人的事情,要有个相互监督的伙伴,想要学习或交流前端问题的小伙伴可以私信“学习”小明加群获取2019web前端最新入门资料,一起学习,一起成长!
*请认真填写需求信息,我们会在24小时内与您取得联系。