Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端性能优化知识集合 #108

Open
hoperyy opened this issue Apr 25, 2018 · 3 comments
Open

前端性能优化知识集合 #108

hoperyy opened this issue Apr 25, 2018 · 3 comments

Comments

@hoperyy
Copy link
Owner

hoperyy commented Apr 25, 2018

本文思维导图

前 端 性 能 优 化

页面请求过程

参考资料:https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing?hl=zh-cn

  • prepare for unload
  • redirect: 重定向
  • app cache: 查询缓存
  • Queuing: 排队
  • Stalled/Blocking: 请求等待发送所用的时间。 可以是等待 Queueing 中介绍的任何一个原因。 此外,此时间包含代理协商所用的任何时间。
  • Proxy Negotiation: 与代理服务器连接协商所用的时间。
  • DNS Lookup: 执行 DNS 查询所用的时间。 页面上的每一个新域都需要完整的往返才能执行 DNS 查询。
  • Initial Connection / Connecting: 建立连接所用的时间,包括 TCP 握手/重试和协商 SSL 的时间。
  • SSL: 完成 SSL 握手所用的时间。
  • Request Sent / Sending: 发出网络请求所用的时间。 通常不到一毫秒。
  • ServiceWorker Preparation. The browser is starting up the service worker.
  • Request to ServiceWorker. The request is being sent to the service worker.
  • Waiting (TTFB): 等待初始响应所用的时间,也称为至第一字节的时间。 此时间将捕捉到服务器往返的延迟时间,以及等待服务器传送响应所用的时间。
  • Content Download / Downloading: 接收响应数据所用的时间。
  • Processing: 页面处理
  • Receiving Push. The browser is receiving data for this response via HTTP/2 Server Push.
  • Reading Push. The browser is reading the local data previously received.

探测页面性能状态

pagespeed 插件:

https://chrome.google.com/webstore/detail/pagespeed-insights-with-p/lanlbpjbalfkflkhegagflkgcfklnbnh?hl=zh-CN

每个阶段的优化点

prepare for unload

跳过

redirect

  • 资源路径不添加协议
  • 检查资源的重定向情况

app cache

  • 稳定的静态资源路径不变,以利用缓存
  • 预加载资源
  • Cache-Control || Expires
  • Last-Modified || Etag
  • If-Modified-Since If-None-Match

Queuing

  • 排队的时间花费。如果某个请求正在排队,则指示:

    • 请求已被渲染引擎推迟,因为该请求的优先级被视为低于关键资源(例如脚本/样式)的优先级。 图像经常发生这种情况。
    • 请求已被暂停,以等待将要释放的不可用 TCP 套接字。
    • 请求已被暂停,因为在 HTTP 1 上,浏览器仅允许每个源拥有六个 TCP 连接。
    • 生成磁盘缓存条目所用的时间(通常非常迅速)
    • 服务器不可用
  • 优化方法

    • 减少请求数量

      HTTP/1.1 协议下,如 chrome 同域名资源最多 6 个,避免在单个网域检索太多的资源。

      该方案对 HTTP/2 无效,因为 HTTP/2 可以单个 TCP 连接多路复用。

      • 多路复用(spdy / HTTP2)
      • 使用雪碧图
    • 提高资源优先级

Stalled/Blocking

优化方案同 Queuing

DNS Lookup

  • pre-fetch

Request Sent / Sending

  • 减少请求大小
    • 压缩 header 头
    • 去除巨型 cookie

Waiting (TTFB)

首字节返回时间(TTFB)。

  • 该环节耗时较长的主要原因:

    • 客户端与服务器之间的网络条件较差

      要解决长 TTFB,首先请尽可能缩减网络。理想的情况是将应用托管在本地,然后查看 TTFB 是否仍然很长。

    • 服务器应用的响应慢

      需要优化应用的响应速度。可以是优化数据库查询、为特定部分的内容实现缓存,或者修改您的网络服务器配置。

      很多原因都可能导致后端缓慢。

    如果本地托管后 TTFB 仍然漫长,那么问题出在您的客户端与服务器之间的网络上。很多事情都可以阻止网络遍历。客户端与服务器之间有许多点,每个点都有其自己的连接限制并可能引发问题。测试时间是否缩短的最简单方法是将您的应用置于其他主机上,并查看 TTFB 是否有所改善。

  • 优化

    • 使用 cdn

