前端性能优化:高在性能,大在范围,必要前置知识一网打尽!(下)

news2024/11/24 19:37:38

前言

在上一篇 前端性能优化:高在性能,大在范围,必要前置知识一网打尽!(上) 一文中介绍了和前端性能优化相关的一些前置知识,那么本篇就针对优化方案进行总结,核心的方向还是上篇文章中提到的内容:

  • 保证资源更快的 加载速度 :达到越快渲染越快,视图展现就越快

  • 保证视图更快的 渲染速度/交互速度 :用户与页面交互,前提是页面要渲染出来,其次是页面需要尽早反馈,目的就是保证用户良好的体验性

其实将上述两点再进行翻译,那么其实指的就是 网络层面的优化 和 浏览器层面的优化,这样看来其实前端性能优化方向还是很明确的,只不过明确的方向中还是会涉及不同方面的具体优化手段。

还是不得不回顾 从输入 URL 到页面加载完成 的核心过程:

  • 进行 DNS 解析

  • 建立 TCP 连接

  • 客户端发送 HTTP 请求

  • 服务端响应 HTTP 资源

  • 浏览器获取响应内容,进行解析和渲染

从上述的内容来看,不难发现每一步都是需要消耗一定的时间,那么优化的方向就可以围绕着这些内容来考虑。

长文预警❗️❗️❗️ 

如何保证资源更快的加载速度?

下面内容主要针对 DNS 解析、 TCP 连接、 HTTP 请求/响应 等阶段来谈的优化,核心优化核心其实就是 网络层面

使用 dns-prefetch 减少 DNS 的查询时间

dns-prefetch 能够 提前解析 后续可能会用到的 不同域的域名,使解析结果 缓存到系统缓存 中,缩短 DNS 解析时间以提高网站的访问速度。

比如在掘金中的体现如下:

扩展】 DNS 解析的核心过程

当浏览器访问一个域名时需解析一次 DNS,以获得对应域名的 IP 地址:

  • 浏览器 会从自身的 缓存中 查询是否存在对应域名的 IP 地址,若存在返回,若不存在进入下一步

  • 客户机查询操作系统中的 /etc/hosts 文件中查询是否有对应域名的 IP 地址,若存在则返回,若不存在进入下一步

  • 客户机请求 本地域名服务器(LDNS) 进行解析,本地域名服务器收到客户机的请求后,先查询自己的缓存信息是否有对应域名的 IP 地址,若存在返回结果,没有则进行下一步

  • 本地域名服务器请求 根域名服务器 解析该域名,根域名告诉本地域名服务器去找对应的 一级域名服务器

  • 本地域名服务器请求一级域名服务器解析这个域名,一级域名服务器告诉它去找对应的 二级域名服务器

  • 本地域名服务器请求二级域名服务器解析这个域名,二级域名服务器告诉它去找对应的 子域名服务器

  • 本地域名服务器请求子域名服务器解析这个域名,子域名服务器返回对应的 IP 地址

  • 本地域名服务器将 IP 地址记录到缓存中,并返回给客户机(会缓存起来),客户机根据收到的 IP 地址访问该网站

使用 preconnect 提前建立连接

preconnect 的作用是提前和第三方资源建立连接,设置了它浏览器就会做好早期的连接工作,但这个连接通常只会维持 10 s

比如在当前域请求一个资源前,可能会涉及 DNS 寻址、TLS 握手、TCP 握手、重定向等,这过程也会花费一定的时间。

比如在掘金中的体现如下:

使用 preload / prefetch 预先加载资源

preload

preload 的作用是提前加载页面对应的 关键资源 加快页面的渲染,preload 的优先级顺序和 as 属性相关。

注意as 属性一定要设置,除了上面提到的设置优先级外,还涉及到浏览识别的问题:如果没有设置 as 属性,后续遇到该请求就会被作为一个 XHR 请求,把意味着资源预加载的功能可能会失效,因为可能会每次都发起新的请求获取

比如在掘金中的体现如下:

比如在 vue-cli 的默认 webpack 配置,如下:

prefetch

preload 是对资源的预加载,它虽提前加载但只在需要执行时执行,即这个资源一定是当前页面所需要的资源,如果是需要为下一个页面提前加载资源,那么应该使用 prefetch,它会在 浏览器空闲时 下载资源。

