浅谈从在浏览器输入URL到前端性能优化

文章目录

  • 一、前言:从浏览器中输入URL到页面加载的发生了什么
  • 二、性能优化
      • 1、DNS解析优化
          • 1-1、DNS缓存
          • 1-2、 DNS预解析
      • 2、减少HTTP请求与连接时间
          • 2-1、TCP 连接优化
            • 1)TCP 长连接:
            • 2)采用 HTTP/2
          • 2-2、HTTP 请求优化
            • 1)减少http请求次数
            • 2)单次请求所花的时间
          • 2-3、缓存
      • 3、浏览器渲染优化
          • 2-1、js执行优化
          • 2-2、css样式渲染优化
          • 2-3、布局优化
          • 2-4、绘制优化
          • 2-5、合成优化(composite)
      • 参考文章

一、前言:从浏览器中输入URL到页面加载的发生了什么

面试或笔试的时候经常会被问到“:
在浏览器中输入URL到整个页面显示在用户面前时这个过程中到底发生了什么?”、“从浏览器中输入URL到页面加载的发生了什么?“。当你认真回答完这个问题后,面试官可能会再问“在代码层面如何在浏览器绘制前减少重绘重排(回流)?”

总的来说,从地址栏输入url按下回车到页面完全展示,大致经历以下几个步骤:

  1. DNS解析
  2. 建立HTTP连接
  3. 发送HTTP请求获取对应的资源(html/js/css)
  4. 服务器处理HTTP请求并返回HTTP报文
  5. 浏览器解析并render页面
  6. 关闭http请求

在谈web性能优化前,来看一张图“延迟与用户反应”。浅谈从在浏览器输入URL到前端性能优化_第1张图片
不难看出,页面响应超过1-10s用户可能就关闭放弃页面。为了更将信息快速响应给用户提供友好交互,留住用户,需要将信息再尽短的时间内反馈给用户。
如何尽快的加载资源?答案就是能不从网络中加载的资源就不从网络中加载,当我们合理使用缓存,将资源放在浏览器端,这是最快的方式。如果资源必须从网络中加载,则要考虑缩短连接时间,即DNS优化部分;减少响应内容大小,即对内容进行压缩。另一方面,如果加载的资源数比较少的话,也可以快速的响应用户。当资源到达浏览器之后,浏览器开始进行解析渲染,浏览器中最耗时的部分就是reflow。所以接下来从以上几个阶段开始。

二、性能优化

1、DNS解析优化

DNS解析过程:
DNS查询顺序:浏览器缓存→系统缓存→路由器缓存→ISP DNS 缓存→递归搜索

了解DNS解析过程,能为我们带来什么呢?可以得出,要更快解析到服务器IP,一要不减少解析步骤(DNS缓存),二要不就是提前解析(DNS预解析)

1-1、DNS缓存

只要有DNS解析的地方就有dns缓存,默认浏览器会缓存访问过域名的ip地址

1-2、 DNS预解析





2、减少HTTP请求与连接时间

2-1、TCP 连接优化
1)TCP 长连接:

服务器在完成 HTTP 请求之后不断开 TCP 连接而是挂起,后续有 HTTP 请求可以直接在这个 TCP 连接上发送;缺点是保持长连接会消耗服务端的资源。

2)采用 HTTP/2

HTTP/2 多路复用的特性允许多个 HTTP 请求在同一个 TCP 连接上发送,可以节省多次建立 TCP 连接的时间。

2-2、HTTP 请求优化

http优化主要减少http请求次数、单次请求所花的时间

1)减少http请求次数
  • 1)静态资源合并:
    对于 JS 和 CSS 文件,可以在构建阶段通过构建工具将 JS 和 CSS 文件打包成一到两个文件。(有启用 HTTP/2 的话,该方法不是很有必要)
  • 2)图片:
    雪碧图:雪碧图牵一发而动全身,一个图片修改了,整个图片都要重新生成,不利于缓存。
    base64 化:增大了文件体积(变为原来的 4/3),且增大了 CSS 的体积,阻碍了页面的渲染
2)单次请求所花的时间

减少文件体积是减少单次请求所花时间的主要手段。
优化方法主要有:

  • 1)压缩

