性能优化

其他内容

  1. 前端题------js
  2. css
  3. vue
  4. react
  5. node
  6. 算法
  7. 浏览器
  8. 网络
  9. 工程化

图片懒加载

juejin.cn/post/727163...

一个大文件上传和断点续传

juejin.cn/post/684490...

路由懒加载

juejin.cn/post/718889...

回流与重绘

1. 回流与重绘的概念及触发条件

(1)回流

当渲染树中部分或者全部元素的尺寸、结构或者属性发生变化时,浏览器会重新渲染部分或者全部文档的过程就称为回流

下面这些操作会导致回流:

  • 页面的首次渲染
  • 浏览器的窗口大小发生变化
  • 元素的内容发生变化
  • 元素的尺寸或者位置发生变化
  • 元素的字体大小发生变化
  • 激活CSS伪类
  • 查询某些属性或者调用某些方法
  • 添加或者删除可见的DOM元素

在触发回流(重排)的时候,由于浏览器渲染页面是基于流式布局的,所以当触发回流时,会导致周围的DOM元素重新排列,它的影响范围有两种:

  • 全局范围:从根节点开始,对整个渲染树进行重新布局
  • 局部范围:对渲染树的某部分或者一个渲染对象进行重新布局

(2)重绘

当页面中某些元素的样式发生变化,但是不会影响其在文档流中的位置时,浏览器就会对元素进行重新绘制,这个过程就是重绘

下面这些操作会导致回流:

  • color、background 相关属性:background-color、background-image 等
  • outline 相关属性:outline-color、outline-width 、text-decoration
  • border-radius、visibility、box-shadow

注意: 当触发回流时,一定会触发重绘,但是重绘不一定会引发回流。

2. 如何避免回流与重绘?

减少回流与重绘的措施:

  • 操作DOM时,尽量在低层级的DOM节点进行操作
  • 不要使用table布局, 一个小的改动可能会使整个table进行重新布局
  • 使用CSS的表达式
  • 不要频繁操作元素的样式,对于静态页面,可以修改类名,而不是样式。
  • 使用absolute或者fixed,使元素脱离文档流,这样他们发生变化就不会影响其他元素
  • 避免频繁操作DOM,可以创建一个文档片段documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中
  • 将元素先设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
  • 将DOM的多个读操作(或者写操作)放在一起,而不是读写操作穿插着写。这得益于浏览器的渲染队列机制

浏览器针对页面的回流与重绘,进行了自身的优化------渲染队列

浏览器会将所有的回流、重绘的操作放在一个队列中,当队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会对队列进行批处理。这样就会让多次的回流、重绘变成一次回流重绘。

上面,将多个读操作(或者写操作)放在一起,就会等所有的读操作进入队列之后执行,这样,原本应该是触发多次回流,变成了只触发一次回流。

3. 如何优化动画?

对于如何优化动画,我们知道,一般情况下,动画需要频繁的操作DOM,就就会导致页面的性能问题,我们可以将动画的position属性设置为absolute或者fixed,将动画脱离文档流,这样他的回流就不会影响到页面了。

4. documentFragment 是什么?用它跟直接操作 DOM 的区别是什么?

MDN中对documentFragment的解释:

DocumentFragment,文档片段接口,一个没有父对象的最小文档对象。它被作为一个轻量版的 Document使用,就像标准的document一样,存储由节点(nodes)组成的文档结构。与document相比,最大的区别是DocumentFragment不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会导致性能等问题。

当我们把一个 DocumentFragment 节点插入文档树时,插入的不是 DocumentFragment 自身,而是它的所有子孙节点。在频繁的DOM操作时,我们就可以将DOM元素插入DocumentFragment,之后一次性的将所有的子孙节点插入文档中。和直接操作DOM相比,将DocumentFragment 节点插入DOM树时,不会触发页面的重绘,这样就大大提高了页面的性能。

节流和防抖

1. 对节流与防抖的理解

  • 函数防抖是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。
  • 函数节流是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。