Content Download / Downloading

如果该阶段耗时较长。

  • 减少发送的字节数

    • 使用 webp

      webp 是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。根据 Google 官方的数据,无损压缩后的 webp 比 PNG 文件少了 26% 的文件大小,有损压缩在具有同等 SSIM 索引的情况下 webp 比 jpeg 文件少 25~34% 的文件大小。webp 支持无损透明度(也叫作 alpha 通道),图片大小增加 22%。支持动画格式 Animated WebP。

    • 图片质量

      • 根据网络的不同,可以显示不同质量的商品图片。

      • 图片锐化

      • 不必要的浪费

        合理地使用 CDN 图片尺寸可以带来下载图片的性能提升,还可以减少不必要的内存消耗。举例:

        自然尺寸:110\*110
        显示尺寸:100\*100
        不必要的像素:110\*110 - 100\*100 = 2100
        不必要的内存消耗:2100\*4/1024=8.2kb
        2X: \*4=32.8kb
        3X: \*9=73.8kb

    • 使用 iconfont

      iconfont 对于前端来说有很多优点:自由变化大小、矢量不失真、自由修改颜色、可以添加一些视觉效果如阴影、旋转、透明度、兼容 IE6.

      为了节省流量,在移动端,目前只引用 ttf 一个字体文件,可以考虑 base64 在 css 文件中。

    • 雪碧图注意

      • 解码内存消耗

        内存消耗公式:w * h * 4(宽 * 高 * 每个像素 4 个字节)

        如果设备 DPI 大于 1,还需要乘以 DIP 系数,如 Retina 设备 X4,RetinaHD 设备 X8

      • 禁止生成大图且利用率少

  • range request/response