比如在 vue-cli 的默认 webpack 配置,如下:

压缩资源体积

资源是需要通过 http 数据包的方式在网络中进行传输的,那么只要能减少传输数据包的体积,也是能够使得资源更快到达客户端,这也是压缩资源体积的核心目的。

HTTP 压缩

HTTP 压缩中一个典型代表就是 gzip,它是一种优秀的压缩算法,可对 http 请求中的一些文件资源进行压缩处理,一般来讲是要在服务端处理的,可通过在响应头中设置 Content-encoding: gzip 表示当前资源使用的压缩方式(如:gzip、deflate、br 等),便于客户端使用正确的方式解压。

注意gzip 并不是万能的,它不能保证针对每个文件的压缩都能使其体积变小,关于 Content-Encoding 的内容可参考 content-encoding 除了gzip之外,你还知道哪些?

比如在京东中的体现:

比如在掘金中的体现:

Webpack 压缩

有 HTTP 压缩 不就够了吗?为什么还需要 Webpack 压缩?

首先必须要明确的是压缩的过程本身就是会消耗时间的,如果所有资源都等到被访问的时候再由服务端进行压缩,在压缩完成之前客户端还是得处于等待状态,即仍 不能保证资源以最快的速度到达客户端

那么优化方案就是将压缩资源的时间放到打包构建中,毕竟只有真正需要发布线上生产环境时才需要执行一系列的打包优化的操作,而这相比于 http 的 请求/响应 速度,稍微延长产物打包时间没有什么大问题。

下面会列举一些 Webpack 插件,但并不会去讲其中的具体用法,因为这些只是达到目的的不同方案而已,每个方案要是细讲都可以独占一篇文章,在这是没有必要的,具体用法可自行查阅。

使用 CompressionPlugin 压缩文件

webpack 文档 提供插件合集中就包含了该插件,它的作用就是: Prepare compressed versions of assets to serve them with Content-Encoding.

使用 HtmlWebpackPlugin 压缩 HTML 文件

通常我们需要 HtmlWebpackPlugin 插件来生成对应 HTML 或 对已有的 HTML 模板自动注入 webpack bundles 资源,除此之外,它还可配置 minify 选项实现压缩模板的目的。

可以在 vue 项目下执行 vue inspect --mode production > webpack.config.js来查看脚手架的默认 webpack 配置内容,比如:

使用 SplitChunksPlugin 自定义分包策略

Webpack 默认会将尽可能多的模块代码打包在一起,这种默认规则的带来的优点和缺点都很明显:

  • 优点:能减少最终页面的 HTTP 请求数

  • 缺点:

    • 页面初始代码包过大,影响首屏渲染性能

    • 无法有效应用浏览器缓存

SplitChunksPlugin 是 Webpack 4 之后内置实现的最新分包方案,与 Webpack 3 中的 CommonsChunkPlugin 相比,它能够基于一些更灵活、合理的启发式规则将 Module 编排进不同的 Chunk,最终构建出 性能更佳、缓存更友好 的应用产物。

比如在 vue-cli 的默认 webpack 配置,如下:

使用 MiniCssExtractPlugin 抽离和压缩 CSS

MiniCssExtractPlugin 会将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的 按需加载 。

比如在 vue-cli 的默认 webpack 配置,如下:

使用 ImageMinimizerWebpackPlugin 压缩图片资源

图片仍是一个 Web 应用中的必不可少的资源,而图片资源的体积也是首屏页面加载的瓶颈之一,因此,压缩图片也是性能优化需要考虑的内容。

ImageMinimizerWebpackPlugin 可用于使用 优化/压缩 所有图像,它可以支持 无损(不损失质量)有损(质量下降) 两种模式的压缩方式。

通过 Tree Shaking 移除无用代码

Tree Shaking 依赖于 ES6 模块语法的 静态结构 特性(如: import 和 export),当 webpack 的模式 mode 为 "production" 时,就可以启用 更多优化项 ,包括 压缩代码与 Tree Shaking

但同时我们就必须保证:

  • 尽量使用 ES6 模块语法,即 import 和 export

  • 保证没有 编译器(如:babel)将对应的 ES6 模块语法转换为 CommonJS 的语法(如:@babel/preset-env 的默认行为)

  • 可在项目的 package.json 文件中添加 "sideEffects" 属性,标识当前内容是否存在副作用操作

  • 可在通过 /*#__PURE__*/ 注释,将函数调用标记为无副作用