防抖函数的应用场景:

  • 按钮提交场景:防⽌多次提交按钮,只执⾏最后提交的⼀次
  • 服务端验证场景:表单验证需要服务端配合,只执⾏⼀段连续的输⼊事件的最后⼀次,还有搜索联想词功能类似⽣存环境请⽤lodash.debounce

节流函数的适⽤场景:

  • 拖拽场景:固定时间内只执⾏⼀次,防⽌超⾼频次触发位置变动
  • 缩放场景:监控浏览器resize
  • 动画场景:避免短时间内多次触发动画引起性能问题

2. 实现节流函数和防抖函数

函数防抖的实现:

ini 复制代码
javascript
复制代码
function debounce(fn, wait) {
  var timer = null;

  return function() {
    var context = this,
      args = [...arguments];

    // 如果此时存在定时器的话,则取消之前的定时器重新记时
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    // 设置定时器,使事件间隔指定事件后执行
    timer = setTimeout(() => {
      fn.apply(context, args);
    }, wait);
  };
}

函数节流的实现:

javascript 复制代码
javascript
复制代码
// 时间戳版
function throttle(fn, delay) {
  var preTime = Date.now();

  return function() {
    var context = this,
      args = [...arguments],
      nowTime = Date.now();

    // 如果两次时间间隔超过了指定时间,则执行函数。
    if (nowTime - preTime >= delay) {
      preTime = Date.now();
      return fn.apply(context, args);
    }
  };
}

// 定时器版
function throttle (fun, wait){
  let timeout = null
  return function(){
    let context = this
    let args = [...arguments]
    if(!timeout){
      timeout = setTimeout(() => {
        fun.apply(context, args)
        timeout = null 
      }, wait)
    }
  }
}

CDN

1. CDN的概念

CDN(Content Delivery Network,内容分发网络)是指一种通过互联网互相连接的电脑网络系统,利用最靠近每位用户的服务器,更快、更可靠地将音乐、图片、视频、应用程序及其他文件发送给用户,来提供高性能、可扩展性及低成本的网络内容传递给用户。

典型的CDN系统由下面三个部分组成:

  • 分发服务系统: 最基本的工作单元就是Cache设备,cache(边缘cache)负责直接响应最终用户的访问请求,把缓存在本地的内容快速地提供给用户。同时cache还负责与源站点进行内容同步,把更新的内容以及本地没有的内容从源站点获取并保存在本地。Cache设备的数量、规模、总服务能力是衡量一个CDN系统服务能力的最基本的指标。
  • 负载均衡系统: 主要功能是负责对所有发起服务请求的用户进行访问调度,确定提供给用户的最终实际访问地址。两级调度体系分为全局负载均衡(GSLB)和本地负载均衡(SLB)。全局负载均衡 主要根据用户就近性原则,通过对每个服务节点进行"最优"判断,确定向用户提供服务的cache的物理位置。本地负载均衡主要负责节点内部的设备负载均衡
  • 运营管理系统: 运营管理系统分为运营管理和网络管理子系统,负责处理业务层面的与外界系统交互所必须的收集、整理、交付工作,包含客户管理、产品管理、计费管理、统计分析等功能。

2. CDN的作用

CDN一般会用来托管Web资源(包括文本、图片和脚本等),可供下载的资源(媒体文件、软件、文档等),应用程序(门户网站等)。使用CDN来加速这些资源的访问。

(1)在性能方面,引入CDN的作用在于:

  • 用户收到的内容来自最近的数据中心,延迟更低,内容加载更快
  • 部分资源请求分配给了CDN,减少了服务器的负载

(2)在安全方面,CDN有助于防御DDoS、MITM等网络攻击:

  • 针对DDoS:通过监控分析异常流量,限制其请求频率
  • 针对MITM:从源服务器到 CDN 节点到 ISP(Internet Service Provider),全链路 HTTPS 通信

除此之外,CDN作为一种基础的云服务,同样具有资源托管、按需扩展(能够应对流量高峰)等方面的优势。

3. CDN的原理

