问题: 从浏览器地址栏输入url到请求返回发生了什么

浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址

url为啥要解析,dns查询规则是什么?

因为网络标准规定了URL只能是字母和数字,还有一些其它特殊符号,而且如果不转义会出现歧义

那url编码的规则是什么呢?

utf-8

然后怎么保证utf-8的编码?

可以用 encodeURIComponent

encodeURIComponent 比 encodeURI有什么区别?
encodeURIComponent 编码范围更广,适合给参数编码,encodeURI 适合给 URL 本身(locaion.origin)编码,当然项目里一般都是用 qs 库去处理

然后说说dns解析流程,并且html如何做dns优化?

  1. 浏览器中输入网址域名,操作系统会先查 hosts 件是否有记录,有的话就会把相对应映射的 IP 返回。
  2. hosts 文件没有就去查本地 dns 解析器有没有缓存。
  3. 然后就去找我们计算机上配置的 dns 服务器上有或者有缓存,就返回
  4. 还没有的话就去找根 DNS 服务器(全球 13 台,固定 ip 地址),然后判断 .com 域名是哪个服务器管理,如果无法解析,就查找网址服务器是否能解析,直到查到网站的 IP 地址

    注意:dns 查询有两种模式,一种是转发模式,一种是非转发模式,我上面说的 4 是非转发模式。

    前端可以做 dns 优化吗?

    前端的dns优化,可以在html页面头部写入dns缓存地址,比如
    1
    2
    <meta http-equiv="x-dns-prefetch-control" content="on" />
    <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
    查找到 IP 之后,就是 http 协议的三次握手(以及后面会涉及到四次挥手)

    三次握手,为啥两次不行,顺便说一下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吗,什么时候会触发?

强缓存会触发,这两种,具体什么行为不知道,大概内容如下:

  1. 先查找内存,如果内存中存在,从内存中加载;
  2. 如果内存中未查找到,选择硬盘获取,如果硬盘中有,从硬盘中加载;
  3. 如果硬盘中未查找到,那就进行网络请求;
  4. 加载到的资源缓存到硬盘和内存;

    什么是启发式缓存吗,在什么条件下触发?

    如果响应中未显示 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