减少 http 请求数量

不同协议 下 请求数量 仍然可能成为 请求/响应 慢的原因:

  • 合并公共资源,如 雪碧图 等

  • 内置模块资源,如 生成 base64 图片、通过 symbol 引用 svg 等

  • 合并代码块,如构建工具分包策略配合 公共组件封装、组件复用逻辑抽离 等

  • 按需加载资源,如 路由懒加载、图片懒加载、上拉加载、分页加载 等

减少不必要的 cookie

不必要的 cookie 来回传输会造成带宽浪费:

  • 减少 cookie 存储的内容

  • 对于静态资源采用 CDN 托管(即非同域),不同域名默认不携带 cookie

CDN 托管静态资源 + HTTP 缓存

CDN 加速的本质是缓存加速,将服务器上存储的静资源容缓存在 CDN 节点上,当后续访问这些静态内容时,无需访问服务器源站,选择就近访问 CDN 节点即可,从而达到加速的效果,同时减轻服务器源站的压力。

在掘金中体现如下:

协议升级为 Http2.0

http1.x 存在的问题: HTTP 的底层协议是 TCP,而 TCP 是面向连接即需要 三次握手才能建立连接,其中:

  • http1.0 中使用的是 短连接,即 一次请求/响应 结束后就会断开连接,这个过程比较耗时

  • http1.1中使用的是长连接,在请求/响应头中设置Connection: keep-alive即可开启,优点是长连接允许多个请求共用一个TCP连接,缺点是带来了队头阻塞

    • 每个 TCP 连接中的多个请求,需要进行排队,只有队头的请求被响应,才能继续处理下一个请求

    • 其中一个缓解方案就是如果当前 TCP 连接中发生 队头阻塞,那就将部分请求放到其他 TCP 连接中

    • 浏览器一般会限制同一个域名建立 6-8 个 TCP 链接,这也就是为什么需要为应用划分子域名、静态资源托管 CDN 的原因之一

  • http1.x 中 header 部分的内容可能会很大,而且每一个请求可能都需要携带大量 重复header 的 文本内容,而这些也是导致 请求/响应 慢的原因之一

以上问题 http2.0 都能够解决:

  • 针对 TCP 连接数 被限制的问题,http2.0 采用 多路复用 一个域名只对应一个 TCP 连接

  • 针对 http 队头阻塞 问题,http2.0 中通过二进制分帧层为每个 请求/响应 添加 stream id 保证 请求/响应 一一对应,即不必等待前面的请求处理完成,并且还可以为每个请求添加 优先级

  • 针对header数据大的问题,http2.0中传输的header帧经过处理后会用二进制的方式表示,替换了原本的文本格式 ,并使用HPACK算法进行压缩

    • 接收/发送 两端会维护一个 索引表,通过下标来标识 header,针对后续重复的 header 信息就可以用对应的索引来代替

  • 针对传统的 请求 —> 响应 模式,http2.0 中提供了 服务端推送 的能力,让服务端能够主动向客户端推送关键资源,加快资源加载

比如在掘金中的体现:

如何保证视图更快的渲染和交互?

保证资源快速到达客户端后,接下来就需要针对 浏览器的解析和渲染 进行优化,当然还包括后续的页面交互的优化,这其实就是 浏览器层面 的优化。

浏览器渲染 HTML 文件的核心过程:

  • HTML 解释器:将 HTML 文档经过词法分析输出 DOM Tree

  • CSS 解释器:解析 CSS 文档,生成样式规则 CSSOM

  • 样式计算:将 DOM Tree 和 CSSOM 合并生成 Render Tree

  • 布局计算:计算 Render Tree 节点在页面中的坐标位置,创建 Layout Tree

  • 划分图层:页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或使用 z-index 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,生成对应的图层树 Layer Tree

  • 图层绘制:

    • 染引擎实现图层的绘制时,会把一个图层的绘制拆分成很多小的 绘制指令,并将这些指令按照顺序组成一个 待绘制列表

    • 当图层的绘制列表准备好后,主线程 会把 待绘制列表 提交(commit)给 合成线程

  • 栅格化 raster:

    • 由于视口有限,用户只能看到页面的很小一部分,没必要绘制出所有图层内容,因此 合成线程 会将 图层(layer) 划分为 图块(tile)

    • 渲染进程 把 生成图块的指令 发送给 GPU 并执行生成图块的 位图

  • 合成和显示:

    • 一旦所有图块都被光栅化,合成线程 就会生成一个绘制图块的命令 —— DrawQuad,然后将该命令提交给 浏览器进程

    • 浏览器进程 里面有一个 viz 组件,会根据 DrawQuad 命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上