CDN和DNS有着密不可分的联系,先来看一下DNS的解析域名过程,在浏览器输入 www.test.com 的解析过程如下: (1) 检查浏览器缓存 (2)检查操作系统缓存,常见的如hosts文件 (3)检查路由器缓存 (4)如果前几步都没没找到,会向ISP(网络服务提供商)的LDNS服务器查询 (5)如果LDNS服务器没找到,会向根域名服务器(Root Server)请求解析,分为以下几步:

  • 根服务器返回顶级域名(TLD)服务器如.com.cn.org等的地址,该例子中会返回.com的地址
  • 接着向顶级域名服务器发送请求,然后会返回次级域名(SLD)服务器的地址,本例子会返回.test的地址
  • 接着向次级域名服务器发送请求,然后会返回通过域名查询到的目标IP,本例子会返回www.test.com的地址
  • Local DNS Server会缓存结果,并返回给用户,缓存在系统中

CDN的工作原理: (1)用户未使用CDN缓存资源的过程:

  1. 浏览器通过DNS对域名进行解析(就是上面的DNS解析过程),依次得到此域名对应的IP地址
  2. 浏览器根据得到的IP地址,向域名的服务主机发送数据请求
  3. 服务器向浏览器返回响应数据

(2)用户使用CDN缓存资源的过程:

  1. 对于点击的数据的URL,经过本地DNS系统的解析,发现该URL对应的是一个CDN专用的DNS服务器,DNS系统就会将域名解析权交给CNAME指向的CDN专用的DNS服务器。
  2. CND专用DNS服务器将CND的全局负载均衡设备IP地址返回给用户
  3. 用户向CDN的全局负载均衡设备发起数据请求
  4. CDN的全局负载均衡设备根据用户的IP地址,以及用户请求的内容URL,选择一台用户所属区域的区域负载均衡设备,告诉用户向这台设备发起请求
  5. 区域负载均衡设备选择一台合适的缓存服务器来提供服务,将该缓存服务器的IP地址返回给全局负载均衡设备
  6. 全局负载均衡设备把服务器的IP地址返回给用户
  7. 用户向该缓存服务器发起请求,缓存服务器响应用户的请求,将用户所需内容发送至用户终端。

如果缓存服务器没有用户想要的内容,那么缓存服务器就会向它的上一级缓存服务器请求内容,以此类推,直到获取到需要的资源。最后如果还是没有,就会回到自己的服务器去获取资源。

CNAME(意为:别名):在域名解析中,实际上解析出来的指定域名对应的IP地址,或者该域名的一个CNAME,然后再根据这个CNAME来查找对应的IP地址。

4. CDN的使用场景

  • **使用第三方的CDN服务:**如果想要开源一些项目,可以使用第三方的CDN服务
  • **使用CDN进行静态资源的缓存:**将自己网站的静态资源放在CDN上,比如js、css、图片等。可以将整个项目放在CDN上,完成一键部署。
  • **直播传送:**直播本质上是使用流媒体进行传送,CDN也是支持流媒体传送的,所以直播完全可以使用CDN来提高访问速度。CDN在处理流媒体的时候与处理普通静态文件有所不同,普通文件如果在边缘节点没有找到的话,就会去上一层接着寻找,但是流媒体本身数据量就非常大,如果使用回源的方式,必然会带来性能问题,所以流媒体一般采用的都是主动推送的方式来进行。
相关推荐
小白小白从不日白4 分钟前
react 组件通讯
前端·react.js
Redstone Monstrosity21 分钟前
字节二面
前端·面试
东方翱翔28 分钟前
CSS的三种基本选择器
前端·css
Fan_web1 小时前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
yanglamei19621 小时前
基于GIKT深度知识追踪模型的习题推荐系统源代码+数据库+使用说明,后端采用flask,前端采用vue
前端·数据库·flask
千穹凌帝1 小时前
SpinalHDL之结构(二)
开发语言·前端·fpga开发
dot.Net安全矩阵1 小时前
.NET内网实战:通过命令行解密Web.config
前端·学习·安全·web安全·矩阵·.net
Hellc0071 小时前
MacOS升级ruby版本
前端·macos·ruby
前端西瓜哥2 小时前
贝塞尔曲线算法:求贝塞尔曲线和直线的交点
前端·算法
又写了一天BUG2 小时前
npm install安装缓慢及npm更换源
前端·npm·node.js