Processing

  • 页面的处理过程:https://developers.google.com/web/fundamentals/performance/critical-rendering-path/?hl=zh-cn

  • 页面的构建过程。

    • HTML -- Nodes

      一一对应

    • Nodes -- LayoutObjects

      一一对应

    • LayoutObjects 到 PaintLayers

      满足以下条件的 LayoutObjects 会拥有独立的渲染层,而其他的 LayoutObject 则和其第一个拥有渲染层的父元素共用一个。

      • NormalPaintLayer(被认为是 SelfPaintingLayer)
        • 根元素(HTML)
        • 有明确的定位属性(relative、fixed、sticky、absolute)
        • 透明的(opacity 小于 1)
        • 有 css 滤镜(filter)
        • 有 css mask 属性
        • 有 css mix-blend-mode 属性(不为 normal)
        • 有 css transform 属性(不为 none)
        • backface-visibility 属性为 hidden
        • 有 css reflection 属性
        • 有 css column-count 属性(不为 auto)或者有 css column-width 属性(不为 auto)
        • 当前有对于 opacity、transform、filter、backdrop-filter 应用动画
      • OverflowClipPaintLayer
        • overflow 不为 visible
      • NoPaintLayer
        • 不需要 paint 的 PaintLayer,比如一个没有视觉属性(背景、颜色、阴影等)的空 div
    • PaintLayers 到 GraphicLayers(合成层)

      渲染层提升为合成层有一个先决条件,该渲染层必须是 SelfPainingLayer,同时满足以下条件的会被提升为合成层:

      • 直接原因

        • 硬件加速的 iframe 元素(比如 iframe 嵌入的页面中有合成层)
        • html5 video 元素
        • 覆盖在 video 元素上的视频控制栏
        • 3D 或者硬件加速的 2D canvas 元素
        • 硬件加速的插件,比如 flash 等
        • 在 DPI 较高的屏幕上,fix 定位的元素会自动地被提升到合成层中。但在 DPI 较低的设备上并非如此,因为这个渲染层的提升会使得字体渲染方式变为灰阶。
        • 有 3D transform
        • backface-visibility 为 hidden
        • 对 opacity、transform、filter、backdropfilter 应用了 animation 或者 transition(需要是 active 的 animation 或者 transition。当 animation 或 transition 效果未开始或结束后,提升合成层也会失效)
        • will-change 设置为 opacity、transform、top、left、bottom、right(其中 top、left 等需要设置明确的定位属性,如 relative 等)
      • 后代原因

        • 有合成层后代同时本身有 transform、opacity(小于 1)、mask、filter、relfelction 属性
        • 有合成层后代同时本身 overflow 不为 visible
        • 有合成层后代同时本身 fixed 定位
        • 有 3D transform 的合成层后代同时本身有 preserve-3d 属性
        • 有 3D transform 的合成层后代同时本身有 perspective 属性
      • overlap 重叠原因

    • 层压缩

      由于重叠的原因,可能随便就能产生大量的合成层,而每个合成层要消耗 CPU 和内存。浏览器考虑到了,于是有了层压缩。但不是万能的,有很多情况下,浏览器是无法进行层压缩的。这些也是我们应该避免的。

    • 提升为合成层有以下好处:

      • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快。

      • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他层。

      • 对于 transform 和 opacity 效果,不会触发 layout 和 paint。

      • 对于 fixed 的合成层,移动时不会触发 repaint。

  • js / css 加载和执行

    • 参考资料:

    • 需要关注四个因素:DOM / CSSOM/ JS / 渲染

      • CSS 默认阻塞渲染
      • JS 默认阻塞渲染,因为由于浏览器不了解脚本计划在页面上执行什么操作,它会作最坏的假设并阻止解析器
    • 资源并行加载、串行执行

    • 关于加载顺序的基本理解

      • js 有可能会修改DOM;
      • js 的执行有可能依赖最新样式;
      • 现代浏览器有并行加载和 prefetch 的优化
      • 如果浏览器尚未完成 CSSOM 的下载和构建,而我们却想在此时运行脚本,会怎样?答案很简单,对性能不利:浏览器将延迟 JS 执行和 DOM 构建,直至其完成 CSSOM 的下载和构建。
    • CSS

      • 默认情况下,CSS 被视为阻塞渲染的资源。
      • 我们可以通过媒体类型和媒体查询将一些 CSS 资源标记为不阻塞渲染。
      • 浏览器会下载所有 CSS 资源,无论阻塞还是不阻塞。
      • css 会阻塞 js 的执行,因此 css 必须放在 js 脚本之前或内联
    • JS

      • JavaScript 可以查询和修改 DOM 与 CSSOM。

      • JavaScript 执行会阻止 CSSOM。

      • 除非将 JavaScript 显式声明为异步,否则它会阻止构建 DOM。

      • 无论我们使用 <script> 标记还是内联 JavaScript 代码段,您都可以期待两者能够以相同方式工作。 在两种情况下,浏览器都会先暂停并执行脚本,然后才会处理剩余文档。不过,如果是外部 JavaScript 文件,浏览器必须停下来,等待从磁盘、缓存或远程服务器获取脚本,这就可能给关键渲染路径增加数十至数千毫秒的延迟。

        默认情况下,所有 JavaScript 都会阻止解析器。由于浏览器不了解脚本计划在页面上执行什么操作,它会作最坏的假设并阻止解析器。向浏览器传递脚本不需要在引用位置执行的信号既可以让浏览器继续构建 DOM,也能够让脚本在就绪后执行;例如,在从缓存或远程服务器获取文件后执行。

        为此,我们可以将脚本标记为_异步_: async

      • 如果浏览器尚未完成 CSSOM 的下载和构建,而我们却想在此时运行脚本,会怎样?答案很简单,对性能不利:浏览器将延迟脚本执行和 DOM 构建,直至其完成 CSSOM 的下载和构建。

      • 动态加载的 js 的执行是不会受到 htm l后面外联的 js 的阻塞的影响,即是说,它的执行和后面 js 的执行顺序是不确定的

      • domContentLoaded 事件除了包含 DOM,还包括 script 标签,且包括 script 的执行时间

  • cpu 负责 Layout,gpu 负责 Paint

  • 60 fps 和 设备刷新率

    如今大部分设备的屏幕刷新率都是 60 次/秒。因此,如果在页面中有一个动画或渐变效果,或者用户正在滑动页面,那么浏览器渲染动画或页面的每一帧的速率,也需要和设备屏幕的刷新率保持一致。

    也就是说,浏览器对每一帧画面的渲染工作需要在 16 毫秒内完成。但实际上,在渲染某一帧画面的同事,浏览器还有一些额外的工作要做(比如渲染队列的管理,渲染线程与其他线程之间的切换等等)。因此单纯的渲染工作一般需要控制在 10 毫秒之内完成,才能达到流畅的视觉效果。如果超过了这个时间限度,页面的渲染就会出现卡顿,也就是常说的 jank。

  • webp 与 base64

    • webp 解码是由 GPU 完成,会增加解码开销,但没有太大影响,应该优先使用
    • DataUrl 解码是在主进程进行的。 会大幅增加图片解码的开销,增加对 CPU 和 内存的开销,甚至阻塞浏览器的主进程,造成卡顿,只有图片的体积足够小,而且是静态的,不值得消耗一个请求的时候,才应该使用 DataUrl。
  • 图片大小对内存的影响

    • 加载、显示、隐藏、移除
    • 真正耗费内存的是图片的解析过程
    • 隐藏图片节点可以减少内存消耗,但作用不大
    • 移除图片节点不会直接减少内存消耗
    • 图片显示尺寸直接影响内存,显示越大占用内存越多。
    • 同一个页面中完全相同的图片会共享内存。
  • Script - Style - Layout - Paint - Composite

    • 几种情况

      • JavaScript -- Style -- Layout -- Paint -- Composite

      • JavaScript -- Style -- (Layout) -- Paint -- Composite

        如果修改了一个 DOM 元素的 paint only 属性,比如背景图片、文字颜色或阴影等,这些属性不会影响页面的布局,因此浏览器会在完成样式计算之后,跳过布局过程,只做绘制渲染层合并过程。

      • JavaScript -- Style -- (Layout -- Paint) -- Composite

        如果修改一个非样式且非绘制的 css 属性,那么浏览器会在完成样式计算后,跳过布局和绘制的过程,直接做渲染层合并,

        这种方式在性能上是最理想的,对于动画和滚动这种负荷很重的渲染,我们要争取使用这种渲染流程。

    • 优化

      • Script 优化

        错误的执行时机和太长的时间消耗,是常见的导致 js 性能低下的原因。尽量从这两方面对 js 代码带来的执行性能的影响入手。

        • 减少错误的执行时机

          • 实现动画效果,避免使用 setTimeoutsetInterval,请使用 requestAnimationFrame
          • 把 DOM 元素的更新划分为多个小任务,分别在多个 frame 中去完成
          • 消除阻塞渲染的 JavaScript 和 CSS
        • 减少时间消耗

          • 用原生 js 书写首屏代码
          • 监控类代码放到页面底部,不要阻塞页面渲染
          • 降低代码复杂度或把耗时长的 js 代码放到 Web Workers 去做
      • Style 优化

        • 将 CSS 置于文档 head 标签内

          尽早在 HTML 文档内指定所有 CSS 资源,以便浏览器尽早发现 标记并尽早发出 CSS 请求。

        • 避免使用 CSS import

          一个样式表可以使用 CSS import (@import) 指令从另一样式表文件导入规则。不过,应避免使用这些指令,因为它们会在关键路径中增加往返次数:只有在收到并解析完带有 @import 规则的 CSS 样式表之后,才会发现导入的 CSS 资源。

        • 内联阻塞渲染的 CSS

          为获得最佳性能,您可能会考虑将关键 CSS 直接内联到 HTML 文档内。这样做不会增加关键路径中的往返次数,并且如果实现得当,在只有 HTML 是阻塞渲染的资源时,可实现“一次往返”关键路径长度。

        • 降低样式选择器的复杂度

        • 使用基于 class 的方式,比如 BEM

        • 减少需要执行样式计算的元素个数

        • 通过 class 或 cssText 的方式批量修改样式

      • Layout 优化

        • 触发条件

          • DOM 元素的“几何属性”的修改

            比如 width/height/left/top 等,都需要重新计算布局

          • 读取样式属性,强制同步布局

            如果在读取样式属性之前,修改了容器的样式,那么会强制触发重绘。

        • 优化方案

          • DOM

            • 减少需要 Layout 的 DOM 元素数量
            • 使用 fragment 操作 DOM
            • 没用的元素而设置为不可见 visibility: hidden
            • 减少 DOM 的深度
          • 布局

            • 使用 flexbox 替代老的布局模型

              flexbox 的性能更高

            • 图片在渲染前指定大小:因为 img 元素是内联元素,所以在加载图片后会改变宽高,严重的情况会导致整个页面重排,所以最好在渲染前就指定其大小,或者让其脱离文档流

            • 避免强制同步布局事件的发生

              我们可以强制浏览器在执行 js 脚本之前先执行布局过程,这就是所谓的强制同步布局。

              在 js 运行的时候,它能获取到的元素样式属性值都是上一帧画面的,都是旧值。

              如果在读取 height 属性之前,修改了容器的样式,那么会强制触发重绘。

              box.classList.addClass('big');
              console.log(box.offsetHeight);

              为了避免触发不必要的布局过程,应该首先批量读取元素样式属性(浏览器将直接返回上一帧的样式属性值),然后再对样式属性进行写操作。

              console.log(box.offsetHeight);
              box.classList.addClass('big');
            • 避免快速连续的布局

              这种情况更糟糕,看代码:

              for(var i = 0; i < sub.length; i++) {
                  sub[i].style.width = box.offsetWidth + 'px';
              }

              在下一次循环中读取 box 的属性值时,浏览器必须先使上一次循环中的样式更新操作生效,也就是执行布局过程,然后才能响应本次循环中的样式读取操作,也就意味着,布局过程将在每次循环中发生。

              优化:

              var width = box.offsetWidth;
              for(var i = 0; i < sub.length; i++) {
                  sub[i].style.width = width + 'px';
              }
      • Paint

        Paint(绘制)其实是生成元素呈现的像素的过程。例如,一个有着灰色背景、有文字的元素,当浏览器 Paint 时,是决定哪些像素填充背景、哪些像素填充文字,然后浏览器将这些像素存入位图(Bitmap)中。

        Paint 是代价最高的一步,因此尽量减少 Paint 的时间,甚至避免 Paint 的发生,对页面性能的提升有很重要的作用。

        • 如何触发

          • 触发 Layout。如几何属性的修改。
          • 改变非几何属性,如:背景、颜色、阴影等,不会触发 Layout,但会触发 Paint。(csstriggers.com)
        • 如何优化

          提升元素渲染层为合成层。

          需要注意的是,用 transformopacity 时,如果元素被提升到了独立的合成层,不会触发 Paint;但如果没有提升,还是会触发。

      • Composite

        由于重叠的原因,可能随便就能产生大量的合成层,而每个合成层要消耗 CPU 和内存。浏览器考虑到了,于是有了层压缩。但不是万能的,有很多情况下,浏览器是无法进行层压缩的。这些也是我们应该避免的。

        提升为合成层有以下好处:

        • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快。

        • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他层。

        • 对于 transform 和 opacity 效果,不会触发 layout 和 paint。

        • 对于 fixed 的合成层,移动时不会触发 repaint。

        对页面中可能发生大量重排重绘的元素单独触发渲染层,使用 GPU 分担 CPU 压力。但也是对 GPU 有压力的,通常情况下,我们会对动画元素采取硬件加速。

        • 用合成层做动画

          优先:will-change

          其次:transform:translateZ(0);

          用 transform 或 opacity 实现动画

          他们仅触发 composite。前提是元素提升为 合成层。

        • 减少绘制区域

        • 防止层爆炸

          解决方案是打破 overlap 的条件,也就是让其他元素不要和合成层元素层叠。

          z-index