渲染层面

减少阻塞渲染的因素

真正渲染视图之前,必然要生成 DOM Tree 和 CSSOM,因此必须保证 HTML 解释器 和 CSS 解释器 都尽早处理完成,同时 JavaScript 的加载和执行可能会阻塞这个过程:

  • HTML 文档中首次渲染的节点数量要尽量少,避免深层次的嵌套结构,避免大量使用慢标签(如:iframe)等

  • CSS 资源放文档头部,降低 CSS 复杂度,比如 合理使用 CSS 选择器

  • JavaScript 资源放文档底部,合理使用 defer、async 的加载方式

懒加载

懒加载主要是针对数量大、资源加载慢的情况,比如图片资源、大量列表数据展示等:

  • 图片资源:优先加载在可视区范围内的图片,可视区外的图片 延后加载 ,或者说当移入的可视区时再加载

  • 列表数据:列表数据通常数据里量大,不可能一次渲染完所有数据,一般通过 分页加载、上拉加载 等方式分批次渲染

白屏优化

白屏是由于 SPA 应用需要等待 JavaScript 加载并执行完成后才会生成具体的页面结构内容导致的,即初始化模板中没有任何有意义需要被渲染的 HTML 结构:

  • 添加 白屏 loading ,可在模板中添加默认的 loading 效果,等到真正页面内容被渲染就可以替换 loading 内容

  • 添加 骨架屏,和上述方案一致,在真正页面内容展示出来之前,先展示默认的视图内容,避免白屏

服务端渲染(server-side rendering)

现代框架默认是属于客户端应用框架,即组件的代码会在浏览器中运行,然后向页面输出 DOM 元素,也叫 客户端渲染(client-side rendering,CSR)

  • 优点

    • 用户体验更好 ,基于 前端路由 的方式并不会真正进行 页面跳转,即不会使页面重新刷新、加载,带来更高的流畅度

    • 占用服务端资源少 ,CSR 渲染 是交由客户端进行处理,服务端不需要关心渲染计算的过程,减轻了服务端的压力

  • 缺点

    • "白屏" 时间较长 ,主要是因为 CSR 渲染需要 *.js 的支持,而 *.js 又必须保证 *.html 被接收和解析, *.html 又强依赖于当前的 网络环境,因此,在差网环境下回导致 白屏时间过长,特别是在移动网络环境下

    • 对 SEO 的支持不友好 ,因为 白屏时间较长 导致在一段时间内没有重要的内容能够交由 搜索引擎 进行分析、分类、打标签等,并且 搜索引擎 并不会等待页面渲染完成,因此对 SEO 优化并不友好

服务端渲染(server-side rendering,SSR) 可将相同组件在服务渲染成相应的 HTML 字符串,并发送给浏览器进行渲染,即客户端不需要等待所有的 JavaScript 都被下载并执行之后才显示,所以用户可以更快看到完整的渲染好的内容。

预渲染(prerender)

上述 服务端渲染(server-side rendering,SSR) 虽然能够解决一些客户端存在的问题,但它也带来了别的问题:

  • 需要保证开发一致性 ,比如 服务端 和 客户端 能够执行的组件生命周期钩子不同,一些外部库在 服务端渲染 应用中可能需要经过特殊处理

  • 需要更多的构建设定和部署要求 ,一个完全静态的 SPA 可以部署在任意的静态文件服务器,但服务端渲染应用需要一个能够运行 Node.js 服务器的环境

  • 更多的服务端负载 ,在 Node.js 中渲染一个完整的应用,会比仅供应静态文件产生更密集的 CPU 运算,并且需要考虑访问流量过大的情况等

