从输入URL到页面加载的过程?
- 从浏览器接收url到开启网络请求线程(这一部分可以展开浏览器的机制以及进程与线程之间的关系)
浏览器是多进程的,有一个主控进程,以及每一个tab页面都会新开一个进程(某些情况下多个tab会合并进程)Browser进程:浏览器的主进程(负责协调、主控),只有一个,浏览器渲染进程(内核):默认每个Tab页面一个进程,互不影响,控制页面渲染,脚本执行,事件处理等(有时候会优化,如多个空白tab会合并成一个进程)
多线程的浏览器内核: GUI线程 JS引擎线程 事件触发线程 定时器线程 网络请求线程
解析URL: protocol host port path query fragment
开启网络线程到发出一个完整的http请求(这一部分涉及到dns查询,tcp/ip请求,五层因特网协议栈等知识)
dns查询: 如果浏览器有缓存,直接使用浏览器缓存,否则使用本机缓存,再没有的话就是用host, 如果本地没有,就向dns域名服务器查询(当然,中间可能还会经过路由,也有缓存等),查询到对应的IP. 需要知道dns解析是很耗时的,因此如果解析域名过多,会让首屏加载变得过慢,可以考虑 dns-prefetch优化。
tcp/ip请求构建: http的本质就是 tcp/ip请求 , 三次握手 四次挥手(因为是全双工的,所以需要四次挥手). get和post本质都是tcp/ip, get会产生一个tcp数据包,post两个。
五层因特网协议栈: 应用层(dns,http) DNS解析成IP并发送http请求 传输层(tcp,udp) 建立tcp连接(三次握手) 网络层(IP,ARP) IP寻址 数据链路层(PPP) 封装成帧 物理层(利用物理介质传输比特流)物理传输(然后传输的时候通过双绞线,电磁波等各种介质)从服务器接收到请求到对应后台接收到请求(这一部分可能涉及到负载均衡,安全拦截以及后台内部的处理等等)
简单的说:用户发起的请求都指向调度服务器(反向代理服务器,譬如安装了nginx控制负载均衡),然后调度服务器根据实际的调度算法,分配不同的请求给对应集群中的服务器执行,然后调度器等待实际服务器的HTTP响应,并将它反馈给用户。
后台的处理: 一般有的后端是有统一的验证的,如安全拦截,跨域验证 , 如果这一步不符合规则,就直接返回了相应的http报文(如拒绝请求等), 然后当验证通过后,才会进入实际的后台代码,此时是程序接收到请求,然后执行(譬如查询数据库,大量计算等等) ,等程序执行完毕后,就会返回一个http响应包(一般这一步也会经过多层封装), 然后就是将这个包从后端发送到前端,完成交互后台和前台的http交互(这一部分包括http头部、响应码、报文结构、cookie等知识,可以提下静态资源的cookie优化,以及编码解码,如gzip压缩等)
通用头部: 请求的web服务器地址 请求方式 请求的返回状态码 请求的远程服务器地址
200——表明该请求被成功地完成,所请求的资源发送回客户端
304——自从上次请求后,请求的网页未修改过,请客户端使用本地缓存
400——客户端请求有错(譬如可以是安全模块拦截)
401——请求未经授权
403——禁止访问(譬如可以是未登录时禁止)
404——资源未找到
500——服务器内部错误
503——服务不可用
1xx——指示信息,表示请求已接收,继续处理 2xx——成功,表示请求已被成功接收、理解、接受 3xx——重定向,要完成请求必须进行更进一步的操作 4xx——客户端错误,请求有语法错误或请求无法实现 5xx——服务器端错误,服务器未能实现合法的请求
请求头部: Host请求的服务器URL 接收类型(对标服务端返回的Content-Type) Cookie Connection(如keep-alive) User-Agent
响应头部:服务器端允许的请求Headers 请求方法 Origin头部 Content-Type Max-age Cache-Control Keep-Alive Server
请求/响应体
cookie以及优化: 浏览器本地就有这个cookie了,以后访问同域名下的页面时,自动带上cookie,自动检验,在有效时间内无需二次登陆。 cookie中设置 httponly(这样就无法通过js操作了) 优化: 将静态资源分组,分别放到不同的子域名下,而子域名请求时,是不会带上父级域名的cookie的,所以就避免了浪费
http1.1起,默认使用长连接,使用长连接会有这一行 Connection:keep-alive 注意: keep-alive不会永远保持,它有一个持续时间,一般在服务器中配置(如apache),另外长连接需要客户端和服务器都支持时才有效。
简述下http2.0的一些特性:多路复用(即一个tcp/ip连接可以请求多个资源) 首部压缩 二进制分帧 服务器端推送 请求优先级单独拎出来的缓存问题,http的缓存(这部分包括http缓存头部,etag,catch-control等)
两种类型: 强缓存( 200fromcache)与 协商缓存( 304)
E-tag相比Last-Modified?
Last-Modified:表明服务端的文件最后何时改变的 它有一个缺陷就是只能精确到1s, 然后还有一个问题就是有的服务端的文件会周期性的改变,导致缓存失效
E-tag:是一种指纹机制,代表文件相关指纹 只有文件变才会变,也只要文件变就会变, 也没有精确时间的限制,只要文件一变,立马E-tag就不一样了浏览器接收到http数据包后的解析流程(解析html-词法分析然后解析成dom树、解析css生成css规则树、合并成render树,然后layout、painting渲染、复合图层的合成、GPU绘制、外链资源的处理、loaded和domcontentloaded等)
渲染步骤大致可以分为以下几步:
解析HTML,构建DOM树 解析CSS,生成CSS规则树 合并DOM树和CSS规则,生成render树
布局render树(Layout/reflow),负责各元素尺寸、位置的计算 绘制render树(paint),绘制页面像素信息
浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上 回流、重绘(offset(Top/Left/Width/Height) scroll(Top/Left/Width/Height) cilent(Top/Left/Width/Height) width,height 调用了getComputedStyle()或者IE的currentStyle)
domcontentloaded:事件触发时,仅当DOM加载完成
loaded:事件触发时,页面上所有的DOM,样式表,脚本,图片都已经加载完成了CSS的可视化格式模型(元素的渲染规则,如包含块,控制框,BFC,IFC等概念)
如何触发BFC? 元素 float属性不为none position为absolute或fixed display为inline-block,flex,inline-flex,table,table-cell,table-caption overflow不为 visible
display:table 它本身不产生BFC,但是它会产生匿名框(包含 display:table-cell的框),而这个匿名框产生BFC。JS引擎解析过程(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)
JS引擎的处理过程可以简述如下:词法分析 => 词元 语法分析 => 语法树 翻译器=> 将代码转为字节码 字节码解释器 => 机器码 最终计算机执行的就是机器码
即时编译: 核心的 JIT编译器将源码编译成机器码运行
GC时,停止响应其他操作, 避免GC造成的长时间停止响应。 分代回收: 多回收“临时对象”区 少回收“持久对象”区 减少每次需遍历的对象,从而减少每次GC的耗时其它(可以拓展不同的知识模块,如跨域,web安全,hybrid模式等等内容)