输入一个url后发生了什么 js性能优化

news2024/9/21 18:58:15

文章目录

      • 从一道题开始:输入一个url后发生了什么?
      • 1.请求协议
        • 可聊点1:http协议相关
          • => 追问: http与TCP
        • 可聊点2: https协议相关
          • => 追问:http与https
      • 2.域名解析
      • 3.web服务器
      • 4.服务(2、3)涉及到 网络优化
      • 5.浏览器渲染
      • 6.脚本执行时 - JS
        • 可聊点:js的垃圾回收
      • 7.打包配置的优化

从一道题开始:输入一个url后发生了什么?

1. 浏览器自动补全协议、端口
2. 浏览器自动完成url编码
3. 浏览器根据url地址查找本地缓存,根据缓存规则看是否命中缓存,若命中缓存则直接使用缓存,不再发出请求
4. 通过DNS解析找到服务器的IP地址 
5. 浏览器向服务器发出建立TCP连接的申请,完成三次握手后,连接通道建立
6. 若使用了HTTPS协议,则还会进行SSL握手,建立加密信道。使用SSL握手时,会确定是否使用HTTP2
7. 浏览器决定要附带哪些cookie到请求头中
8. 浏览器自动设置好请求头、协议版本、cookie,发出GET请求
9. 服务器处理请求,进入后端处理流程。完成处理后,服务器响应一个HTTP报文给浏览器。
10. 浏览器根据使用的协议版本,以及Connection字段的约定,决定是否要保留TCP连接。
11. 浏览器根据响应状态码决定如何处理这一次响应
12. 浏览器根据响应头中的Content-Type字段识别响应类型,如果是text/html,则对响应体的内容进行HTML解析,否则做其他处理
13. 浏览器根据响应头的其他内容完成缓存、cookie的设置
14. 浏览器开始从上到下解析HTML,若遇到外部资源链接,则进一步请求资源
15. 解析过程中生成DOM树、CSSOM树,然后一边生成,一边把二者合并为渲染树(rendering tree),随后对渲染树中的每个节点计算位置和大小(reflow),最后把每个节点利用GPU绘制到屏幕(repaint)
16. 在解析过程中还会触发一系列的事件,当DOM树完成后会触发DOMContentLoaded事件,当所有资源加载完毕后会触发load事件

1.请求协议

可聊点1:http协议相关

=> 追问: http与TCP

a.概念
http:应用层网络协议
TCP:传输层协议

b.关联:http基于TCP实现连接(http依赖TCP实现请求、发送、断开)
优化点:http1.0 => http2.0
UDP vs TCP
TCP:面向连接确认。UDP:面向连接传输
UDP更快,性能更高。但是TCP更确保能收到
(1)TCP 是面向连接的,UDP 是无连接的即发送数据前不需要先建立链接。
(2)TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付。
并且因为 tcp 可靠,面向连接,不会丢失数据因此适合大数据量的交换。
(3)TCP 是面向字节流,UDP 面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如 IP 电话和视频会议等)。
(4)TCP 只能是 1 对 1 的,UDP 支持 1 对 1,1 对多。
(5)TCP 的首部较大为 20 字节,而 UDP 只有 8 字节。
keep-alive (http1.1实现, 2.0没有)
http发送请求之后会断开TCP连接。打开这个配置,保持TCP的连续畅通,不用反复的建立连接
http版本
http1.0 和 http2.0在链接上的区别: 复用通路 - 2.0多个请求复用同一条TCP通路
例:同时发送十条请求:
1.1中:同步发送六条,一条结束,补上一条,直到请求完毕。
2.0中:十条同时发送。(复用通路、无并发限制,尽量避免使用数据多的‘胖接口’,http2.0帮助实现)

c.差别:http - 无状态连接;TCP - 有状态
优化点:
socket连接,封装化的TCP,让我们的应用更加方便的使用调用。

可聊点2: https协议相关

=> 追问:http与https

a. 概念
https=http + SSL(TLS)
位于TCP连接协议与各种应用协议之间
b. 实现原理
在这里插入图片描述

客户端像服务器请求数据,服务端会返回给客户端一个盒子,这个盒子的钥匙(公匙)只有服务端有。客户端收到后,根据自身定义生成对应的密匙,装进盒子后,发送给服务端。服务端用自己的钥匙打开自己的盒子,得到客户端的密钥。这样,只有客户端和服务端才有客户端的钥匙,就可以通过这个密匙加密来进行通信。

在这里插入图片描述