因此,并不是所有应用都合适 服务端渲染,如果只是希望通过 SSR 来改善一些 推广页面 (如 //about/contact 等) 的 SEO,那么应该优先考虑 预渲染 的方式:

  • 预渲染 是在打包构建过程中(离屏状态),针对对应的 routes 路由预先生成对应的页面内容

  • 预渲染 需要和 打包构建工具(webpack、rollup 等) 进行配合,如 webpack ,就可通过 prerender-spa-plugin 来支持 预渲染

交互层面

减少回流/重绘

重绘:页面中元素样式的改变并不影响它在文档流中的位置时(如:color、background-color、visibility 等),浏览器会将新样式赋予给元素并 重新绘制

回流:当 Render Tree 中部分或全部元素的 尺寸、结构、某些属性 发生改变时,浏览器 重新渲染 部分或全部文档

  • 减少对 DOM 进行频繁操作

  • 使经常变动的元素脱离文档流,如具有持续性的动画效果,会一直触发回流和重绘

  • 避免访问或减少访问会导致浏览器强制刷新队列的属性,如:offsetTop、offsetLeft、offsetWidth

    • 扩展】浏览器的渲染队列机制会通过 队列 将会触发 回流或重绘 的操作进行存储,等到一定的时间或一定的数量时再执行这些操作

  • 避免对 css 进行单个修改,如在 JavaScript 修改多个样式时,尽量使用 css 选择器实现样式的集中变更

  • 使用 will-change 开启 GPU 加速,will-change 指定的属性使得浏览器可在元素属性真正发生变化之前提前做好对应的优化

  • 预先设定图片尺寸,避免图片资源加载完成后引发回流

防抖/节流

防抖:多次频繁触发执行操作,以 最后一次 为准,忽略中间过程

节流:在指定的时间间隔内,只允许 执行一次对应的操作

合理使用 防抖/节流 优化应用中的操作,比如 节流 可用于优化 滚动事件、模糊搜索等,防抖 可用于优化一些按钮点击操作等。

Web Worker

JavaScript 是单线程的,如果存在需要大量计算的场景(如视频解码),UI 线程就会被阻塞,甚至浏览器直接卡死。

Web Worker 可以使脚本运行在新的线程中,它们独立于主线程,可以进行大量的计算活动,而不会影响主线程的 UI 渲染,但不能滥用 Web Worker 。

虚拟列表

最常用的还是 分页加载 的方式:

  • 基于 table 表格的渲染,只会渲染固定数量的 DOM

  • 基于 上拉加载 列表的渲染,随着加载数据的增多,对应的 DOM 节点也会增多,达到某个限制页面一定会发生卡顿

虚拟列表 核心就是固定渲染的 DOM 数,通过动态切换数据内容实现视图的更新,并保证文档中真实 DOM 的数量不随着数据量增大而增大(其实和 table 分页很像,但它支持滚动)。

大文件分片上传

大部分的项目总少不了文件上传功能,但对大文件的上传还是有必要进行优化,所谓的 断点续传秒传 都要基于 分片上传 这个核心功能。

Excel 导入/导出

针对 Excel 导入/导出 的功能相信很多人第一印象是后端的活,但大多数情况下,后端接口的处理速度会受各种影响,导致速度方面不是很理想,有时候也是需要前端来进行优化处理的,比如导入时前端不发送文件只发送解析后的 JSON 数据,导出时不需要单独发送额外接口,直接使用当前展示数据实现导出等。

Vue 项目的优化

这部分内容相信大家都不陌生,下面就简单列举一些内容(包括但不限于):

  • 减少响应式数据的生成,对于纯展示、又需要使用在 template 模板中使用的数据,可使用 Object.freeze() 进行冻结,避免被转为 不必要的响应式数据

  • Vue 组件初始化是比较损耗性能的,使用 函数式组件 减少组件初始化的过程,适用于实现没有业务逻辑只展示内容的简单组件

  • 合理使用 v-show 和 v-if、为 v-for 组件设定唯一 key(非 index)、v-for 和 v-if 不要一起使用等

  • 使用 KeepAlive 复用组件,避免组件重复的创建、销毁带来的性能损耗

  • 使用 () => import(xxx) 方式实现路由懒加载

  • 使用 ESM 的方式封装自定义工具库等

  • 针对第三方库做到按需引入

  • 合理使用闭包,避免造成内存泄漏

  • 及时清除组件中的副作用,比如 setTimeout、setInterval、addEventListener 等

总结

以上优化方案对应到 上一篇 中提到的性能指标,如下:

  • 首字节达到时间(Time to First Byte,TTFB

  • 首次绘制(First Paint,FP

  • 首次内容绘制(First Contentful Paint,FCP

  • 首屏时间 / 最大内容绘制(Largest Contentful Paint, LCP

  • 累积布局偏移(Cumulative Layout Shift, CLS)

  • 首次输入延迟(First Input Delay, FID

关键资源越早到达客户端,证明 TTFB 时间越短,而这也能间接的减少 FP 和 FCP 的时间;对资源进行了压缩处理意味着能够尽可能提升 LCP 的时间;减少了页面的 回流/重绘 就能使得 CLS 的数值越小,视图越趋于稳定;FID 是一个用于跟踪浏览器对用户输入做出反应之前的延迟时间的指标,包括点击和敲击,保证资源的快速加载和页面尽早渲染,其对应的数值就越小,视图响应就越快。

最后

前端性能优化 的范围实在太大,以上列举的优化主要围绕着 资源加载、页面渲染/交互 两个大的方向,而具体的优化方案其实有很多(包括但不限于上述内容),很多内容随着关注的方向不同而不同。

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

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

相关文章

C++基础(6)——类和对象(4)

前言 本文主要介绍了C中运算符重载的基本知识。 4.5.1:加号运算符重载(成员函数和全局函数都可实现) 运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 1:成员…

管理类联考——写作——素材篇——论说文——写作素材03——志篇:逆境·考验04——志篇:初心

管理类专业学位联考 (写作能力) 论说文素材 03——志篇:逆境考验 论文说材料: 逆境是天才的进身之阶;信徒的洗礼之水;能人的无价之宝; 弱者的无底之渊。 ——巴尔扎克 一:道理论据 不是一番寒彻骨,怎得…

【Azure】微软 Azure 基础解析(九)Azure 标识、身份管理、Azure AD 的功能与用途

本系列博文还在更新中,收录在专栏:「Azure探秘:构建云计算世界」 专栏中。 本系列文章列表如下: 【Azure】微软 Azure 基础解析(三)云计算运营中的 CapEx 与 OpEx,如何区分 CapEx 与 OpEx 【A…

测量设备频宽范围选择要素—系统响应速度

系统响应速度是输入信号经过电压/电流驱动系统输出响应的幅值升到终值过程的斜率,而上升时间是系统响应速度的一种度量,上升时间越短,响应速度越快。 由一阶系统响应定义中,稳定的一阶系统上升时间 定义是响应从终值10%上升到终值…

git常用命令合集(建议收藏)

1、git init将本文件夹初始化成一个本地git仓库 2、git clone'xxx'将github上的远程克隆到本地 3、git add [file1] [file2] 添加文件到暂存区,包括修改的文件、新增的文件 4、git add [dir] 添加目录到暂存区,包括子目录 5、…

java 类之间相互引用实例探索

本文记录一下自己对类之间相互引用的探索,如有错误,希望不吝赐教 问题一:类之间相互引用依赖会不会引用死循环 不会,例如:A类中声明一个B类的引用,B类中也声明一个A类的引用,因为类之间的引用相…

TCP为什么要三次握手与四次分手?

概要 TCP协议是五层协议中运输层的协议,下面依赖网络层、链路层、物理层,对于一个报文想发到另一台机器(假设是服务器)上对等层,每一个所依赖的层都会对报文进行包装,例如TCP协议就依赖网络层的IP协议,所以发送的报文会…

【数据库数据恢复】SQL Server数据表结构损坏的数据恢复案例

数据库故障&分析: SQL server数据库数据无法读取。 经过初检,发现SQL server数据库文件无法被读取的原因是因为底层File Record被截断为0,无法找到文件开头,数据表结构损坏。镜像文件的前面几十M空间和中间一部分空间被覆盖掉…

大专毕业,干了 3 年外包,废了····

如果不是女朋友和我提分手,我估计到现在还是外包公司呆着 大专生,19年通过校招进入湖南某软件公司,干了接近3年的点点点(功能测试),今年年初,感觉自己不能够在这样下去了,长时间呆在…

VSCode借助Remote-SSH扩展,远程调试linux系统的机器人

本文主要介绍使用VSCode借助Remote-SSH扩展,远程调试linux系统的机器人的方法 在我之前的文章: ROS主机搭建NFS服务器,虚拟机通过挂载访问及修改主机文件 中介绍了采用挂载到的方式进行远程调试的方法,本文将介绍另一种方法&#…

汽车三高试验离不开的远程试验管理平台——TFM

一 背景 众所周知,车辆在量产之前都要经过长时间的耐久性试验和多种汽车适应性或法规试验。道路试验就是在汽车上装设测试仪表和施加模拟载荷,并按实际使用条件来进行测试。此外,在实际试验场地和试验时间上也是有一定规定的。企业根据不同的…

导出符号表和字符设备驱动

目录 1. 导出符号表 1.1. 应用场景:驱动B想要使用驱动A的函数 1.2. 函数解析 1.3. 撰写提供者.c文件 1.4. 撰写提供者makefile文件 1.5. 执行makefile文件生成Module.symvers 1.6. 撰写调用者.c文件 1.7. 撰写调用者的makefile 1.8. 调用验证 2. 字符设备…

springCloud对接kafka+websockt消息中心

1.网关没有配置message和websockt的路由 2.message启动报错,线上zookeeper启动失败导致 3.message配置文件参数读取不到,原因:message_dev.yml 正确名称 message-dev.yml 4.线上websockt地址连接失败,原因:白名单没…

Cisco MPLS VPN Option C2

无RR 一、拓扑 环境:AR1-AR8各有loopback0接口分别是1.1.1.1 2.2.2.2 二、配置步骤 1、配置AS100和AS200的底层网络,这里使用OSPF配置 2、配置AS内使用LDP协议分发标签 3、ASBR之间建立EBGP邻居关系,相对端通告路由时携带标签,互联…

确保消息不会丢失

现在主流的消息队列产品都提供了非常完善的消息可靠性保证机制,完全可以做到在消息传递过程中,即使发生网络中断或者硬件故障,也能确保消息的可靠传递,不丢消息。 绝大部分丢消息的原因都是由于开发者不熟悉消息队列,没…

第一章:软件工程师必备的硬件基础

目录 1、软件工程师需要具备的知识 2、计算机的组成 3、操作系统 4、BIOS的相关知识 1、软件工程师需要具备的知识 问题一:运维工程师、实施工程师是啥? 运维工程师负责服务的稳定性,确保服务可以不间断地为用户提供服务。 实施工程师负…

CmakeList使用笔记

cmake是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。 Cmake的所有语句都写在一个CMakeLists.txt的文件中,Cmake运行之后就会产生我们想要的makefile文件,然…

【Jquery】Jquery实现页面嵌套到客户项目框架里面,不需要登录,获取cookie并直接展示首页:

文章目录 一、效果图:二、实现思路:三、实现代码: 一、效果图: 二、实现思路: 需求&#xff1a;嵌套到别的客户项目框架里面&#xff0c;不需要登录直接展示首页 实现&#xff1a;在打开页面前&#xff0c;获取登录cookie&#xff0c;然后再打开页面 三、实现代码: <!DOCTYP…

63、基于51单片机数字频率计NE555数码管显示系统设计(程序+原理图+Proteus仿真+参考论文+开题报告+任务书+元器件清单等)

摘 要 近年来随着计算机在社会领域的渗透和大规模集成电路的发展&#xff0c;单片机的应用正在不断地走向深入&#xff0c;由于它具有功能强&#xff0c;体积小&#xff0c;功耗低&#xff0c;价格便宜&#xff0c;工作可靠&#xff0c;使用方便等特点&#xff0c;因此越来越…

世界名酒商城元宇宙 中国4大“惨败酒

大家平时买白酒都怎么选择呢&#xff1f;一般都选择平时广告做得多&#xff0c;耳熟能详的大品牌&#xff0c;或者是直接听导购的买酒&#xff0c;毕竟那么贵的价格酒不可能不好&#xff0c;实际上这种买酒方式虽然不能说错吧&#xff0c;但是极容易错过很多好酒。 白酒市场上就…