构建阶段压缩:通过删除多余空格和空行以及变量名替换(用字符较少的变量名替换字符较多的变量名)减少文件的字符数量。

HTTP 压缩(内容编码):对 HTTP 所传的内容重新编码,缩小文件的体积,例如 Gzip 压缩。

  • 2)拆分资源

将文件按 url 路径(或者采用更小粒度)进行拆分,优先加载关键渲染路径所依赖的文件,其他文件在需要的时候再异步请求,以 Vue 项目为例

// 异步组件,会按需加载
const SearchToast = () => ({
    component: import('component/search-toast.vue'),
});
2-3、缓存

缓存可以减少网络 IO 消耗,提高页面访问速度

  • 1)HTTP缓存:
    分为强缓存(200)、协商缓存(304/E-tag)
  • 2)Service Worker 缓存
    借助 Service Worker 可以实现离线缓存。(www.taobao.com mail.google.com/)
  • 3)IndexDB缓存
    :H5离线应用
  • 4)manifest应用缓存
    断网依旧可以访问域名 链接
    已应用网站:https://www.zybuluo.com

3、浏览器渲染优化

浏览器渲染流程:JS执行 => CSS 样式渲染 => 布局 => 绘制 => 合成
在这里插入图片描述

2-1、js执行优化
  • 1)对于动画效果的实现,避免使用 setTimeout 或 setInterval,使用 requestAnimationFrame

  • 2)如果不需要访问 DOM,可以将长时间运行的 Javascript 工作从主线程移动 worker 线程

  • 3)如果必须在主线程上执行大型任务,可以将大型任务分割为多个微任务,每个微任务所占时间不超过几毫秒

2-2、css样式渲染优化

降低选择器的复杂性,使用以类为中心的方法,比如 BEM:

// 渲染性能比较好的方式
.final-box-title {
  /* styles */
}
 
// 渲染性能比较差的方式
.box:nth-last-child(-n+1) .title p {
  /* styles */
}
2-3、布局优化

布局是浏览器计算各元素的几何信息的过程,包括元素的大小和在页面中的位置。

1)尽可能避免布局操作

几何属性(高度、宽度、位置等)的更改都会引发布局计算,而布局几乎总是作用到整个文档,所以会耗费大量性能。

2)使用 flexbox 布局模型

flexbox 布局模型的性能更好。

2-4、绘制优化

绘制是浏览器填充像素的过程。绘制通常是渲染过程中性能开销最大的部分,应该尽可能避免绘制。

将元素提升为合成层:

.moving-element {
  will-change: transform;
  translate3D(120, 0, 0);
}
// 不支持 will-change 的浏览器
.moving-element {
  transform: translateZ(0);
}

will-change应用:滚动视差效果的实现及优化方案

提升为合成层的元素,transform 和 opacity 的改变不会引发绘制,只会引发合成。

但也要注意不要创建太多层,因为每层都需要内存和管理开销。

减少绘制的区域 减少绘制区域往往是编排您的动画和变换,使其不过多重叠,或设法避免对页面的某些部分设置动画。

降低绘制的复杂性 在谈到绘制时,一些绘制比其他绘制的开销更大。

2-5、合成优化(composite)

合成是将页面已绘制的部分放在一起在屏幕上显示的过程。
页面中的合成层数量不宜太多,如果没有必要,还是不要讲元素提升为合成层。

影响页面的性能因素:
1)需要管理的合成器层数量
2)动画属性

坚持使用 transform 和 opacity 属性更改来实现动画
使用 transform 和 opacity 时要注意的是,这些属性所在的元素应处于其自身的合成器层(will-change 提升)。

管理层并避免层数激增 如无必要,请勿提升元素
硬件加速transform、opacity测试例子

参考文章

  • 浏览器的DNS缓存查看和清除
  • 一次dns缓存引起的血案
  • 浅谈前端性能优化(移动端)
  • 深入浅出经典面试题:从浏览器中输入URL到页面加载发生了什么 - Part 1
  • 浏览器渲染原理(性能优化之如何减少重排和重绘)
  • 前端经典面试题: 从输入URL到页面加载发生了什么?
  • CSS性能优化的8个技巧

你可能感兴趣的:(前端)