客户端拥有秘钥A,服务器拥有公钥B和私钥C,首先,客户端向服务器发送请求,服务器接到请求,响应请求并把它的公钥B传给客户端,客户端接收到公钥B后用公钥B加密秘钥A,形成一段密文,然后把密文传给服务器,而公钥加密的密文只能用私钥解密,但我们只传输过公钥,所以只有服务器拥有私钥,能够解密这段密文得到秘钥A,这样就只有客户端和服务器这个秘钥A了,中间没有任何人拥有秘钥A,然后客户端和服务器的通信就可以通过秘钥A来进行加密解密,这样就保证了数据传输过程中的加密问题。

c. 优化
https多次连接,导致网络请求加载时间延长,增加开销和消耗。
建议合并请求,长连接。

–可能问到:中间层 整合请求时 - 异常处理–

2.域名解析

IP地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转换过程。域名的解析工作由DNS服务器完成。

1. 浏览器缓存中 - 浏览器中会缓存DNS一段时间
2. 系统缓存 - 系统中找缓存 -> HOST
 (没有找到说明当前这台机器没有访问此次域名的记录)
3. 路由器缓存 - 各级路由器缓存域名信息
4. 运营商地方站点的缓存信息 - partner (基本上可以找到)
5. 根域名服务器
        优化:
        => CDN - Content Delivery Network  
       1. 为同一个主机分配多个Ip地址
       2. LB - 负载均衡
       => 缓存 => 各级缓存 => 浏览器区分缓存(协商缓存、强缓存)

3.web服务器

常用服务器:apache、ngnix
1.作用:接受请求传递给服务端代码
2.通过反向代理,传递给其他服务器
3.不同域名 => 指向相同ip的服务器 => ngnix域名解析 => 引导到不同的服务监听端口

4.服务(2、3)涉及到 网络优化

手写并发 - QPS

面试:并发优化,10个请求,由于后台或者业务需求只能同时执行三个,如何做一个前端并发请求的控制
(10个请求,每次请求三个,一个结束,补上一个,知道十个全部请求完成)
分析:
  输入 :promise请求数组,limit限制参数(默认为3)
  存储:reqpool - 请求并发池,控制最大并发量,所有请求一个一个进来,有执行结束的,再塞进来一个
  思路:
  塞入并发池,直到超过limit,停止。reqpool满了,开始执行。
  有一个返回,则再次塞入并发池。

分析时,可根据时间顺序、逻辑顺序、结构顺序 拆解

function qpsLimit(requestPipe, limitMax = 3){
  let reqPool = []
  
  // 塞入方法,往并发池里塞入promise请求
  const add =()=>{
   let _req = requestPipe.shift()
   reqPool.push(_req)
  }
  
  // 执行的方法,执行实际请求
  const run =()=>{
  if(requestPipe.length === 0) return      //没有要执行的方法,停止
  let _finish = Promise.race(reqPool)    //有一个执行完,就要添加一个,获取到执行最快的那个
   _finish.then((res)=>{
   let done=reqPool.indexOf(_finish)
   reqPool.slice(done,1)                // 请求池中拿出请求完毕的那个请求
   add()                                // 重新添加一个
   })
  }
  
  // 便利,区分满没满
  while(reqPool.length < limitMax ){
   add()
  }
  
  run()
}

优化思考:结合节流实现,三秒内不会重复发请求

5.浏览器渲染

在这里插入图片描述
主线:HTML => DOM + CSSOM => renderTree + js => layout => paint
支线:
repaint - 改变文本、颜色等展示,不改变自身及周边的大小和布局
reflow - 元素几何尺寸变了,需要重新计算renderTree(reflow 成本>repaint成本)

渲染流程:首先,渲染引擎解析HTML文档,生成DOM树,css样式会被解析生成CSSOM树。然后CSSOM与DOM生成render Tree。接下来在渲染树的基础上进行布局。最后将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting

优化: 减少repaint,避免reflow(display: none => reflow; visibility:hidden; => repaint)
页面加载时,添加一个loading,待页面构建完成再展示页面,避免首次加载时,元素或数据加载不全的reflow

6.脚本执行时 - JS

js在代码里能做哪些性能优化?

可聊点:js的垃圾回收

点击了解详情 js垃圾回收
mark & sweep => 触达标记,锁定清空、未触达直接抹掉

    // 内存分配:申明变量、函数、对象
    // 内存使用:读写内存
    // 内存释放
    // gc:垃圾回收
  const zhaowa = {
        js: {
            performance: 'good',
            teacher: '云隐'
        }
    }

    // 建立引用关系
    const _obj = zhaowa

    // 引用源给替换掉了 - 暂未gc
    zhaowa = 'best'
    /**
    *此时,zhaowa的值已经变成了‘best’,但是_obj还在用最初对象的值,所以对象还不能被垃圾回   收。
    */

      // 深入层级做引用 - 暂未gc
       const _class = _obj.js
      // obj被拆分成两份存在堆内容中,一个指向_obj,一个指向_class
      
       // 引用方替换 - 暂未gc
        _obj = 'over'
        
        // gc 完成
        _class = null

优化点

  1. 对象层级,宜平不宜深
  2. 深层引用最好深拷贝,或者用完直接销毁
  3. 避免循环引用
  // 1.循环引用:
  function traverseTree(node1, node2) {
        node1.parent = node2;
        node2.children = node1;
    }
   // 这种写法,每个节点既有父节点的信息,又有子节点的信息,拿到一个节点,可以知道他的关系节点。可以提高效率。但是这种写法使两个节点相互引用,导致node永远不会被gc。

   // 2. 内存泄露
    // 莫名其妙的全局变量
    function foo() {
        bar1 = ''
        this.bar2 = ''
    }

    // 未清理的定时器
    setInterval(() => {
    }, 1000)

    // 使用后的闭包
    function zhaowa() {
        const _no = 1
        return {
            number: _no
        }
    }

7.打包配置的优化

三个方向:

  1. 懒加载 - 非必要不加载
  2. 按需引入 - 非必要不引入
  3. 抽离公共 - 相同项目合并公用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Zookeeper】关于windows安装问题整理汇总

文章目录常规安装&#xff1a;1、windows配置zoo.cfg之后&#xff0c;提示&#xff1a;JAVA_HOME is not set.1.1 本地没有安装JDK或者没有配置JAVA_HOME解决方案&#xff0c;参考JDK安装下载办法1.2 本地配置的JDK但是环境变量JDK路劲不叫名字“JAVA_HOME”解决方案&#xff1…

docker容器将系统盘空间占满的解决办法

最近遇到一个问题&#xff0c;线上服务器的系统盘空间被占满了&#xff0c;导致服务不能正常运行了。docker启动时会报出下面这个错误no space left on device排查用到的命令&#xff0c;显示当前路径下占用空间超过1G的文件或文件夹du -h --max-depth1|grep G|sort -n经过一番…

SAP FICO 详细解析新总账功能 - 平行分类账配置

平行分类账配置 其作用简单来说就是&#xff0c;同时一笔记账&#xff0c;会产生多个账套的凭证。 【配置流程】 1、定义总账会计核算的分类账 账套可以有多个&#xff0c;但是主分类账有且只有一个。 表FAGLFLEXT就是存储所有财务分类账发生额数据的汇总表。 勾选多个“主…

CSS知识梳理

CSS的三大特性 一 . 层叠性 : 相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖&#xff08;层叠&#xff09;另一个冲突的样式。层叠性主要解决样式冲突的问题 层叠性原则 : 样式冲突&#xff0c;遵循的原则是就近原则&#xff0c;哪个样式离结构近&#xff0c…

在Azure应用程序按指定时区的时间来输出日志(NLog)

部署在Azure应用程序使用NLog组件进行日志输出&#xff0c;如购买的Azure云是国际版&#xff08;非中国版Azure&#xff09;&#xff0c;默认使用国标时间&#xff08;即&#xff1a;UTC&#xff09;来输出日志时间&#xff0c;与中国地区的时间相差8小时&#xff08;即&#x…

NodeJs使用mysql.createPool连接池

1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABASE mydb1; mysql> SHOW DATABASES; -------------------- | Database | -------------------- | information_schem…

客快物流大数据项目(一百零三):快递追踪需求介绍

文章目录 快递追踪需求介绍 ​​​​​​​前言 背景介绍 快递追踪需求介绍 ​​​​​​​前言

Juicesync实现对腾讯云CHDFS存储的数据迁移

文章目录前言一、Juicesync准备二、Hadoop准备三、迁移实验四、实现思路前言 近年来&#xff0c;云计算越来越流行&#xff0c;企业从自身利益出发&#xff0c;或是不愿意被单一云服务商锁定&#xff0c;或是业务和数据冗余&#xff0c;或是出于成本优化考虑&#xff0c;会尝试…

Electron + vite + vue3简单实现

文章目录一、创建Electron应用程序1. 初始化vite项目2. 安装electron3. 修改配置文件4. 编写electron文件5. npm run dev 运行二、打包1. 安装包2. 配置打包脚本3. 渲染进程和主进程的通信渲染进程主进程一、创建Electron应用程序 Electron官网 1. 初始化vite项目 npm creat…

【区块链技术前沿】可下载内容与NFT

发表时间&#xff1a;2022年3月29日 信息来源&#xff1a;coingeek.com 目前&#xff0c;DLC&#xff08;可下载内容&#xff09;仍然是备受争议的话题&#xff0c;但却是电子游戏世界在2010年代选择的一个非常成功的市场方向。许多游戏玩家继续抱怨着电子游戏发行商在敲诈用户…

认识Panda3D引擎bam相关命令

看一下Panda自带命令&#xff0c;其中有bam相关的&#xff0c;来了解一下&#xff1b; 输入一个命令看一下&#xff0c;提示需要输入一个bam文件名&#xff1b; 查一下&#xff0c;查到一个介绍一种bam文件的资料如下&#xff0c; SAM (Sequence Alignment/Map) 格式是一种通用…

Springboot +Shiro +VUE 前后端分离式权限管理系统

前言前后端分离&#xff0c;一般都是通过token实现&#xff0c;本项目也是一样&#xff1b;用户登录时&#xff0c;生成token及 token过期时间&#xff0c;token与用户是一一对应关系&#xff0c;调用接口的时候&#xff0c;把token放到header或 请求参数中&#xff0c;服务端就…

ROS2机器人编程简述humble-第二章-Publishing and Subscribing .3.2

ROS2机器人编程简述humble-第二章-Controlling the Iterative Execution .3.1官方示例pub和sub使用std_msgs/msg/string.hpp&#xff0c;数据类型std_msgs::msg::String。这本书中使用是std_msgs/msg/int32.hpp&#xff0c;数据类型&#xff1a;std_msgs::msg::Int32。对于机器…

Servlet —— Servlet API

JavaEE传送门JavaEE Servlet —— Tomcat, 初学 Servlet 程序 Servlet —— Smart Tomcat,以及一些访问出错可能的原因 目录Servlet APIHttpServletHttpServletRequest获取 GET 请求中的参数获取 POST 请求的参数HttpServletResponseServlet API 虽然 Servlet 提供的类和方法…

【UE4 第一人称射击游戏】53-制作烟雾弹

上一篇&#xff1a;【UE4 第一人称射击游戏】52-手榴弹攻击丧尸本篇效果&#xff1a;按F键掷出烟雾弹&#xff0c;伴随产生音效和烟雾效果本篇步骤&#xff1a;拷贝一份“GrenadeActor”命名为“SmokeGrenadeActor”双击打开“SmokeGrenadeActor”&#xff0c;删除如下节点改变…

尚医通-医院详情功能(二十七)

目录&#xff1a; &#xff08;1&#xff09;前台用户系统-医院详请-情接口开发 &#xff08;2&#xff09;前台用户系统-技术点-nuxt路由 &#xff08;3&#xff09;前台用户系统-医院详情-前端整合 &#xff08;1&#xff09;前台用户系统-医院详-情接口开发 现在做在页面…

13 Java异常(异常过程解析、throw、throws、try-catch关键字)

文章目录13 异常13.1 异常概念13.2 异常的产生过程解析13.3 异常的阐释和处理13.3.1 throw关键字13.3.2 throws关键字13.3.3 try-catch代码块13.3.4 try-catch-finally代码块Java中final、finally和finalize相似点和区别13.3.5 自定义异常13 异常 13.1 异常概念 异常&#xff…

SpringCloud(12):Zuul路由网关

1 为什么需要服务网关 在分布式系统系统中&#xff0c;有商品、订单、用户、广告、支付等等一大批的服务&#xff0c;前端怎么调用呢&#xff1f;和每个服务一个个打交道&#xff1f;这显然是不可能的&#xff0c;这就需要有一个角色充当所有请求的入口&#xff0c;这个角色就是…

【C++】从0到1入门C++编程学习笔记 - 实战篇:通讯录管理系统

文章目录一、需求分析二、创建项目2.1 创建新项目2.1 添加文件三、菜单功能四、退出功能五、添加联系人5.1 设计联系人结构体5.2 设计通讯录结构体5.3 main 函数中创建通讯录5.4 封装添加联系人函数5.5 测试添加联系人功能六、显示联系人6.1 封装显示联系人函数6.2 测试显示联系…

STM32F103和AIR32F103的FreeRTOS中断优先级

关于 Arm Cortex M 系列内核的中断优先级 Cortex M 的中断和优先级 首先要区分开 中断 和 中断优先级 这是两个不同的东西, 不要搞混了 对于 Cortex-M0 和 Cortex-M0 内核, 除了系统内建中断外, 支持最多 32 个中断对于 Cortex-M3 内核, 除了 16 个内核中断外, 支持最多 240…