感知性能

  • 使用骨架屏

  • 白屏感知

  • 页面可见时间

  • 重要内容可见时间

  • 白屏时间和补救方法

    尽量同步输出,mock,placeholder

  • 内存

  • chrash

其他

  • 关于页面加载过程中的各个事件

    参考资料:https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp?hl=zh-cn

    • domLoading: 这是整个过程的起始时间戳,浏览器即将开始解析第一批收到的 HTML 文档字节
    • domInteractive: 表示浏览器完成对所有 HTML 的解析并且 DOM 构建完成的时间点。
    • domContentLoaded: 一般表示 DOM 和 CSSOM 均准备就绪,且没有 阻塞解析的 js 的时间点
    • domComplete: 顾名思义,所有处理完成,并且网页上的所有资源(图像等)都已下载完毕,也就是说,加载转环已停止旋转
    • loadEvent: 作为每个网页加载的最后一步,浏览器会触发 onload 事件,以便触发额外的应用逻辑
  • httpDNS

    • httpDNS 是什么

      httpDNS 是面向无线端的域名解析服务,与传统的走 UDP 协议的 DNS 不同,httpDNS 基于 HTTP 协议。

      PC 端的服务一般通过浏览器访问,对于域名解析,浏览器只会走标准 DNS,我们没法干预。无线端的可操作空间比较大,APP 可以自己构造并发送 HTTP 请求,所以能够做到精细化的控制,其中就包括域名解析。

      使用 httpDNS 解析域名的基本流程如下:

      1、客户端向 httpDNS 服务端发送普通的 HTTP 请求,请求中携带需要解析的域名。

      2、httpDNS 服务端解析出域名对应的 ip 地址,将解析结果封装为 JSON 格式,返回给客户端。

      和传统 DNS 一样,httpDNS 的解析结果中包含 TTL,客户端可以根据 TTL 将结果缓存一段时间。

    • httpDNS 的优势

      • 防止域名劫持

        传统 DNS 由 Local DNS 解析域名,不同运营商的 Local DNS 由不同的策略,某些 Local DNS 可能会劫持特定的域名,

        采用 httpDNS 可以绕过 Local DNS,避免被劫持;

        另外,httpDNS 的解析结果包含 HMAC 校验,也能够防止解析结果被中间网络设备篡改。

      • 更精准的调度

        对域名解析而言,尤其是 CDN 域名,解析得到的 IP 应该更靠近客户端的地区和运营商,这样才能有更快的网络访问速度。然而,由于运营商策略的多样性,其推送的 Local DNS 可能和客户端不在同一个地区,这时得到的解析结果可能不是最优的。httpDNS 能够得到客户端的出口网关 IP,从而能够更精确地判断客户端的地区和运营商,得到更精准的解析结果。

      • 更小的解析延迟和波动

        在 2G/3G 这种移动网络下,DNS 解析的延迟和波动都比较大。就单次解析请求而言,httpDNS 不会比传统的 DNS 更快,但通过 httpDNS 客户端 SDK 的配合,总体而言,能够显著降低解析延迟和波动。httpDNS 客户端 SDK 有几个特性:预解析、多域名解析、TTL 缓存和异步请求。

      • 额外的域名相关信息

        传统 DNS 的解析结果只有 ip,httpDNS 的解析结果采用 JSON 格式,除了 ip 外,还支持其他域名相关的信息,比如端口、spdy 协议等。利用这些额外的信息,APP 可以启用或停止某个功能,甚至利用 httpDNS 来做灰度发布,通过 httpDNS 控制灰度的比例。

    • httpDNS 如何解析一个域名

      httpDNS 服务端并没有“域名和 ip 对应关系”的数据库,它做了一次协议转换,从 HTTP 转换为 DNS,将域名解析请求转发给后端 DNS。

      请求过程是这样的:客户端--(HTTP)-- httpDNS 服务器 --(DNS)-- DNS服务器

      后端 DNS 服务器需要拿到客户端的来源 ip,如何透传 httpDNS 服务器呢?httpDNS 使用了 Google 提出的 DNS 扩展选项 edns-client-subnet,通过该选项,可以将客户端 ip 放在 DNS 报文中传给后端 DNS,只要后端 DNS 支持该选项,它就会从 DNS 报文中提取客户端 ip。 httpDNS 对接的后端 DNS 都支持 edns-client-sub 选项。

      具体而言,httpDNS 服务端的处理过程如下:

      1、接收客户端发来的 HTTP 请求,请求中携带域名列表。

      2、解析请求的内容,检查安全校验值,执行白名单过滤,得到待解析的域名列表。

      3、针对域名列表中的每一个域名,构造 DNS 请求报文,发往对应的后端 DNS。

      4、等待并收集 DNS 响应报文,解析报文得到 IP 地址,最后,每个域名都有了解析结果或已经超时。

      5、对每个域名,将解析得到的 IP,以及在 httpDNS 上配置的其他信息,添加到 JSON 报文中。

      6、根据 JSON 报文计算 HMAC 校验值,将校验值和 JSON 报文发给客户端。

参考资料

@hoperyy hoperyy closed this as completed Apr 29, 2018
@hoperyy hoperyy reopened this May 29, 2018
@hoperyy hoperyy closed this as completed May 29, 2018
@hoperyy hoperyy reopened this May 29, 2018
@hoperyy
Copy link
Owner Author

hoperyy commented Sep 5, 2018

image

@hoperyy hoperyy changed the title 前端性能优化 前端性能优化知识杂糅 Oct 27, 2018
@hoperyy hoperyy changed the title 前端性能优化知识杂糅 前端性能优化知识集合 Dec 16, 2018
@everglow1
Copy link

666

1 similar comment
@jin5354
Copy link

jin5354 commented Apr 9, 2019

666

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants