输入url到页面显示过程的优化

浏览器架构

线程:操作系统能够进行运算调度的最小单位。

进程:操作系统最核心的就是进程,他是操作系统进行资源分配和调度的基本单位。

一个进程就是一个程序的运行实例。启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,把这样的一个运行环境叫进程。

线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率。

进程和线程之间的关系4个特点。

  1. 进程中任意线程执行出错,都会导致整个进程崩溃
  2. 线程之间共享进程中的数据
  3. 当一个进程关闭后,操作系统会回收进程占用的内存
  4. 进程之间内容相互隔离(通过IPC机制进行通信)

现代浏览器为多进程架构,打开一个页面,浏览器至少会打开四个进程 -- 浏览器主进程、渲染进程、GPU进程、网络进程。

  • 浏览器进程:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • 渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎Blink和JavaScript引擎V8都是运行在该进程中,默认情况下,Chrome会为每个Tab标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU进程:实现3D CSS效果,UI界面绘制。
  • 网络进程。主要负责页面的网络资源加载。
  • 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

地址栏键入URL后会发生什么?

  1. 构建请求:浏览器准备发起网络请求,构建请求行等
  2. 查找缓存:若命中强缓存,直接拦截请求,从本地获取资源

#URL解析

先进行url解析,提取出协议,端口,域名,路径等信息

判断你输入的是一个合法的URL 还是一个待搜索的关键词,并且根据你输入的内容进行对应操作

#DNS查询

获取到了域名对应的目标服务器IP地址

DNS(Domain Name System)是互联网中用于将域名转换为对应 IP 地址的分布式数据库系统。当客户端需要解析域名时,它会发送 DNS 查询请求到 DNS 服务器,并获取对应的 IP 地址。DNS 查询过程可以分为递归查询和迭代查询两种方式。### 递归查询1. **客户端发起请求**:当客户端需要解析域名时,它会发送一个 DNS 查询请求到本地 DNS 服务器。2. **本地 DNS 服务器查询**:本地 DNS 服务器首先检查自己的缓存中是否有该域名对应的 IP 地址。如果有,它会直接返回给客户端。3. **迭代查询**:如果本地 DNS 服务器的缓存中没有该域名对应的 IP 地址,它会向根域名服务器发送一个 DNS 查询请求。根域名服务器会告诉本地 DNS 服务器负责该顶级域的权威 DNS 服务器的地址。4. **查询顶级域 DNS 服务器**:本地 DNS 服务器再向负责该顶级域的权威 DNS 服务器发送一个 DNS 查询请求。顶级域 DNS 服务器会告诉本地 DNS 服务器负责该二级域的权威 DNS 服务器的地址。5. **查询权威 DNS 服务器**:本地 DNS 服务器继续向负责该二级域的权威 DNS 服务器发送 DNS 查询请求,直到最终获取到域名对应的 IP 地址。本地 DNS 服务器将 IP 地址返回给客户端,并将 IP 地址缓存起来,以便下次查询时使用。### 迭代查询1. **客户端发起请求**:客户端发送一个 DNS 查询请求到 DNS 服务器。2. **DNS 服务器查询**:DNS 服务器首先检查自己的缓存中是否有该域名对应的 IP 地址。如果有,它会直接返回给客户端。3. **迭代查询**:如果 DNS 服务器的缓存中没有该域名对应的 IP 地址,它会向根域名服务器发送一个 DNS 查询请求。根域名服务器会告诉 DNS 服务器负责该顶级域的权威 DNS 服务器的地址。4. **查询顶级域 DNS 服务器**:DNS 服务器再向负责该顶级域的权威 DNS 服务器发送一个 DNS 查询请求。顶级域 DNS 服务器会告诉 DNS 服务器负责该二级域的权威 DNS 服务器的地址。5. **查询权威 DNS 服务器**:DNS 服务器继续向负责该二级域的权威 DNS 服务器发送 DNS 查询请求,直到最终获取到域名对应的 IP 地址。然后,DNS 服务器将 IP 地址返回给客户端。=======递归查询和迭代查询的主要区别在于,递归查询是由 DNS 服务器代为向其他 DNS 服务器查询,直到找到域名对应的 IP 地址并返回给客户端;而迭代查询是由 DNS 服务器一步步地指导客户端自行向其他 DNS 服务器查询,直到最终找到域名对应的 IP 地址。
实际上,DNS 解析过程中既有递归查询,也有迭代查询,这两种查询方式是相辅相成的。1. **递归查询**:在 DNS 解析过程中,客户端向本地 DNS 服务器发起递归查询请求。本地 DNS 服务器会负责向其他 DNS 服务器发送递归查询请求,直到找到域名对应的 IP 地址,并将结果返回给客户端。递归查询的特点是 DNS 服务器会负责完成整个查询过程,直到找到结果并返回给客户端。2. **迭代查询**:在 DNS 解析过程中,当本地 DNS 服务器无法直接返回结果时,它会向其他 DNS 服务器发送迭代查询请求,获取更多的信息。这些迭代查询请求会依次向根域名服务器、顶级域 DNS 服务器和权威 DNS 服务器发送,直到最终找到结果。迭代查询的特点是 DNS 服务器向客户端提供其他 DNS 服务器的地址,然后客户端会继续向这些 DNS 服务器发送查询请求,直到找到结果。因此,DNS 解析过程中通常会同时使用递归查询和迭代查询,以确保客户端能够快速准确地获取到域名对应的 IP 地址。

#TCP连接

在确定目标服务器服务器的IP地址后,则经历三次握手建立TCP连接

#发送 http 请求

当建立tcp连接之后,就可以在这基础上进行通信,浏览器发送 http 请求到目标服务器

请求的内容包括:

  • 请求行
  • 请求头
  • 请求主体

#响应请求

当服务器接收到浏览器的请求之后,就会进行逻辑操作,处理完成之后返回一个HTTP响应消息,包括:

  • 状态行
  • 响应头
  • 响应正文

在服务器响应之后,由于现在http默认开始长连接keep-alive,当页面关闭之后,tcp链接则会经过四次挥手完成断开

#页面渲染

当浏览器接收到服务器响应的资源后,首先会对资源进行解析:

  • 查看响应头的信息,根据不同的指示做对应处理,比如重定向(301,302),存储cookie(如果响应头中包含 Set-Cookie 字段,表示服务器希望浏览器存储 cookie,浏览器会根据这些字段存储 cookie 信息。),解压gzip(Content-Encoding :gzip),缓存资源等等
  • 查看响应头的 Content-Type的值,根据不同的资源类型采用不同的解析方式

(Content-Type 是响应头中的一个字段,它指示了响应内容的类型。浏览器会根据 Content-Type 的值来确定响应的内容类型,然后采用不同的解析方式对响应内容进行处理。例如:

  • 如果 Content-Type 表示响应内容是 HTML 文档(如 text/html),浏览器会将其解析为 DOM 结构,并进行页面渲染。
  • 如果 Content-Type 表示响应内容是 JavaScript 脚本(如 application/javascript),浏览器会执行这段 JavaScript 代码。
  • 如果 Content-Type 表示响应内容是 CSS 样式表(如 text/css),浏览器会解析这段 CSS 代码,并应用于页面渲染。
  • 如果 Content-Type 表示响应内容是图片、音频或视频等媒体资源(如 image/jpegaudio/mp3video/mp4 等),浏览器会直接将其展示给用户或者交给相应的插件进行处理。)

渲染流程:HTML、CSS和JavaScript,是如何变成页面的?

关于页面的渲染过程如下:dom css render 布局绘制显示

  • 解析HTML,构建 DOM 树
  • 解析 CSS ,生成 CSS 规则树 样式计算
  • 合并 DOM 树和 CSS 规则,生成 render 树,(在这个阶段,浏览器会根据 DOM 树中的每个可见节点和样式计算得到的具体样式来构建渲染树,忽略掉不可见的元素或不影响渲染的节点(比如 <script><meta> 等)。这个渲染树将用于后续的布局和绘制。)
  • 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
  • 绘制 render 树( paint ),绘制页面像素信息
  • 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成,显示在屏幕上
  1. 构建DOM树:浏览器无法直接理解和使用HTML,所以需要将HTML转换为浏览器能够理解的结构——DOM树

  2. 样式计算:

    1. 把CSS转换为浏览器能够理解的结构 -- styleSheets
    2. 转换样式表中的属性值,使其标准化,比如将颜色‘red’转化成渲染引擎可以理解的rgb值
    3. 浏览器会将DOM树和CSS规则树合并,计算每个元素的具体样式信息,即进行样式计算。这个过程中,浏览器会计算出每个DOM节点的最终样式信息,包括继承的样式和自身的样式。
  3. 布局阶段:有了DOM树和样式,还不足以显示页面,接下来就需要计算出DOM树中可见元素的几何位置,这个计算过程叫做布局。

    1. 创建布局树:构建一颗元素布局树,比如去掉head等没有实际元素的标签,去掉display为none的元素等
  4. 分层:页面中有很多复杂的效果,如一些复杂的3D变换、页面滚动,或者使用z-indexing做z轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树。所以浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面

  5. 图层绘制:将布局树中的元素转换成屏幕上的像素信息。

  6. 栅格化操作:通常一个页面可能很大,但是用户只能看到其中的一部分,这个部分叫做视口。在有些情况下,有的图层可以很大,比如有的页面要滚动好久才能滚动到底部,但是通过视口,用户只能看到页面的很小一部分,所以在这种情况下,要绘制出所有图层内容的话,就会产生太大的开销,而且也没有必要。基于这个原因,合成线程会将图层划分为图块,这些图块的大小通常是256x256或者512x512。然后合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。而图块是栅格化执行的最小单位。

  7. 合成和显示:所有图块都栅格化完成后,合成线程将指令提交给浏览器进程,浏览器进程根据指令将页面内容绘制到内存中,最后从内存中取出图像显示到屏幕上。

从发起URL请求开始,到首次显示页面的内容,在视觉上经历三个阶段。可能会有阻塞的地方,怎么解决

页面渲染过程中可能出现阻塞的主要环节包括:

  • 等请求发出去之后,到提交数据阶段,这时页面展示出来的还是之前页面的内容。
  • 提交数据之后渲染进程会创建一个空白页面,这段时间称为解析白屏,并等待CSS文件和JavaScript文件的加载完成,生成CSS规则树和dom树,然后合成布局树,最后还要经过一系列的步骤准备首次渲染。
  • 第三个阶段,等首次渲染完成之后,就开始进入完整页面的生成阶段了,然后页面会一点点被绘制出来。

影响第一个阶段的因素主要是网络或者是服务器处理。

第二个阶段主要问题是白屏时间,如果白屏时间过久,就会影响到用户体验。为了缩短白屏时间,需要挨个分析这个阶段的主要任务,包括了解析HTML、下载CSS、下载Js、生成CSSOM、执行JavaScript、生成布局树、绘制页面一系列操作。通常情况下的瓶颈主要体现在下载CSS文件、下载JavaScript文件和执行JavaScript。

1. HTML解析:浏览器解析HTML文档构建DOM树时,如果遇到`<script>`标签,会立即暂停解析,等待脚本执行完毕。这是因为脚本可能会修改DOM,所以浏览器需要等待脚本执行完成后再继续解析。

2. CSS解析:CSSOM(CSS对象模型)的构建也可能阻塞渲染,因为浏览器需要确保页面的样式在脚本执行之前就已经确定。

3. JavaScript执行:JavaScript的执行会阻塞DOM的构建,因为脚本可能会操作DOM元素。

所以要想缩短白屏时长,可以有以下策略:

  • 将关键CSS直接内联到HTML中(style标签),可以加快首次渲染的速度(行内>内部>外部)。对于非关键CSS,可以通过媒体查询或JavaScript异步加载。这样只有在特定的场景下才会加载特定的CSS文件。
  • <!-- 异步加载非关键CSS --><script>var link = document.createElement('link');link.rel = 'stylesheet';link.href = 'non-critical.css';document.head.appendChild(link);</script>
    </head>

  • 异步加载脚本:使用asyncdefer属性将JavaScript脚本异步加载,可以使得脚本不会阻塞页面的渲染,从而减少白屏时间。                           async:异步加载脚本,脚本加载完成后,会立即执行,与在页面中出现的顺序无关;            defer:浏览器立即加载,但是延迟执行,需要在DOMContentLoaded事件之前执行,与出现顺序有关,dom加载完毕后按出现顺序依次执行。
  • 使用CDN加速:将页面资源分发到全球各地的CDN(内容分发网络),可以加速资源的加载速度,减少白屏时间。CDN可以使用户从距离较近的服务器获取资源,从而提高访问速度

  • 使用预加载和预渲染技术:可以使用预加载(preload)和预渲染(prerender)等技术,提前加载页面所需的资源或者预渲染页面内容,以减少白屏时间。预加载可以在页面加载过程中提前加载关键资源,而预渲染可以在后台加载整个页面内容,使得用户访问页面时可以立即展示完整内容。
  • HTTP/2通过引入多路复用、头部压缩、服务器推送等技术,优化了网络资源的利用效率,减少了网络连接的延迟,提高了页面加载速度
  • 代码分割和懒加载:可以使用代码分割将代码分成多个小块,然后按需加载。对于不影响首屏渲染的组件或功能,可以使用懒加载技术延迟加载。Webpack提供了一种称为“动态导入”的语法,可以实现代码分割。
// 使用动态导入语法,将代码按需分割成多个小块
import('./module').then(module => {// 在需要的时候加载模块module.doSomething();
});
Webpack会将动态导入的代码块分割成单独的文件,并在需要的时候按需加载。
在React中,可以使用React.lazy和Suspense组件来实现懒加载。
import React, { Suspense } from 'react';const LazyComponent = React.lazy(() => import('./LazyComponent'));function MyComponent() {return (<div><Suspense fallback={<div>Loading...</div>}><LazyComponent /></Suspense></div>);
}
当 MyComponent 被渲染时,它会先显示 fallback 属性指定的加载中提示,
然后在 LazyComponent 加载完成后显示真正的内容。
  • 客户端缓存:浏览器可以通过缓存响应内容来减少对服务器的请求。通过设置合适的缓存控制头(如Cache-ControlExpires),可以告诉浏览器何时可以使用缓存以及缓存的有效期。对于那些不经常变化的静态资源,可以使用强缓存来尽快地加载页面内容,减少白屏时间;而对于那些可能会频繁更新的动态内容,可以使用协商缓存来确保客户端可以获取到最新的资源。在Express中,你可以在路由处理函数中设置缓存控制头,通过 res.setHeader 方法实现。

代码优化

比如下面的代码,实现了一个斐波那契数列,也就是说,在实现的这个数列中,每一个数的值是前面两个数的值之和。可以使用简单的递归算法实现斐波那契数列后,在页面显示计算结果。

function fib(n){ if(n<=1) return 1 return fib(n-1)+fib(n-2) } let count = ref(fib(38))

使用performance:

打开调试窗口中的 Performance 面板,使用录制功能后,便可得到下面的火焰图。通过这个火焰图,可以清晰地定位出这个项目中,整体而言耗时最长的 fib 函数,并且能看到这个函数被递归执行了无数次。到这里,不难意识到这段代码有性能问题。不过,定位到问题出现的地方之后,代码性能的优化就变得方向明确了。

用户体验优化

1.比如用户加载大量图片的同时,如果本身图片清晰度较高,那直接加载的话,页面会有很多图一直是白框。所以可以预先解析出图片的一个模糊版本加载图片的时候,先加载这个模糊的图作为占位符,然后再去加载清晰的版本。虽然额外加载了图片文件,但是用户在体验上得到了提升。

2.类似的场景还有很多,比如用户上传文件的时候,如果文件过大,那么上传可能就会很耗时。而且一旦上传的过程中发生了网络中断,那上传就前功尽弃了。为了提高用户的体验,可以选择断点续传也就是把文件切分成小块后,挨个上传。这样即使中间上传中断,但下次再上传时,只上传缺失的那些部分就可以了。可以看到,断点上传虽然在性能上,会造成网络请求变多的问题,但也极大地提高了用户上传的体验。

3.还有很多组件库也会提供骨架图的组件,能够在页面还没有解析完成之前,先渲染一个页面的骨架和 loading 的状态这样用户在页面加载的等待期就不至于一直白屏

性能监测报告

解释一下 FCP、TTI 和 LCP 这几个关键指标的含义。

首先是 First Contentful Paint,通常简写为 FCP,它表示的是页面上呈现第一个 DOM 元素的时间。在此之前,页面都是白屏的状态;

然后是 Time to interactive,通常简写为 TTI,也就是页面可以开始交互的时间;

还有和用户体验相关的 Largest Contentful Paint,通常简写为 LCP,这是页面视口上最大的图片或者文本块渲染的时间,在这个时间,用户能看到渲染基本完成后的首页,这也是用户体验里非常重要的一个指标。


可以通过代码中的 performance 对象去动态获取性能指标数据,并且统一发送给后端,实现网页性能的监控。性能监控也是大型项目必备的监控系统之一,可以获取到用户电脑上项目运行的状态。下图展示了 performance 中所有的性能指标,可以通过这些指标计算出需要统计的性能结果。

const timing = window.performance && window.performance.timing
const navigation = window.performance && window.performance.navigation// DNS 解析:
const dns = timing.domainLookupEnd - timing.domainLookupStart// 总体网络交互耗时:
const network = timing.responseEnd - timing.navigationStart// 渲染处理:
const processing = (timing.domComplete || timing.domLoading) - timing.domLoading// 可交互:
const active = timing.domInteractive - timing.navigationStart

在上面的代码中,通过 Performance API 获取了 DNS 解析、网络、渲染和可交互的时间消耗。有了这些指标后,就可以随时对用户端的性能进行检测,做到提前发现问题,提高项目的稳定性。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Word的”交叉引用“和”插入题注“快捷键设置

Word的”交叉引用“和”插入题注“快捷键设置 在MSWord2021中&#xff0c;可以自定义设置快捷键。方法如下&#xff1a;文件-选项-自定义功能区-键盘快捷方式&#xff08;自定义&#xff09;。具体过程如图所示。 最后&#xff0c;按照上述流程将插入题注&#xff08;Insert…

openwrt开发包含路由器基本功能的web问题记录

1.这里的扫描怎么实现的先找一些luci代码&#xff0c;在openwrt21版本后&#xff0c;luci用js替换了lua写后台&#xff0c;先找一些代码路径 在openrwt15这部分代码是在这个目录下 feeds/luci/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_join.htm 里面包含…

java:6 数组(3)

文章目录 14. 二维数组14.1 定义14.2 二维数组的使用14.3 练习 【老韩视频p175-】 14. 二维数组 14.1 定义 多维数组我们只介绍二维数组&#xff1a; 二维数组的应用场景&#xff1a;比如我们开发一个五子棋游戏&#xff0c;棋盘就是需要二维数组来表示。请用二维数组输出如下…

HarmonyOS 应用开发之非线性容器

非线性容器实现能快速查找的数据结构&#xff0c;其底层通过hash或者红黑树实现&#xff0c;包括HashMap、HashSet、TreeMap、TreeSet、LightWeightMap、LightWeightSet、PlainArray七种。非线性容器中的key及value的类型均满足ECMA标准。 HashMap HashMap 可用来存储具有关联…

Typecho自媒体博客Spimes主题 X7.2

主题介绍 spimes主题专为博客、自媒体、资讯类的网站设计开发&#xff0c;自适应兼容手机、平板设备。一款简约新闻自媒体类的 typecho 主题&#xff0c;设计上简约、干净、精致、响应式&#xff0c;后台设置更是强大而且实用的新闻自媒体类主题。 已经更新到7.2&#xff0c;删…

Lumos学习王佩丰Excel第一讲:认识Excel

最近发现自己在操作excel的一些特殊功能时会有些不顺手&#xff0c;所以索性找了一个比较全的教程&#xff08;王佩丰excel24讲&#xff09;拿来学习&#xff0c;刚好形成文档笔记&#xff0c;分享给有需要但没有时间看视频的朋友们。整体笔记以王老师授课的知识点去记录&#…

阿里云数据库服务器价格表查询_一张表精准报价

阿里云数据库服务器价格表&#xff0c;优惠99元一年起&#xff0c;ECS云服务器2核2G、3M固定带宽、40G ESSD Entry云盘&#xff0c;优惠价格99元一年&#xff1b;阿里云数据库MySQL版2核2G基础系列经济版99元1年、2核4GB 227.99元1年&#xff0c;云数据库PostgreSQL、SQL Serve…

详解k8s集群内外的访问方式

文章目录 1、集群内访问2、集群外访问2.1、Ingress转发外网请求2.2、LoadBanlancer接入外网请求2.3、NodePort接入外网请求 3、总结和对比3.1、Ingress、NodePort和LoadBalancer总结3.2、Ingress和网关的区别 1、集群内访问 在k8s中创建的微服务&#xff0c;大部分都是在集群内…

验证码demo(简单实现)

前言 我们注意到我们登录网站的时候经常会用到网络验证码,今天我们就简单实现一个验证码的前后端交互问题,做一个小demo 准备 我们这里并不需要依靠原生的java来实现,而是只需要引入一个maven依赖,使用现成的封装好的即可,这是我使用的是hutool工具包 网址:Hutool&#x1f36c;…

17、GateWay和Sentinel继承实现服务限流

注&#xff1a;本篇文章主要参考周阳老师讲解的cloud进行整理的&#xff01; 1、需求说明 cloudalibaba-sentinel-gateway9528 保护 cloudalibaba-provider-payment9001 2、启动nacos服务器8848 startup.cmd -m standalone 3、启动sentinel服务器8080 java -jar sentinel-dash…

Spring面试常见问题

目录 1、为什么要用Spring框架&#xff1f;2、有了spring为什么又出现了 springboot&#xff1f;3、springboot出现后为什么又出现了spring cloud&#xff1f;4、SpringBoot自动配置&#xff08;重点&#xff09;5、SpringBoot启动流程&#xff08;重点&#xff09;6、简单谈一…

美易官方:盘前道指期货涨0.02%,小非农超预期

在盘前交易中&#xff0c;道指期货微涨0.02%&#xff0c;市场气氛相对平稳。而与此同时&#xff0c;被市场称为“小非农”的美国ADP就业数据却超预期&#xff0c;显示出美国就业市场的强劲表现。这两个消息交织在一起&#xff0c;为今天的股市交易定下了基调。 美股股指期货周三…

Wireshark抓包分析TCP协议:三次握手和四次挥手

01、前言 面试中我们经常会被问到TCP协议的三次握手和四次挥手的过程&#xff0c;为什么总喜欢问这个问题呢&#xff1f; 其实我们平时使用的很多协议都是应用层协议&#xff0c;比如HTTP协议&#xff0c;https协议&#xff0c;DNS协议&#xff0c;FTP协议等&#xff1b;而应…

情感视频素材在哪找?8个视频素材大全网站

在追求创意表达的道路上&#xff0c;每一位视频创作者都是一名勇敢的探险家&#xff0c;不断寻找那些能够点亮作品、让故事生动起来的珍贵资源。无论你的目标是打动人心、传达信息&#xff0c;还是简单地分享生活&#xff0c;以下八个视频素材网站将为你的每一个项目提供无尽的…

定时器与晶振时钟、中断系统、定时中断

定时器 简介&#xff1a; C51中的定时器和计数器是同一个硬件电路支持的&#xff0c;通过寄存器配置不同&#xff0c;就可以将他当做定时器 或者计数器使用。 确切的说&#xff0c;定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使用时&#xff0…

计算机视觉之三维重建(5)---双目立体视觉

文章目录 一、平行视图1.1 示意图1.2 平行视图的基础矩阵1.3 平行视图的极几何1.4 平行视图的三角测量 二、图像校正三、对应点问题3.1 相关匹配法3.2 归一化相关匹配法3.3 窗口问题3.4 相关法存在的问题3.5 约束问题 一、平行视图 1.1 示意图 如下图即是一个平行视图。特点&a…

视觉检测系统,外观细节无可挑剔

在传统行业中&#xff0c;利用人工检测来检测产品外观缺陷依然是主流&#xff0c;但由于竞争的加剧&#xff0c;对企业生产效率的要求也越来越高。传统的检测产品外观缺陷问题的方法就是透过人工目检&#xff0c;或者工人采用游标卡尺等工具检测&#xff0c;此种方式检测速度慢…

如何优化嵌入式系统的实时性能

大家好&#xff0c;今天给大家介绍如何优化嵌入式系统的实时性能&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 优化嵌入式系统的实时性能是一个综合性的任务&#xff0c;涉及到…

【介绍什么是DDOS】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

C语言 | Leetcode C语言题解之第6题Z字形变换

题目&#xff1a; 题解&#xff1a; char * convert(char * s, int numRows){int n strlen(s), r numRows;if (r 1 || r > n) {return s;}int t r * 2 - 2;char * ans (char *)malloc(sizeof(char) * (n 1));int pos 0;for (int i 0; i < r; i) { // 枚举矩阵的…