问题: 从浏览器地址栏输入url到请求返回发生了什么
浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址
url为啥要解析,dns查询规则是什么?
因为网络标准规定了URL只能是字母和数字,还有一些其它特殊符号,而且如果不转义会出现歧义
那url编码的规则是什么呢?
utf-8
然后怎么保证utf-8的编码?
可以用 encodeURIComponent
encodeURIComponent 比 encodeURI有什么区别?
encodeURIComponent 编码范围更广,适合给参数编码,encodeURI 适合给 URL 本身(locaion.origin)编码,当然项目里一般都是用 qs 库去处理
然后说说dns解析流程,并且html如何做dns优化?
- 浏览器中输入网址域名,操作系统会先查 hosts 件是否有记录,有的话就会把相对应映射的 IP 返回。
- hosts 文件没有就去查本地 dns 解析器有没有缓存。
- 然后就去找我们计算机上配置的 dns 服务器上有或者有缓存,就返回
- 还没有的话就去找根 DNS 服务器(全球 13 台,固定 ip 地址),然后判断 .com 域名是哪个服务器管理,如果无法解析,就查找网址服务器是否能解析,直到查到网站的 IP 地址
注意:dns 查询有两种模式,一种是转发模式,一种是非转发模式,我上面说的 4 是非转发模式。
前端可以做 dns 优化吗?
前端的dns优化,可以在html页面头部写入dns缓存地址,比如查找到 IP 之后,就是 http 协议的三次握手(以及后面会涉及到四次挥手)1
2<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />三次握手,为啥两次不行,顺便说一下3次握手发生了什么
- 第一次握手:主机 A 发送位码 为SYN=1 的 TCP 包给服务器,并且随机产生一个作为确认号(这是 tcp 包的一部分),主机 B 收到 SYN 码后直到 A 要求建立连接;
- 第二次握手:主机 B 收到请求后,向 A 发送确认号(主机A的seq+1),syn=1,seq = 随机数 的 TCP 包;
- 主机 A 收到后检查确认号是否正确,即第一次 A 发送的确认号是否 +1 了,以及位码 ack 是否为 1,若正确,主机 A 会再发送确认号(主机 B 的 seq+1),ack=1,主机 B 收到后确认 seq 值与 ack=1 则连接建立成功。
三次握手建立链接,就该请求 html 文件了,如果 html 文件在缓存里面浏览器直接返回,如果没有,就去后台取
解释一下缓存
浏览器首次加载资源成功时,服务器返回 200,此时浏览器不仅将资源下载下来,而且把 response 的 header(里面的 date 属性非常重要,用来计算第二次相同资源时当前时间和 date 的时间差)一并缓存;
下一次加载资源时,首先要经过强缓存的处理,cache-control 的优先级最高,比如 cache-control:no-cache,就直接进入到协商缓存的步骤了,如果 cache-control:max-age=xxx,就会先比较当前时间和上一次返回 200时的时间差,如果没有超过 max-age,命中强缓存,不发请求直接从本地缓存读取该文件(这里需要注意,如果没有 cache-control,会取 expires 的值,来对比是否过期),过期的话会进入下一个阶段,协商缓存
协商缓存阶段,则向服务器发送 header 带有 If-None-Match 和 If-Modified-Since 的请求,服务器会比较 Etag,如果相同,命中协商缓存,返回 304;如果不一致则有改动,直接返回新的资源文件带上新的 Etag 值并返回 200;
协商缓存第二个重要的字段是,If-Modified-Since,如果客户端发送的 If-Modified-Since 的值跟服务器端获取的文件最近改动的时间,一致则命中协商缓存,返回 304;不一致则返回新的 last-modified 和文件并返回 200;
什么是from disk cache和from memory cache吗,什么时候会触发?
强缓存会触发,这两种,具体什么行为不知道,大概内容如下:
- 先查找内存,如果内存中存在,从内存中加载;
- 如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载;
- 如果硬盘中未查找到,那就进行网络请求;
- 加载到的资源缓存到硬盘和内存;
什么是启发式缓存吗,在什么条件下触发?
如果响应中未显示 Expires,Cache-Control:max-age或Cache-Control:s-maxage,并且响应中不包含其他有关缓存的限制,缓存可以使用启发式方法计算新鲜度寿命。通常会根据响应头中的2个时间字段 Date 减去 Last-Modified 值的 10% 作为缓存时间。Date 减去 Last-Modified 值的 10% 作为缓存时间。
Date:创建报文的日期时间, Last-Modified 服务器声明文档最后被修改时间 response_is_fresh = max(0,(Date - Last-Modified)) % 10
- 返回 html 之后,会解析 html, cssom + domTree = html,然后布局和绘制
- 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree)
- 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树
- 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件)
- 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree)
- 渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性
- 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置
- 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成
页面渲染层有什么优化手段?
- HTML 文档结构层次尽量少
- 脚本尽量后放,放在前即可
- 少量首屏样式内联放在标签内
- 样式结构层次尽量简单
- 在脚本中尽量减少 DOM 操作,尽量缓存访问 DOM 的样式信息,避免过度触发回流
- 减少通过 JavaScript 代码修改元素样式,尽量使用修改 class 名方式操作样式或动画
- 动画尽量使用在绝对定位或固定定位的元素上
- 隐藏在屏幕外,或在页面滚动时,尽量停止动画
- 尽量缓存 DOM 查找,查找器尽量简洁
- 涉及多域名的网站,可以开启域名预解析;
如何诊断页面渲染时各个性能指标?
通过 chrome 浏览器的工具,比如看网络请求情况的 network,还有看页面渲染情况的 perfermance
zhuanlan.zhihu.com/p/105561186