首页 > 其他分享 >笔记摘要

笔记摘要

时间:2024-10-14 14:24:30浏览次数:1  
标签:缓存 渲染 摘要 笔记 loader 使用 CSS 加载

8.12
MessageChannel
MessageChannel 常用于主线程与 Web Worker 线程之间的通信,尤其是当需要在Worker完成计算或处理后,向主线程报告结果时
0. 避免宏任务队列堵塞:在某些场景下,使用setTimeout或Promise来延迟执行可能不够精确或会导致不必要的延迟。通过MessageChannel,可以在当前事件循环的微任务队列之外安排任务,避免阻塞UI线程。
0. 跨源Iframe通信:虽然通常使用postMessage直接进行跨iframe通信,但结合MessageChannel可以提供更安全和灵活的通信方式,尤其是在需要持续的双向通信时

Vue 和 React
0. 不可变数据VS可变数据
0. 双向数据 单向数据流
0. 函数式编程 渐进式开发体验
0. 引用组件重新渲染 组件为根目录,默认全部重新渲染

类组件与函数组件
类组件是基于面向对象编程的,它主打的是继承、生命周期等核心概念;而函数组件内核是函数式编程,主打的是 immutable、没有副作用、引用透明等特点。
渲染性能上:shouldComponentUpdate React.memo 
 Hooks  比原先更细粒度的逻辑组织与复用 时间切片与并发模式

react异常
错误边界(Error Boundary)
Window 错误监听事件  window.addEventListener('error')
useEffect的错误处理

懒渲染 react-visibility-observer 进行监听
结合React.lazy和Suspense使用动态import(),可以实现组件级别的懒加载

Scheduler(调度器)
负责调度组件的渲染更新任务 车道模型 执行顺序
Reconciler(协调器)
Fiber节点的生成 Fiber任务
任务的执行与中断(Scheduler)
Commit阶段
Reconciler会生成一棵新的workInProgressFiber树+逐渐diff

 React18有哪些更新
setState自动批处理
• 17中只有react合成事件会进行批处理,legacy模式;
• 18中所有事件都进行批处理,提高了性能,concurrent模式。
支持并发模式的渲染
去掉了对IE浏览器的支持
flushSync,用于退出批量更新
react组件返回值更新
• 17中返回空组件只能返回null,返回undefined会报错
• 18中支持null和undefined
支持useId(在服务器和客户端生成相同的唯一一个id,避免hydrating的不兼容)
新增hooksuseInsertionEffect:只建议在css in js库中使用,在dom生成之前执行,在useLayoutEffect之前,一般用于提前注入脚本
useSyncExternalStore:解决外部数据撕裂问题
Suspense不再需要fallback捕获
并发模式

 

undefined:
擅长领域:低代码建设,可视化搭建,性能优化

undefined:
医疗健康数据可视化平台 - 医疗研究机构
在某知名医疗研究机构,我参与设计并实施了一个低代码医疗健康数据可视化项目。该平台整合了来自不同医院、电子病历系统和公共卫生数据库的海量数据,通过低代码工具快速构建了交互式仪表板和分析报告,支持研究人员实时监控疫情趋势、疾病分布、药物疗效评估等关键指标。低代码的灵活性使我们能够快速迭代,根据研究需求调整数据模型和可视化界面。该项目极大地加速了研究进程,助力多项研究成果提前发布,对公共卫生产生了积极影响

undefined:
自定义递增数字的hook useIncreateNumber useFormValidate..

 

8.13

forwardRef + useImperativeHandle(自定义暴露内容)传递组件ref到父组件
const ChildComponent = forwardRef((props, ref) => {
const internalState = useRef(0);

useImperativeHandle(ref, () => ({
increment: () => {
internalState.current += 1;
},
decrement: () => {
internalState.current -= 1;
},
reset: () => {
internalState.current = 0;
},
getState: () => internalState.current,
}));

return <div>{`Child State: ${internalState.current}`}</div>;
});

Babel原理
解析=>as tree =>插件转换=>生成新代码以及Source Maps原代码

并发模式 react
React 16.6引入
根据应用的状态和用户交互智能地调度渲染任务
分片渲染 挂起和恢复(Suspense)
错误发生时,React可以暂停渲染过程,给予应用机会去恢复或优雅地展示错误信息,而不是立即崩溃。
可中断的渲染 同步与异步渲染的混合

函数组件与类组件的区别:
0. 类组件需要声明constructor,函数组件不需要
0. 类组件需要手动绑定this,函数组件不需要
0. 类组件有生命周期钩子,函数组件没有
0. 类组件可以定义并维护自己的state,属于有状态组件,函数组件是无状态组件
0. 类组件需要继承class,函数组件不需要
0. 类组件使用的是面向对象的方法,封装:组件属性和方法都封装在组件内部 继承:通过extends React.Component继承;函数组件使用的是函数式编程思想

React 路由
监听URL(通常是popstate事件和History API的监听)=>匹配路由规则=>找到渲染组件,卸载旧的渲染新的到指定的容器


Fiber 架构有两个阶段,render 阶段就是负责构架 Fiber 对象和链表,而 commit 阶段就是负责去构建 DOM

• Scheduler(调度器);调度任务的优先级,高优任务优先进入Reconciler;代替requestIdleCallback
• Reconciler(协调器);负责找出变化的组件 Fiber 打标记
• Renderer(渲染器);负责将变化的组件渲染到页面上

 

8.14

bug场景: 项目列表每次导出的数据都不是查询之后的数据
原先代码实现: 查询条件对象使用useMemo记忆,依赖项是查询的每个字段。导出执行的函数是使用useCallback的记忆函数,空依赖项。函数里引用了useMemo返回的查询条件,结果出现该问题。
原因:
• 初始渲染时,useMemo根据其依赖计算一个值,useCallback创建一个引用该useMemo返回值的回调函数。
• 当useMemo的依赖改变时,它会计算新的值,但由于useCallback的依赖数组是空的,它不会创建新的回调函数,仍然保持对初次渲染时useMemo返回值的引用。
• 这就解释了为什么在后续调用useCallback的回调时,即使useMemo内部的值已经因为依赖变化而更新,回调函数内部使用的始终是最初计算的那个useMemo返回值。因为回调函数保持不变,它内部封闭的环境(包括对useMemo返回值的引用)也就保持不变。

解决办法:在useCallback的依赖数组中包含对useMemo返回值的引用。这样,当useMemo的值因为依赖变化而更新时,useCallback也会得到通知并创建一个新的回调函数,确保每次调用时都能获取到最新的useMemo结果

扩展:useCallback回调函数中除了memo返回值,其他hook如:useCallback 函数也要添加到依赖项中去


useMemo返回值的引用指向堆中一个对象的引用:
在JavaScript中,基本类型(如数字、字符串、布尔值等)是存储在栈中的,而复杂类型(如对象、数组、函数等)则存储在堆中,栈中存放的是指向这些堆中数据的指针。当你使用useMemo计算并返回一个复杂类型的值(如对象、数组)时,这个返回值实际上是堆内存中的一个地址引用,这个引用被保存在函数组件的作用域或相关的React内部状态中

如果某个值的变化应当触发useMemo重新计算,那么这个值应当被列在useMemo的依赖数组中;同样,如果useCallback的逻辑依赖于某个状态或prop,这些也应该被列为依赖项


React 算法之深度优先遍历
最主要的使用时在ReactElement和fiber树的构造过程. 其次是在使用context时, 需要深度优先地查找消费context的节点.
function dfs(node) {
const stack = [];
stack.push(node);
// 栈顶元素还存在, 就继续循环
while ((node = stack[stack.length - 1])) {
if (node.visited) {
console.log('回溯阶段: ', node.name);
// 回溯完成, 弹出该元素
stack.pop();
} else {
console.log('探寻阶段: ', node.name);
node.visited = true;
// 利用栈的先进后出的特性, 倒序将节点送入栈中
for (let i = node.children.length - 1; i >= 0; i--) {
stack.push(node.children[i]);
}
}
}
}

• Fiber 树由链表构成,节点间通过 return(父节点)、child(第一个子节点)、sibling(下一个兄弟节点)相连。
• 当前视图对应的 Fiber 树称为 current 树,每次协调发起,都会构建新的 workInProgress 树,并在结束时替换 current 树。
• Fiber 树的遍历方式是深度优先遍历,向下的过程由 beginWork 发起,向上的过程由 completeUnitOfWork 发起。beginWork 每次只向下一步,completeUnitOfWork 则每次向上若干步(由其内部若干个一步循环达成)。
• Fiber 树是边构建边遍历的,构建在 beginWork 向下过程中发起。
• Fiber 树的 Diffing 策略体现在构建过程中:父节点已复用、key 和 type 相同是节点复用的基本条件;子节点 Diffing 从易向难,单节点 Diffing —> 多节点末尾增删(一轮循环) —> 多节点其他情况(二轮循环)。
• Diffing 的结果,诸如节点的删除、新增、移动,称为 effect,以 effectTag 的形式挂在节点上。
• completeUnitOfWork 的内部循环会自底向上收集 effect,不断把有 effectTag 的子节点和自身向上合并到父节点的 effectList 中,直至根节点。effectList 是个链表。
• 宿主相关组件节点会把宿主实例挂到 stateNode 上,间接调用宿主方法对其完成创建、更新,由此也会产生 effectTag。

 

8.15

async defer异步下载
async 不保证顺序,下载完立即执行,暂停解析
defer 保证执行顺序,下载完需要等到页面解析后,DOMContentLoaded事件触发之前执行


浏览器
渲染引擎-浏览器引擎
• Chrome 和 Edge 使用 Blink 引擎(原本是Webkit的一个分支)。
• Safari 使用 WebKit 引擎。
• Firefox 使用 Gecko 引擎,现在正在转向新的Quantum项目,特别是GeckoView。
• Internet Explorer 使用 Trident(老版本)和 EdgeHTML(Edge旧版,已不再维护)。

渲染层(也称作布局层或图形层)和合成层
合成层是浏览器渲染引擎中的一种优化策略,它将页面分割成多个独立的图层,并在GPU上进行组合(composite)
• 图层划分:当元素具有某些特定属性,如transform、opacity、filter(部分情况下)或被指定为will-change属性时,浏览器会将其提升为独立的合成层。
• GPU加速:合成层能够在GPU上独立渲染,然后由浏览器合成这些图层来形成最终画面。这减少了重排和重绘的需求,提高了动画的流畅性。
• 并发处理

布局: 重排(Reflow)或回流 位置和大小 布局树 绘制指令 分层信息(哪些可以提升成合成层)

绘制:元素信息转换成实际屏幕上的像素颜色值数据 合成层,它的绘制记录会被转化为纹理(Texture),存储在GPU内存中 位图/像素数据(绘制记录被转换成实际的位图数据,即像素颜色值的集合) 纹理(对于合成层)

光栅化:属于绘制阶段里面。绘制命令随后被转换为实际的像素数据。它将绘制指令转换为具体的像素阵列。对于文本,这可能包括将字体形状映射到像素网格;对于形状和图像,则涉及抗锯齿处理和颜色空间转换。光栅化过程的直接结果是生成一帧的像素数据,即每个像素点的颜色值。这些数据构成了屏幕上用户可以看到的实际图像。

合成:对于被提升为合成层的图层,它们各自的位图或图块在GPU内存中被管理。合成器(Compositor)负责将这些图层按照正确的顺序和位置叠加在一起,形成最终的页面视图。这个过程可以在独立的合成线程中进行,与主渲染进程并行工作,从而减少阻塞和提升性能

显示:合成后的位图被传递到显示器上显示 帧缓冲区(framebuffer)的更新
渲染层通过布局、绘制、光栅化生成位图,然后在合成阶段将这些位图在GPU上组合,最后输出到屏幕上


JavaScript引擎
• V8:Chrome 和 Edge 浏览器使用。
• JavaScriptCore(也被称作Nitro或SquirrelFish):主要用于Safari。
• SpiderMonkey:Firefox 使用。
• Chakra(后来的ChakraCore):曾经用于Internet Explorer和早期的Microsoft Edge

网络请求“引擎”
用户界面(UI)“引擎”
数据存储“引擎”


防抖 延迟执行,只执行最后一次触发
节流 限制执行频率 一段时间内 只执行一次

webpack
入口
loader 解析文件 专注于转换单个文件的内容,遵循从右到左的执行顺序
plugin 扩展功能,构建过程中特定事件触发,插件通过在特定的生命周期钩子(hooks)注册回调函数来监听事件,从而在合适的时机执行
出口

常见Loader
0. babel-loader: 用于将ES6+语法转换为浏览器兼容的JavaScript代码。
0. ts-loader 或 awesome-typescript-loader: 将TypeScript编译为JavaScript。
0. css-loader 和 style-loader: 用于加载和插入CSS到DOM中。css-loader负责解析CSS文件中的@import和url(),而style-loader则将CSS插入到页面中。
0. sass-loader 或 less-loader: 分别用于将Sass或Less预处理器编写的样式转换为CSS。
0. file-loader 和 url-loader: 用于处理文件资源,如图片、字体文件等。file-loader将文件发送到输出目录,并返回URL,而url-loader可以在一定阈值下将文件转换为base64编码直接嵌入代码中。
0. image-webpack-loader: 对图片进行压缩和优化。
0. eslint-loader: 在构建过程中运行ESLint检查代码质量。
•  thread-loader 多进程去打包 放置在其他 loader 之前, 那 thread-loader 之后的 loader 就会在一个单独的 worker 池(worker pool)中运行
• HappyPack
常见插件
0. HtmlWebpackPlugin: 自动创建HTML文件,并将打包生成的JS文件自动注入到HTML中。
0. MiniCssExtractPlugin: 将CSS从JS中提取出来,生成单独的CSS文件,有利于缓存和加载速度。
0. UglifyJsPlugin 或 TerserWebpackPlugin: 用于压缩JavaScript代码,减少文件体积。
0. CleanWebpackPlugin: 在每次构建前清空输出目录。
0. CopyWebpackPlugin: 复制静态资源到输出目录。
0. DefinePlugin: 在编译时定义全局常量,可用于环境变量替换。
0. HotModuleReplacementPlugin: 实现模块热替换(HMR),在开发过程中无需刷新页面即可实时看到代码更改的效果。
0. OptimizeCssAssetsWebpackPlugin: 压缩和优化CSS资产。
0. BundleAnalyzerPlugin: 分析打包后资源的大小,帮助识别优化点。
• HardSourceWebpackPlugins 提升二次构建及后续构建的速度

多进程/多实例+压缩类
• terser-webpack-plugin 开启 parallel 参数,使用多进程并行运行 (推荐使用这个,支持 ES6 语法压缩)
• parallel-uglify-plugin 插件
• uglifyjs-webpack-plugin 开启 parallel 参数

分割打包
• Webpack 4+:SplitChunksPlugin
• Webpack 3:CommonsChunkPlugin

缓存
cache-loader 性能开销大的 loader 之前添加此 loader
use: ["cache-loader", ...loaders]

多进程/多实例
• thread-loader 高开销的 loader 中使用
• parallel-web-pack 多入口点的项目
• HappyPack。对 file-loader、url-loader 支持的不友好

 

8.16

HotModuleReplacementPlugin
webpack-dev-server (开启一个HTTP服务器)=> (通过HotModuleReplacementPlugin向入口chunk中注入)HMR客户端代码(监听模块变化)=>WebSocket=> (通信)浏览器

HardSourceWebpackPlugin
提升二次构建及后续构建的速度。它通过缓存上一次构建过程中的一些中间结果,比如模块解析、loader处理结果等
缓存(loader处理输出、解析后的模块、插件处理结果等)
增量构建(项目再次构建时,通过缓存,复用之前构建的结果。如果某个模块或其依赖没有发生改变,那么这部分的编译工作就会被跳过,直接使用缓存中的结果)

thread-loader 适用提高那些CPU密集型loader
推荐用于:
babel-loader(Babel转换JavaScript代码是一个CPU密集型任务)
ts-loader(TypeScript编译也是耗时的)之前,其他重型loader: 任何执行复杂处理或转换的loader,如图像优化、模板编译等,都可以考虑使用thread-loader来加速
不建议:
轻量级loader 资源消耗大 异步执行,不能保证loader执行顺序


SplitChunksPlugin
Webpack的一个内置插件,用于代码拆分,通过optimization.splitChunks来配置。减少初始加载时间 缓存 并行加载 将公共的、可复用的代码分离到单独的chunk。 CommonsChunkPlugin已废弃,被SplitChunksPlugin取代


terser-webpack-plugin
压缩JavaScript代码的插件。配置optimization.minimizer来使用 Webpack 5及以上版本已内置,parallel 参数开启多线程压缩

https://github.com/facebook/create-react-app

Parcel
一款快速、零配置的Web应用打包工具。它旨在简化前端开发流程,通过提供自动化配置、快速冷启动编译、热模块替换(HMR)等功能

0. 零配置:Parcel 自动处理诸如模块打包、代码转换(如Babel)、样式处理(Sass、Less等)、图片优化、代码拆分等任务,无需复杂的配置文件。
0. 快速启动:Parcel 采用多进程编译模型,每个处理器都有自己的进程,这使得它在初次启动和后续编译时都非常迅速。
0. 热模块替换(HMR):自动启用HMR,允许在开发过程中实时查看代码变更,而无需刷新浏览器。
0. 全面的文件类型支持:Parcel 内置支持处理各种现代Web开发中的文件类型,包括JS、CSS、HTML、图片、SVG、字体等。
0. tree shaking:自动移除未使用的代码,帮助减小最终打包文件的大小。
0. 自动源码映射:为生产环境和开发环境生成源码映射,便于调试。
0. 环境变量:支持.env文件,方便管理不同环境下的配置。
0. 优化的生产构建:在生产环境中,Parcel会自动进行一系列优化,包括代码压缩、资源最小化等,以提高性能。


react-router-dom是React应用中最常用的路由库之一,它是react-router的一个子集
• <BrowserRouter>: 这是最常用的路由器组件,它使用HTML5的历史API(pushState, replaceState)来管理导航,提供了友好的URL体验且不需要 hashes (#)。
• <Route>: 定义了路径与组件之间的映射关系。当URL匹配到定义的路径时,对应的组件会被渲染。
• <Switch>: 包裹一系列<Route>组件,确保只有一个与当前URL匹配的<Route>会被渲染。
useHistory, useLocation, useParams: React Hooks

Midway
Node.js 的企业级框架

 

8.17

DllPlugin和HardSourceWebpackPlugin: DllPlugin可以将第三方库预先打包成单独的文件,减少构建时间。HardSourceWebpackPlugin可以缓存中间文件,加速后续构建过程

使用现代的压缩工具,如Brotli和Gzip,来对静态资源进行压缩

webpack和vite差异:
在开发环境中,Webpack 是先打包再启动开发服务器,而 Vite 则是直接启动,然后再按需编译依赖文件
Webpack 是基于 Node.js 构建的,而 Vite 则是基于 esbuild ,Go 语言编写的,Go 语言是纳秒级别的,而 Node.js 是毫秒级别的
热更新的处理
 Webpack 重新编译 vite 需要让浏览器重新请求该模块即

Monorepo 
项目代码管理方式,指单个仓库中管理多个项目
渐进式架构方案

ESLint
源代码字符串通过Parser解析成AST,之后ESLint就可以通过AST提供的信息与Rules对比,从而给出代码规范分析的结果,指出错误,并且还可以自动修复

Babel 的原理就是将 JavaScript 源代码转换为抽象语法树(AST),然后对 AST 进行转换

npm install
读取 package.json 文件,该文件列出了项目所需要的依赖。
根据 package.json 中的依赖信息以及 node_modules 目录状态,npm 会决定哪些模块需要下载和安装。
npm 会查看每个模块的可用版本,并选择符合 package.json 中指定版本范围的最新版本进行安装。
下载所需模块到本地的 node_modules 目录。
如果模块包含子模块(package.json 中 dependencies 或 devDependencies 中的模块),则递归执行上述步骤安装这些子模块


PostCss 做的是类似的事情:它可以编译尚未被浏览器广泛支持的先进的 CSS 语法,还可以自动为一些需要额外兼容的语法增加前缀。


webpack打包优化:
一、分析打包速度
在webpack构建过程中,实际上耗费时间大多数用在 loader 解析转换以及代码的压缩中;speed-measure-webpack-plugin 测量你的 webpack 构建期间各个阶段花费的时间

二、分析影响打包速度环节
搜索时间
——优化 loader 配置
使用 Loader 时可以通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件
——优化 resolve.module 配置
resolve.modules 用于配置 webpack 去哪些目录下寻找第三方模块
——优化 resolve.alias 配置
resolve.alias 配置项通过别名来把原导入路径映射成一个新的导入路径,减少耗时的递归解析操作
———优化 resolve.extensions 配置
在导入语句没带文件后缀时,webpack 会根据 resolve.extension 自动带上后缀后去尝试询问文件是否存在
• resolve.extensions 列表要尽可能的小,不要把项目中不可能存在的情况写到后缀尝试列表中。
• 频率出现最高的文件后缀要优先放在最前面,以做到尽快的退出寻找过程。
• 在源码中写导入语句时,要尽可能的带上后缀,从而可以避免寻找过程
————优化 resolve.mainFields 配置
有一些第三方模块会针对不同环境提供几分代码。 例如分别提供采用 ES5 和 ES6 的2份代码,这2份代码的位置写在 package.json 
webpack 会根据 mainFields 的配置去决定优先采用那份代码
webpack 会按照数组里的顺序去 package.json 文件里寻找,只会使用找到的第一个。
假如你想优先采用 ES6 的那份代码,可以这样配置:
mainFields: ['jsnext:main', 'browser', 'main']
—————优化 module.noParse 配置
module.noParse 配置项可以让 Webpack 忽略对部分没采用模块化的文件的递归解析处理,这样做的好处是能提高构建性能。 原因是一些库,例如 jQuery 、ChartJS, 它们庞大又没有采用模块化标准,让 Webpack 去解析这些文件耗时又没有意义

详细配置
// 编译代码的基础配置
module.exports = {
// ...
module: {
// 项目中使用的 jquery 并没有采用模块化标准,webpack 忽略它
noParse: /jquery/,
rules: [
{
// 这里编译 js、jsx
// 注意:如果项目源码中没有 jsx 文件就不要写 /\.jsx?$/,提升正则表达式性能
test: /\.(js|jsx)$/,
// babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
use: ['babel-loader?cacheDirectory'],
// 排除 node_modules 目录下的文件
// node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: /node_modules/,
},
]
},
resolve: {
// 设置模块导入规则,import/require时会直接在这些目录找文件
// 可以指明存放第三方模块的绝对路径,以减少寻找
modules: [
path.resolve(`${project}/client/components`),
path.resolve('h5_commonr/components'),
'node_modules'
],
// import导入时省略后缀
// 注意:尽可能的减少后缀尝试的可能性
extensions: ['.js', '.jsx', '.react.js', '.css', '.json'],
// import导入时别名,减少耗时的递归解析操作
alias: {
'@compontents': path.resolve(`${project}/compontents`),
}
},
};

 

解析时间(单线程逐文件处理)
—— 开启多线程打包
——1. thread-loader(webpack4 官方推荐 专门处理loader)
——2. HappyPack 多进程打包(Webpack 5 +不推荐 内置通过 thread-loader 和 worker-loader)
通常,你会为特定类型的加载器(如 Babel)设置一个 HappyPack 实例
// ... 其他配置 ...
module: {
rules: [
{
test: /\.js$/,
use: ['happypack/loader?id=babel'], // 使用 HappyPack 处理 .js 文件
exclude: /node_modules/,
},
// ... 其他规则 ...
],
},
plugins: [
new HappyPack({
id: 'babel', // 这个id需要与上面的use中的id匹配
loaders: [{
loader: 'babel-loader',
options: { // 传递给 babel-loader 的选项
presets: ['@babel/preset-env'],
},
}],
threadPool: HappyPack.ThreadPool({ size: 4 }), // 线程池大小,默认是 os.cpus().length
}),
// ... 其他插件 ...
],
当项目较小时,多线程打包反而会使打包速度变慢

压缩时间(分析处理AST)
webpack3 启动打包时加上 --optimize-minimize 
ParallelUglifyPlugin多线程压缩(4+中被废弃 不支持 ES6 +)
webpack4 中 webpack.optimize.UglifyJsPlugin 已被废弃
terser-webpack-plugin(4+ 推荐)

二次打包时间
———合理利用缓存(初始慢)
ache-loader (放其他性能大loader之前)
HardSourceWebpackPlugin 或 babel-loader 的 cacheDirectory


DllPlugin
提升构建速度的插件,将一些不经常改变的代码(如第三方库)预先打包成一个或多个(DLL),从而在后续的构建过程中避免重新打包这些库


npm 
安装慢 每个依赖的每个版本都会被安装一次,磁盘占用高
tnpm 镜像
pnpm
安装快 占磁盘不高 但是,推广程度不高 兼容性

 

8.20

样式篇
postcss-loader
PostCSS 相当于 CSS 的 Babel
postcss-cssnext 体验未来css特性
cssnano这样的插件进行CSS代码压缩、去除无用代码等优化
{
// 使用style-loader将CSS注入到DOM中(或MiniCssExtractPlugin.loader抽取到文件)
'style-loader',
// 使用css-loader处理CSS @import 和 url()
'css-loader',
// 使用resolve-url-loader修正CSS中的URL
{
loader: 'resolve-url-loader',
options: {
attempts: 1, // 尝试解析的次数,默认1次
},
},
{
loader: "postcss-loader",
options: {
plugins: () => ([
require("autoprefixer"), //自动加前缀
require('cssnano')({ preset: 'default' }), // CSS压缩
require('postcss-preset-env')({ browsers: 'last 2 versions' , '>1%', 'iOS 7'}), // 转换现代CSS语法
require("precss") // 使用类似sass标签
])
}
}
}


css-loader 默认处理 相对导入
参数 importLoaders :对所找到的导入文件执行 css-loader 之前需要执行多少个 loader 。您通过 @import 语句从 CSS 导入其他 CSS 文件,并希望通过特定的 loader 处理导入 很重要

resolve-url-loader
处理CSS文件中引用的相对URL路径

MiniCssExtractPlugin
生成单独的 CSS 包,只会作用于编译阶段,它不适用于热模块更换(HMR)

PurifyCSS uncss. 去除未使用样式

图像篇
url-loader
在使用 limit 选项 达到绝对限制后的情况下,url-loader默认将可能的附加选项传递给 file-loader,如果你想使用另一个 loader , fallback: "some-loader"
不要同时在图像上同时应用两个 loader!如果 url-loader limit 不够,请使用 include 字段进一步控制

加载 SVG
{
test: /\.svg$/,
use: "file-loader",
}
react-svg-loader svg-url-loader svg-sprite-loader

优化图像
压缩图像 image-webpack-loader、svgo-loader(专用于 SVG)或 imagemin-webpack-plugin 应用于最后数据  放use 列表中的最后一个
利用 srcset
resize-image-loader 和 responsevie-loader

使用图片占位符
image-trace-loader
lqip-loader

引用图像
 babel-plugin-transform-react-jsx-img-import
css-loader

字体篇
url-loader 和 file-loader
{
// 除了 .woff?v=1.1.1 这样的格式以外,还要匹配 woff2.
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: "url-loader",
options: {
// 限制为 50k. 超过它就生成独立的文件
limit: 50000,

// 设置 mimetype
// 如果没有这一项,默认会根据文件扩展名来获取
mimetype: "application/font-woff",

// 输出字体到文件夹
name: "./fonts/[name].[ext]",
publicPath: "../", // 输出时基于这个目录
}
},
},
注意优先级
@font-face {
font-family: 'myfontfamily';
src: url('./fonts/myfontfile.woff2') format('woff2'), url('./fonts/myfontfile.woff') format('woff'),
url('./fonts/myfontfile.eot') format('embedded-opentype'), url('./fonts/myfontfile.ttf') format('truetype');
/* 还可以添加你认为合适的其他格式 */
}
基于 SVG 生成字体文件
 webfonts-loader

使用字体图标
iconfont-webpack-plugin

脚本篇
Babel
 babel-loader babel-webpack-plugin
• plugins:babel 中使用的插件,这些插件可以控制如何转换代码
presets:babel 可以使用哪些新的语法特性,
babel-plugin-react  • babel-plugin-import
babel/plugin-transform-runtime
• @babel/preset-env:允许您为旧版浏览器支持某些语言特性。为此,您应该启用其 useBuiltIns 选项(设置 "useBuiltIns": true 或 "useBuiltIns": "usage")并安装 @babel/polyfill。您必须通过 import 或 entry(app: ["@babel/polyfill", PATHS.app])将其包含在项目中。@babel/preset-env 根据您选定的浏览器重写导入,并仅加载所需要的 polyfill。
• @babel/polyfill:会在全局范围内提供了像 Promise、Set 这样的对象,这会污染全局作用域,对于一些库的开发者来说这可能会造成影响,这时候可以使用 `@babel/plugin-transform-runtime 。它可以作为 Babel 插件启用,避免了全局变量污染的问题。
• babel-plugin-import:重写模块导入,以便您可以使用这样的形式(import { Button } from 'antd')来导入模块,而不必指出精准的路径

TypeScript
• ts-loader
• awesome-typescript-loader

环境变量
DefinePlugin webpack-conditional-loader

 

8.21
glob 强大的方式来匹配和选择文件
const glob = require('glob');

glob("**/*.js", function (err, files) {
console.log(files); // 打印所有.js文件的路径
});

样式篇
postcss-loader
PostCSS 相当于 CSS 的 Babel
postcss-cssnext 体验未来css特性
cssnano这样的插件进行CSS代码压缩、去除无用代码等优化
{
// 使用style-loader将CSS注入到DOM中(或MiniCssExtractPlugin.loader抽取到文件)
'style-loader',
// 使用css-loader处理CSS @import 和 url()
'css-loader',
// 使用resolve-url-loader修正CSS中的URL
{
loader: 'resolve-url-loader',
options: {
attempts: 1, // 尝试解析的次数,默认1次
},
},
{
loader: "postcss-loader",
options: {
plugins: () => ([
require("autoprefixer"), //自动加前缀
require('cssnano')({ preset: 'default' }), // CSS压缩
require('postcss-preset-env')({ browsers: 'last 2 versions' , '>1%', 'iOS 7'}), // 转换现代CSS语法
require("precss") // 使用类似sass标签
])
}
}
}


css-loader 默认处理 相对导入
参数 importLoaders :对所找到的导入文件执行 css-loader 之前需要执行多少个 loader 。您通过 @import 语句从 CSS 导入其他 CSS 文件,并希望通过特定的 loader 处理导入 很重要

resolve-url-loader
处理CSS文件中引用的相对URL路径

MiniCssExtractPlugin
生成单独的 CSS 包,只会作用于编译阶段,它不适用于热模块更换(HMR)

PurifyCSS uncss. 去除未使用样式

critters-webpack-plugin 自动提取 关键CSS,并内联到HTML中,同时将剩余的CSS分离到外部文件

isomorphic-style-loader (服务器端渲染) 提供一致的CSS加载体验,确保样式在首次渲染时就已应用,从而避免了无样式内容闪烁(FOUT, Flash of Unstyled Content)或样式闪现(FOUC, Flash of Unstyled Content)的问题

图像篇
url-loader
在使用 limit 选项 达到绝对限制后的情况下,url-loader默认将可能的附加选项传递给 file-loader,如果你想使用另一个 loader , fallback: "some-loader"
不要同时在图像上同时应用两个 loader!如果 url-loader limit 不够,请使用 include 字段进一步控制

加载 SVG
{
test: /\.svg$/,
use: "file-loader",
}
react-svg-loader SVG文件作为React组件导入并在React应用中使用
svg-url-loader
svg-sprite-loader

优化图像
压缩图像
image-webpack-loader 它在图像文件被其他加载器(如file-loader或url-loader)处理后,进一步执行图像优化。它利用了mozjpeg、optipng、pngquant、gifsicle等底层工具来压缩JPEG、PNG、GIF等格式的图片。

svgo-loader(压缩SVG)
 imagemin-webpack-plugin 应用于最后数据  放use 列表中的最后一个
利用 srcset
resize-image-loader 和 
responsevie-loader 它会根据配置自动生成不同尺寸的图片,并且可以生成相应的HTML srcset 和 sizes 属性,以支持响应式图像

使用图片占位符
image-trace-loader 将SVG或位图图像(如JPEG、PNG等)转换为SVG矢量路径,像素图像转换为可缩放的矢量图形,从而在任何分辨率下都能保持清晰度 适用图标之类
lqip-loader 生成并立即显示图像的低质量预览图,随后再加载高质量图像,通常会生成一个Base64编码的小图作为占位符

引用图像
 babel-plugin-transform-react-jsx-img-import
css-loader

字体篇
url-loader 和 file-loader
{
// 除了 .woff?v=1.1.1 这样的格式以外,还要匹配 woff2.
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: "url-loader",
options: {
// 限制为 50k. 超过它就生成独立的文件
limit: 50000,

// 设置 mimetype
// 如果没有这一项,默认会根据文件扩展名来获取
mimetype: "application/font-woff",

// 输出字体到文件夹
name: "./fonts/[name].[ext]",
publicPath: "../", // 输出时基于这个目录
}
},
},
注意优先级
@font-face {
font-family: 'myfontfamily';
src: url('./fonts/myfontfile.woff2') format('woff2'), url('./fonts/myfontfile.woff') format('woff'),
url('./fonts/myfontfile.eot') format('embedded-opentype'), url('./fonts/myfontfile.ttf') format('truetype');
/* 还可以添加你认为合适的其他格式 */
}
基于 SVG 生成字体文件
 webfonts-loader
细粒度的字体文件处理能力,包括Base64嵌入和CSS自动生成
用于处理Web字体文件,包括Icon Fonts。它不仅能够加载字体文件,还可以自动生成CSS样式,甚至可以将图标编码为Base64字符串直接嵌入到CSS中,进一步减少HTTP请求。

使用字体图标
iconfont-webpack-plugin
处理Icon Font(图标字体)。它可以帮助你将图标字体文件(如.ttf、.eot、.woff、.woff2等)自动注入到你的项目中,确保图标字体资源在打包时被正确处理和优化。使用这个插件可以简化Icon Font的集成过程,避免手动编写链接和样式引用,特别是在使用自定义或第三方Icon Fonts时非常有用
plugins: [
new IconFontPlugin({
// 配置项,如字体文件路径、输出目录等
fontPath: './path/to/iconfont', // 图标字体文件目录
fontName: 'my-iconfont', // 字体名称
formats: ['woff2', 'woff', 'ttf', 'eot', 'svg'], // 支持的字体格式
}),
]

脚本篇
Babel
 babel-loader babel-webpack-plugin
• plugins:babel 中使用的插件,这些插件可以控制如何转换代码
presets:babel 可以使用哪些新的语法特性,
babel-plugin-react  •
babel-plugin-import. 主要用于按需加载模块,特别适用于那些提供了按需加载机制的库,如Ant Design的按需加载CSS
babel/plugin-transform-runtime 这个插件用于避免重复包含Babel的帮助函数
• @babel/preset-env:允许您为旧版浏览器支持某些语言特性。为此,您应该启用其 useBuiltIns 选项(设置 "useBuiltIns": true 或 "useBuiltIns": "usage")并安装 @babel/polyfill。您必须通过 import 或 entry(app: ["@babel/polyfill", PATHS.app])将其包含在项目中。@babel/preset-env 根据您选定的浏览器重写导入,并仅加载所需要的 polyfill。
• @babel/polyfill:会在全局范围内提供了像 Promise、Set 这样的对象,这会污染全局作用域,对于一些库的开发者来说这可能会造成影响,这时候可以使用 `@babel/plugin-transform-runtime 。它可以作为 Babel 插件启用,避免了全局变量污染的问题。
• babel-plugin-import:重写模块导入,以便您可以使用这样的形式(import { Button } from 'antd')来导入模块,而不必指出精准的路径

TypeScript
用于加载TypeScript文件的加载器。它们允许你在Webpack构建流程中直接使用TypeScript代码,而无需先将其编译成JavaScript
• ts-loader 官方支持 包括transpileOnly模式,该模式可以显著加快编译速度,但牺牲了一部分类型检查功能
• awesome-typescript-loader

环境变量
DefinePlugin webpack-conditional-loader
它允许你在编译时创建全局常量。设置环境变量、API端点、版本号等非常有用,因为它允许你根据不同的环境(开发、生产等)条件编译不同的代码块,而不需要在代码中硬编码这些值
lugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'), // 设置环境变量
'MY_APP_VERSION': JSON.stringify('1.2.3'), // 设置应用版本号
// 更多全局常量定义...
}),
],

if (process.env.NODE_ENV === 'production') {
console.log('Production environment detected.');
}

console.log('App version:', MY_APP_VERSION);

 

现象:项目施工列表点击数据,有时候地图上路线渲染正常,有时候闪一下消失,有时候直接不显示
排查过程:首先排查数据问题,每次点击路线图层拿到的数据是不是正常。结果数据没问题,后来怀疑渲染问题,检查React组件是否没有重新渲染,最后发现图层组件渲染问题
原因: 组件內的key值有重复,不唯一,导致react 复用旧节点没替换,页面路线数据诡异现象

bug场景: 项目列表每次导出的数据都不是查询之后的数据
原先代码实现: 查询条件对象使用useMemo记忆,依赖项是查询的每个字段。导出执行的函数是使用useCallback的记忆函数,空依赖项。函数里引用了useMemo返回的查询条件,结果出现该问题。
原因:
• 初始渲染时,useMemo根据其依赖计算一个值,useCallback创建一个引用该useMemo返回值的回调函数。
• 当useMemo的依赖改变时,它会计算新的值,但由于useCallback的依赖数组是空的,它不会创建新的回调函数,仍然保持对初次渲染时useMemo返回值的引用。
• 这就解释了为什么在后续调用useCallback的回调时,即使useMemo内部的值已经因为依赖变化而更新,回调函数内部使用的始终是最初计算的那个useMemo返回值。因为回调函数保持不变,它内部封闭的环境(包括对useMemo返回值的引用)也就保持不变。

解决办法:在useCallback的依赖数组中包含对useMemo返回值的引用。这样,当useMemo的值因为依赖变化而更新时,useCallback也会得到通知并创建一个新的回调函数,确保每次调用时都能获取到最新的useMemo结果

扩展:useCallback回调函数中除了memo返回值,其他hook如:useCallback 函数也要添加到依赖项中去

 

8.26

sideEffects 布尔值或字符串数组,用于声明模块是否有副作用
• 布尔值:如果设置为false,表明该模块没有副作用,打包工具可以更激进地进行Tree-shaking,安全地移除未被直接引用的代码。
• 数组:如果是一个字符串数组,列出模块中具有副作用的文件路径(相对于模块根目录)。这样,即使整个模块未被直接引用,这些特定的文件也不会被优化掉

Webpack 4及以前:
NamedChunksPlugin
目的是给输出的代码块(chunk)赋予更具可读性的名字
在开发环境中启用,以提高开发时的可读性

NamedModulesPlugin
将模块的ID替换为模块的实际路径名。这在开发模式下堆栈跟踪特别有用

HtmlWebpackPlugin 自动生成HTML文件,并自动注入Webpack打包生成的所有JS资源
WebpackShellPlugin 允许你在Webpack构建前后执行shell命令,比如重启服务器、清理目录等,常用于构建自动化
WebPackManifestPlugin 生成一个manifest.json文件,列出所有产出的文件及其哈希值


mainFields
0. exports (Node.js 12.0.0+ 新增,用于更细粒度的导出控制)
0. module (用于ES模块)
0. main (通用的入口点,通常用于CommonJS模块)

PurifyCSSPlugin 废弃 CSS中移除未使用的样式
替代方案:PurgeCSS 和 purgecss-webpack-plugin

uglifyjs-webpack-plugin 压缩JavaScript ,parallel: true来开启并行处理,利用Node.js的多线程能力加速压缩过程,尤其是在多核处理器的机器
terser-webpack-plugin是另一个常用的替代品 Webpack 5+


Polyfill.io 兼容性服务
pngcrush, optipng, 和 tinypng pngquant都是用于优化PNG图像的工具
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// 配置pngquant
pngquant: {
quality: [0.65, 0.9],
speed: 4
},
gifsicle: {
interlaced: false,
},
optipng: {
enabled: false,
},
webp: {
quality: 75
}
},
},
],


clean-css-loader 压缩和优化CSS代码,放在CSS的加载器链的末尾
test: /\.css$/,
use: [
// 如果你打算将CSS提取到文件中,这里应该使用MiniCssExtractPlugin.loader或style-loader
// 'style-loader',
MiniCssExtractPlugin.loader,
'css-loader', // 解析CSS
'postcss-loader', // 可选,用于额外的CSS处理,如自动添加前缀
{
loader: 'clean-css-loader', // 在这里使用clean-css-loader进行CSS压缩
options: {
// 这里可以配置clean-css的选项
level: 2, // 压缩级别,0-2,数字越大压缩程度越高
},
},
],

OptimizeCssAssetsPlugin 压缩CSS
css-minimizer-webpack-plugin Webpack 5+,已被官方推荐的 (最小化CSS文件)

mini-css-extract-plugin CSS提取成单独文件
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
{
test: /\.s[ac]ss$/i,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
// ...其他规则
],
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),


html-loader 解析HTML文件资源引用 引用本地文件,转换为require/import语句
posthtml-minifier 压缩和优化HTML代码

test: /\.html$/,
use: [
{
loader: 'html-loader', // 首先使用html-loader处理HTML文件
options: {
// html-loader 的配置选项
},
},
{
loader: 'posthtml-loader', // 然后使用posthtml-loader,这里可以配置使用posthtml-minifier
options: {
plugins: [
MiniHtmlWebpackPlugin({
removeComments: true, // 移除HTML注释
collapseWhitespace: true, // 压缩空格和换行
minifyCSS: true, // 同时压缩内联CSS
minifyJS: true, // 同时压缩内联JS
}),
],
},
},
],

webpack-closure-compiler(出现早). closure-webpack-plugin 优化js

Webpack SplitChunksPlugin 代码拆分
optimization: {
splitChunks: {
chunks: 'all', // 对所有类型的 chunk(同步和异步)应用代码分割
minSize: 10000, // 最小尺寸,达到此大小的模块才会被分割
maxSize: 0, // 可选,最大的 chunk 大小,超过此大小的 chunk 会被进一步分割
minChunks: 1, // 最小共享次数,被多少个 chunk 共享的模块才会被分割
maxAsyncRequests: 30, // 最大异步请求数量
maxInitialRequests: 30, // 最大初始化请求数量
automaticNameDelimiter: '~', // 名称分隔符
name: true, // 基于 chunks 和 cacheGroupKey 自动命名
cacheGroups: { // 配置缓存组,可以定义更细粒度的分割策略
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
filename: 'vendors.js',
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
},

AggressiveSplittingPlugin 代码分割的
new AggressiveSplittingPlugin({
minSize: 10000, // 指定最小模块大小,单位字节,只有大于这个大小的模块才会被分割
maxSize: 50000, // 可选,最大模块大小,超过这个大小的chunk会被进一步分割
}),
AggressiveMergingPlugin 合并较小的 chunks 来减少总的HTTP请求数量

DllReferencePlugin 依赖打包成dll
speed-measure-webpack-plugin loader和plugin的执行时间

 

8.27

空数组 的some 返回false
空数组every 返回true

知识点归类
Webpack性能优化 总结:

输出分析(前提)
webpack-bundle-analyzer


打包(编译):

文件查找
resolve.modules
resolve.mainFields
resolve.alias
resolve.extensions

插件
DllPlugin 和DllReferencePlugin 生成dll文件,缓存第三方依赖
HappyPack 多进程loader
ParallelUglifyPlugin 多进程js压缩
HardSourceWebpackPlugin 中间缓存步骤
TerserWebpackPlugin 缓存
babel-loader?cacheDirectory=true 缓存
thread-loader 多进程


打包输出:
TreeShaking 

样式
css-loader?minimize + ExtractTextPlugin cssnano 压缩并提取到单独文件

脚本
ParallelUglifyPlugin 多进程js压缩
uglify-webpack-plugin 压缩es6
DLLPlugin DLLReferencePlugin
CommonChunksPlugin => SplitChunksPlugin(webpack4+)
UglifyJsPlugin
externals防止打包 CDN 引入

图片

 

 

9.10

空数组 的some 返回false
空数组every 返回true

知识点归类
Webpack性能优化 总结:

输出分析(前提)
webpack-bundle-analyzer


打包(编译):

文件查找
resolve.modules
resolve.mainFields
resolve.alias
resolve.extensions

插件
DllPlugin 和DllReferencePlugin 生成dll文件,缓存第三方依赖
HappyPack 多进程loader
ParallelUglifyPlugin 多进程js压缩
HardSourceWebpackPlugin 中间缓存步骤
TerserWebpackPlugin 缓存
babel-loader?cacheDirectory=true 缓存
thread-loader 多进程


打包输出:
TreeShaking 

样式
css-loader?minimize + ExtractTextPlugin cssnano 压缩并提取到单独文件
clean-css-loader
mini-css-extract-plugin
• style-loader:将模块的导出作为样式添加到 DOM 中
• css-loader:解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码
• less-loader:加载和转译 LESS 文件
• sass-loader:加载和转译 SASS/SCSS 文件
• postcss-loader:使用 PostCSS 加载和转译 CSS/SSS 文件


脚本
ParallelUglifyPlugin 多进程js压缩
uglify-webpack-plugin 压缩es6
DLLPlugin DLLReferencePlugin
CommonChunksPlugin => SplitChunksPlugin(webpack4+) 分割打包
UglifyJsPlugin(官方不推荐) 压缩
externals防止打包 CDN 引入
TerserWebpackPlugin (推荐)压缩
ts-loader

图片
img-loader
imagemin-webpack
imagemin-webpack-loader
imagemin-webpack-plugin


文档
 posthtml-minifier
 html-loader
HtmlWebpackPlugin
url-loader:像 file loader 一样工作,如果文件小于限制,返回 data URL
file-loader:将文件发送到输出文件夹,并返回(相对)URL

框架
vue-loader

工作流程
Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
0. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
0. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
0. 确定入口:根据配置中的 entry 找出所有的入口文件
0. 编译模块:从入口文件出发,调用所有配置的 loader 对模块进行翻译,再找出该模块依赖的模块,再 递归 本步骤直到所有入口依赖的文件都经过了本步骤的处理
0. 完成模块编译:在经过第 4 步使用 loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的 依赖关系图
0. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会
0. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统

0. 初始化:启动构建,读取与合并配置参数,加载 plugin,实例化 Compiler。
0. 编译:从 entry 出发,针对每个 module 串行调用对应的 loader 去翻译文件内容,再找到该 module 依赖的 module,递归地进行编译处理。
0. 输出:对编译后的 module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统

 

9.12
Umi
Remix
Next.js
ice
Modern.js React字节开发的框架 支持ssr 微前端


可能会造成性能问题、内存泄漏、CPU/GPU飙升的原因如下:
0. 频繁的DOM操作:
• 在renderTraffictLight函数中,每一帧都会对DOM进行查询和修改操作,这在高帧率下会非常消耗性能。
• trafficLightDom.forEach中对每个红绿灯进行操作,如果红绿灯数量很多,这将是一个性能瓶颈。
0. 大量的WebGL渲染:
• renderOneFramePointsPosition函数在每一帧都可能会重建整个顶点数组,这在数据量大时,会频繁触发GPU渲染,可能导致性能问题。
0. 内存泄漏:
• trafficLightMarkers数组如果不及时清理,可能会随着时间积累越来越多的标记,造成内存泄漏。
• 如果fetchDataInterval定时器在组件卸载时没有被清除,它将继续在后台执行,即使组件不再使用。
0. 并发和异步处理:
• 使用多个异步请求(如fetchData和fetchCacheData)而没有适当的控制或取消机制,可能会导致大量的并发操作,消耗大量内存和CPU资源。
0. 红绿灯渲染问题:
• 如果红绿灯有时渲染不出来,可能是由于数据更新和DOM渲染不同步,或者是因为某些红绿灯数据不完整。
优化建议:
0. 优化DOM操作:
• 减少在renderTraffictLight中的DOM查询操作,可以考虑使用类名或ID来直接引用DOM元素。
• 对于红绿灯状态的更新,可以考虑使用CSS类来控制颜色变化,而不是直接操作style属性。
0. 优化WebGL渲染:
• 避免在每一帧都重建顶点数组。可以预先计算好整个轨迹的顶点,然后在渲染时只更新需要显示的部分。
• 使用BufferGeometry的setDrawRange方法来只渲染可视范围内的点。
0. 避免内存泄漏:
• 确保在组件卸载时清除所有的定时器、事件监听器和WebGL资源。
• 定期清理不再需要的对象和数据,例如trafficLightMarkers。
0. 控制并发和异步处理:
• 使用Promise的all或者race方法来控制并发请求,避免同时处理过多的异步操作。
• 提供取消机制,如在组件卸载时取消未完成的请求。
0. 修复红绿灯渲染问题:
• 确保红绿灯数据和DOM元素的同步,可以使用状态管理库来控制状态和渲染。
• 检查红绿灯数据是否完整,并在数据缺失时提供默认行为。
针对红绿灯有时渲染不出来的问题,可以进一步检查以下几点:
• 确认红绿灯数据是否正确,并且包含了必要的position信息。
• 检查是否所有的红绿灯标记都被正确添加到了地图上。
• 查看控制红绿灯显示的逻辑,确认是否由于某些条件未满足导致红绿灯没有显示。
在优化过程中,监控工具可以帮助识别性能瓶颈和内存泄漏的具体位置。例如,使用Chrome的开发者工具来分析CPU和内存的使用情况,以及查看可能存在的内存泄漏

CPU占满100%的原因:
0. 高频的渲染和计算:
• setInterval在putTrackPointsOnMap方法中设置了一个高频的定时器(1000/framesPerSecond),这会导致频繁的执行renderOneFramePointsPosition和renderTraffictLight方法,这两个方法涉及到图形渲染和计算,可能会占用大量CPU资源。
0. Web Workers的使用:
• 使用了Web Worker在calcData方法中进行数据处理。如果数据处理逻辑复杂或者数据量很大,这可能会占用大量CPU资源。
0. 大量的DOM操作:
• 在renderTrafficLightMarkers方法中,频繁地创建和销毁AMap.Marker实例以及操作DOM元素,这可能会引起重绘和回流,从而增加CPU的负担。
0. 图形渲染:
• 使用Three.js进行3D图形渲染,尤其是在render方法中,如果场景复杂或者渲染设置不当,都可能导致CPU或GPU负载过高。
0. 大量的数据请求和处理:
• 在fetchData方法中,如果频繁地请求数据,并且数据量较大,处理这些数据可能会占用大量CPU资源。
页面DOM节点持续增多的原因:
0. 重复添加红绿灯标记:
• 在renderTrafficLightMarkers方法中,每次调用都会创建新的AMap.Marker实例并添加到地图上,但如果之前的标记没有被正确地移除,就会导致DOM节点持续增多。
0. 没有正确清理DOM:
• 在clearCurrentTrafficLightMarkers方法中,虽然尝试移除DOM节点,但如果某些节点没有被成功移除(例如,由于引用仍然存在),它们将留在DOM中。
0. 类名操作:
• 在renderTraffictLight方法中,对.traffic-light__marker类的元素进行操作,如果元素没有被正确地隐藏或移除,它们会继续存在于DOM中。
解决这些问题的一些方法可能包括:
• 优化定时器使用,避免不必要的频繁调用。
• 优化数据处理逻辑,减少在Web Worker中的计算量。
• 在不需要时,确保正确地清理和销毁Three.js的渲染资源。
• 确保每次创建新的地图标记前,旧的标记都被正确地移除。
• 优化DOM操作,避免不必要的DOM节点创建和删除。


优化搜索性能通常涉及多个方面,包括算法选择、数据结构优化、索引使用、缓存机制、并行处理等。以下是一些通用的优化策略:
1. 数据结构和算法优化
• 使用高效的数据结构:例如,使用哈希表(如JavaScript中的对象或Map)来快速查找数据。
• 选择合适的搜索算法:对于不同的数据集和搜索需求,选择合适的算法(如二分搜索、深度优先搜索、广度优先搜索等)。
• 剪枝:在搜索过程中,如果能够确定某个分支不可能产生结果,则可以提前终止该分支的搜索。
2. 索引
• 建立索引:对于经常搜索的数据,建立索引可以大幅提高搜索效率。例如,数据库中的索引、全文搜索引擎的倒排索引等。
• 多级索引:对于复杂的数据结构,可以使用多级索引来快速定位到数据所在的区域。
3. 缓存
• 缓存搜索结果:如果相同的搜索请求会被多次执行,可以将结果缓存起来,避免重复计算。
• 局部性原理:利用数据访问的局部性原理,缓存最近或最频繁访问的数据。
4. 并行处理
• 多线程/多进程:将搜索任务分解成多个子任务,并行执行以利用多核处理器的优势。
• 分布式搜索:对于非常大的数据集,可以使用分布式系统来进行并行搜索。
5. 优化查询
• 减少查询范围:通过过滤不必要的数据来减少搜索范围。
• 预处理查询:在可能的情况下,对查询进行预处理,比如正则表达式编译。
6. 硬件优化
• 使用更快的存储:使用SSD代替HDD,以提高数据读取速度。
• 增加内存:增加可用内存可以减少磁盘I/O操作,提高搜索速度。
7. 代码优化
• 避免不必要的计算:移除代码中不必要的计算,减少循环和递归的深度。
• 优化循环和递归:优化循环结构,减少循环次数,避免不必要的递归调用。
8. 监控和分析
• 性能监控:使用性能监控工具来识别瓶颈。
• 分析查询模式:通过分析用户的查询模式来优化搜索策略

处理大量节点的情况通常需要考虑数据结构和算法的选择、内存管理、并发处理以及系统架构等多个方面。以下是一些处理大量节点的策略:
1. 数据结构选择
• 分而治之:使用树状结构(如B树、B+树、红黑树等)来管理节点,这样可以将大量的节点分布在不同的层级和子树中,提高搜索和插入的效率。
• 哈希表:对于不需要顺序遍历的场景,使用哈希表可以快速访问节点。
• 图数据结构:对于节点之间有复杂关系的场景,使用图数据结构,并通过适当的图算法来处理。
2. 算法优化
• 避免全量遍历:对于需要遍历的场景,尽量使用迭代而非递归,以避免栈溢出。
• 优化搜索算法:使用更适合大量节点的搜索算法,如A*搜索、Dijkstra算法等。
3. 内存管理
• 内存池:使用内存池来管理节点的内存分配,减少内存碎片和分配开销。
• 对象复用:在可能的情况下,复用已存在的节点对象,减少内存分配。
4. 并发处理
• 多线程/多进程:利用多线程或多进程来并行处理节点,特别是在CPU密集型的操作中。
• 分布式系统:对于非常大的节点集合,可以使用分布式系统来分散负载。
5. 系统架构
• 分片:将节点分布在不同的分片中,每个分片独立处理一部分节点,降低单个节点的负载。
• 负载均衡:使用负载均衡技术来分配节点处理任务,确保系统资源得到有效利用。
6. 索引和缓存
• 建立索引:为节点建立索引,以加速查找和访问速度。
• 缓存热点数据:缓存频繁访问的节点数据,减少磁盘I/O操作。
7. 数据存储
• 外部存储:对于无法全部加载到内存中的节点,使用外部存储(如数据库、文件系统等)。
• 数据压缩:对存储的数据进行压缩,以减少存储空间的需求。
8. 性能监控和调优
• 性能监控:实时监控系统的性能,及时发现瓶颈。
• 调优:根据监控结果对系统进行调优,如调整缓存大小、优化数据库查询等


在处理大量节点的搜索问题时,优化搜索算法的性能是非常重要的。以下是一些常用的搜索优化技巧:
1. 剪枝(Pruning)
• 预剪枝:在搜索过程中,如果发现当前路径不可能产生比当前最优解更好的解,则可以提前终止该路径的搜索。
• 后剪枝:在搜索完成后,如果发现某个节点不会影响最终解,则可以将其删除。
2. 启发式搜索(Heuristic Search)
• A*搜索算法:使用启发式函数估计从当前节点到目标节点的成本,优先搜索更有可能找到最优解的路径。
• IDA*搜索算法:迭代加深A*算法,结合深度优先搜索和启发式搜索的优点。
3. 空间优化
• 迭代加深搜索(IDDFS):结合深度优先搜索和广度优先搜索的优点,逐步增加搜索深度。
• 跳跃表(Skip List):在搜索时跳过一些节点,加速搜索过程。
4. 数据结构优化
• 优先队列(Priority Queue):使用优先队列来管理待搜索的节点,保证总是先搜索最有希望的节点。
• 哈希表(Hash Table):用于快速查找和更新节点状态。
5. 动态规划(Dynamic Programming)
• 记忆化搜索(Memoization):存储已计算的结果,避免重复计算。
• 状态表:使用表格来存储中间状态,便于快速查找。
6. 并行搜索
• 多线程/多进程搜索:将搜索任务分解为多个子任务,并行执行。
• 分布式搜索:在多个机器上分布式执行搜索任务。
7. 局部搜索优化
• 爬山算法(Hill Climbing):总是选择当前最优的移动。
• 模拟退火(Simulated Annealing):允许在一定概率下接受非最优解,以跳出局部最优。
• 遗传算法(Genetic Algorithms):使用生物进化原理来搜索解空间。
8. 搜索策略优化
• 双向搜索:从目标节点和起始节点同时进行搜索,直到两者相遇。
• 重启动策略:在搜索陷入局部最优时重新开始搜索。
9. 其他技巧
• 路径压缩:在搜索过程中压缩已访问路径,减少搜索空间。
• 循环检测:在搜索过程中检测并避免进入循环。
• 位运算优化:在处理状态时使用位运算来提高效率。
实际应用中的注意事项
• 理解问题特性:针对具体问题选择合适的搜索算法和优化技巧。
• 测试和调整:通过实验测试不同优化技巧的效果,并根据结果调整策略。
• 资源监控:监控搜索过程中的资源使用情况,如内存和CPU使用,避免资源耗尽。


搜索缓存的设计是提升搜索效率的关键部分,它能够减少对原始数据的重复处理,加快搜索响应时间。以下是一些设计高效搜索缓存的策略:
1. 缓存粒度
• 细粒度缓存:缓存单个查询结果,适用于查询结果变化不频繁且查询量大。
• 粗粒度缓存:缓存整个数据集或数据集的一部分,适用于数据更新不频繁的场景。
2. 缓存失效策略
• 定时失效:设置缓存项在一定时间后自动失效。
• 主动更新:当数据源发生变化时,主动更新或清除相关缓存项。
• 懒加载:在缓存项被访问时检查其有效性,如果无效则重新加载。
3. 缓存存储
• 内存缓存:使用内存作为缓存介质,如Redis或Memcached,以获得最快的访问速度。
• 磁盘缓存:对于数据量大且不经常访问的数据,可以使用磁盘缓存。
4. 缓存结构
• 哈希表:用于快速查找和访问缓存项。
• 树结构:如B树、红黑树,适用于需要范围查询的场景。
5. 缓存内容
• 结果缓存:直接缓存查询的最终结果。
• 中间结果缓存:缓存搜索过程中产生的中间结果,减少重复计算。
6. 缓存命中率优化
• 缓存热点数据:优先缓存访问频率高的数据。
• 缓存预加载:预测即将被访问的数据并提前加载到缓存中。
7. 缓存并发控制
• 读写锁:控制缓存项的并发读写,保证数据的一致性。
• 原子操作:使用原子操作来更新缓存,避免并发问题。
8. 缓存大小管理
• 固定大小:设置缓存的最大容量,当达到容量限制时,使用LRU(最近最少使用)、LFU(最不经常使用)等算法淘汰旧数据。
• 动态调整:根据系统负载和资源使用情况动态调整缓存大小。
9. 缓存安全性
• 数据加密:对敏感数据进行加密存储。
• 访问控制:确保只有授权的用户或服务可以访问缓存。
10. 监控与统计
• 性能监控:监控缓存命中率、响应时间等关键指标。
• 日志记录:记录缓存操作日志,便于问题追踪和分析。
实现高效搜索缓存的步骤:
0. 需求分析:了解搜索查询的特性和访问模式。
0. 缓存策略设计:根据需求选择合适的缓存粒度、失效策略、存储方式和结构。
0. 缓存实现:编写代码实现缓存逻辑,并进行单元测试。
0. 性能测试:通过压力测试来评估缓存性能,并根据测试结果进行优化。
0. 持续优化:根据实际运行情况进行调整,提高缓存效率。

 

arguments.callee是指当前正在执行的函数 匿名函数的递归调用
DOMContentLoaded事件必须等待其所属script之前的样式表加载解析完成后才会触发

循环中多次在刚给 DOM 更新样式位置后,立即通过 offsetTop 获取 DOM 位置。这样的操作会强制启动重排,因为浏览器并不清楚上一个循环内 DOM 有没有改变位置,必须立即重新布局才能计算 DOM 位置


preload本质:preload 是声明式的 fetch,可以改变浏览器加载资源的优先级,强制浏览器请求资源,同时不阻塞文档 onl oad 事件,也因此可以将 load 事件与脚本解析过程解耦
prefetch本质:让浏览器空闲的时候加载下一页可能需要的资源,同样的load和解析解耦
dns-fetch,让浏览器提前做dns预解析,当静态资源和html不在同一个域的时候,特别好用
async,defer是script的属性,其让html解析与下载并行,但是async下载完之后立即执行,而defer是html解析完之后再执行,一般按照顺序执行,但据说不是百分百靠谱

性能角度考虑,尽量不要把读操作和写操作,放在一个语句里面。DOM 的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作
先将元素设为display: none(需要1次重排和重绘),然后对这个节点进行100次操作,最后再恢复显示(需要1次重排和重绘)。这样一来,你就用两次重新渲染,取代了可能高达100次的重新渲染。
第六条,position属性为absolute或fixed的元素,重排的开销会比较小,因为不用考虑它对其他元素的影响。
第七条,只在必要的时候,才将元素的display属性为可见,因为不可见的元素不影响重排和重绘。另外,visibility : hidden的元素只对重绘有影响,不影响重排。


渐进加载
渐进加载是指先加载低质量甚至模糊的图片,然后随着页面继续加载,使用LQIP(低质量图片占位符)技术替换为高质量的完整版本。

这种技术确实提高了首次进行有意义绘制的时间

浏览器每次处理 HTML 标记时,都会完成上述所有步骤:将字节转换为字符,确定令牌,将令牌转换为节点,然后构建 DOM 树。

对于较大的页面,此过程可能需要更长的时间。在制作流畅的动画时,如果浏览器必须处理大量 HTML,这很容易成为瓶颈。
DOM 树会捕获文档标记的属性和关系,但不会告知我们元素在渲染时的外观。这就是 CSSOM 

CSS 字节会依次转换为字符、令牌、节点,最后链接到一个称为“CSS 对象模型”(CSSOM) 的树形结构


阴影的计算和渲染“成本高昂”
CSS 是一种阻塞渲染的资源

CRP 主要包括以下几个阶段:
0. HTML 解析:
• 浏览器开始读取 HTML 文档并构建 DOM 树(Document Object Model)。
• HTML 的每个标签都会生成一个对应的 DOM 节点。
0. CSS 解析:
• 浏览器解析 CSS 文件和内联样式,生成 CSSOM 树(CSS Object Model)。
• CSSOM 树结合 DOM 树,产生一个渲染树,每个渲染树节点对应一个要显示的页面元素。
0. 布局(Layout):
• 浏览器根据渲染树为每个节点计算位置和尺寸,这一步也称为回流(reflow)。
0. 绘制(Paint):
• 将渲染树节点转换为屏幕上的像素,这个过程称为绘制。
0. 合成(Composition):
• 将不同的层(Layers,例如固定定位元素、动画元素等)合成一个最终的页面。
影响 CRP 的因素
0. 阻塞渲染的 CSS 和 JavaScript:
• CSS 文件是渲染阻塞的,因为浏览器必须先构建 CSSOM 才能正确渲染页面。
• JavaScript 文件也可能阻塞渲染,因为它们可能会修改 DOM 和 CSSOM,从而影响页面内容和样式。
0. 资源加载顺序:
• 资源的加载顺序和解析顺序会直接影响页面的显示时间。关键资源应尽量优先加载。
优化关键渲染路径
0. 最小化 CSS 阻塞:
• 内联关键 CSS:将关键样式内联到 HTML 中,减少外部 CSS 文件的请求时间。
• 延迟/异步加载非关键 CSS:使用媒体查询或 loadCSS 等工具延迟加载非关键 CSS。
0. 最小化 JavaScript 阻塞:
• 使用 async 或 defer 属性:对于外部 JavaScript 文件,使用 async 或 defer 属性异步加载脚本。
• 拆分脚本:将必要的脚本部分放在 <head> 中,延迟或异步加载非关键的脚本。
0. 优化资源加载:
• 压缩和合并资源:通过压缩和合并 CSS 和 JavaScript 文件减少 HTTP 请求和文件大小。
• 使用 HTTP/2:HTTP/2 通过多路复用请求提高资源加载速度。
• 缓存资源:利用浏览器缓存和服务器缓存策略减少重复加载时间。
0. 优化图像:
• 延迟加载图像(Lazy Loading):通过 Lazy Loading 技术,图片仅在需要显示时加载。
• 使用合适的图像格式:选择合适的图像格式(如 WebP)和压缩图像以减少文件大小。

最小组件集,并将它们批量处理为单个网络请求

一个组件到 JS 模块的映射,以告知客户端要加载哪些模块。通过将组件标记为延迟加载,JS 模块将稍后加载

静态import和动态import()都很有用。它们各自都有非常独特的用例。使用 staticimport来获取初始绘制依赖项,尤其是首屏内容。在其他情况下,请考虑使用 dynamic 按需加载依赖项import()。

https://github.com/GoogleChrome/web-vitals


优化 JavaScript 和资源
• 消除阻塞渲染的资源。
• 拆分代码并使用动态import()。
• 将所有内容分成单独的部分,并延迟加载折叠下方的 HTML 文件。
• 按需执行并加载 JavaScript。
• <script>通过在标签上使用异步属性并与重要来源建立早期连接(资源提示,如dns-prefetch、preconnect和preload),识别缓慢的 JavaScript 资源并优化加载过程。
• 删除未使用的代码,并最小化和压缩代码。
• 使用 CDN。
• 使用 Service Worker和Workbox控制缓存。
优化图像
• 延迟加载首屏以下的图片。
• 使用 CDN 优化图像,提供适当大小的图像,压缩图像,并采用适合工作的图像格式(WebP、SVG、Web Fonts)。
优化 CLS
• 使用CSSaspect-ratio在图像加载时为图像保留所需的空间。
• min-height在元素延迟加载时使用 CSS来最小化布局偏移。


navigator.connection.effectiveType === '2g

scroll但事件侦听器本身会安排大量必须在主线程上运行的工作。这项工作导致主线程争用,从而增加了交互延迟,导致搜索页面上的 INP 不佳。
• scroll事件处理程序已去抖动,以减少事件回调在给定时间段内触发的次数。通过降低事件scroll回调运行的频率,主线程能够更快地响应搜索页面上的用户交互。
• 通过使用回调对最终的渲染工作进行优先排序requestAnimationFrame。requestAnimationFrame告诉浏览器回调中的工作必须在下一帧之前完成。
• 为了通过更早地触发延迟加载来改善用户体验和视觉性能,在搜索结果页面的倒数第二张卡片上获取了新一批结果。
• 延迟加载期间,每次网络调用获取的结果更少。通过将获取的结果从 30 个减少到 10 个,可以观察到 INP 范围从 870 到 900 减少到 350 到 370。


<input type="text"
         inputmode="numeric"
         autocomplete="one-time-code"
         pattern="\d{6}"
         required>


content-visibility,浏览器可以延迟对不可见内容的渲染
使用 content-visibility 延迟渲染屏幕外的元素


WebCodecs. 音视频编解码器。视频绘制在canvas
主要功能
• 视频编解码:编码和解码视频数据流。
• 音频编解码:编码和解码音频数据流。
• 低延迟:适用于实时应用,比如视频会议和游戏流媒体。
• 高性能:通过直接访问编解码器来提高性能,减少开销。
https://sketch.pixiv.net/

Asm.js 是 WebAssembly 的前身,可以认为是一种 WebAssembly 的“轻量级”实现。虽然 WebAssembly 现在通常更受欢迎,但 Asm.js 仍然是一个重要的技术,因为它不需要特定的浏览器支持(所有支持 JavaScript 引擎的浏览器均支持)。

重大更改(例如增加“html”元素的字体大小)将导致缓存失效、依赖和整个树的重新绘制

当你使用 will-change 属性时,浏览器会根据指定的属性或内容进行优化。例如,如果你告知一个元素的 transform 将会改变,浏览器可能会为该元素分配一个独立的图层,从而避免在动画或变换时触发重排 (reflow) 或重绘 (repaint)

图层是渲染树的一个优化机制,浏览器会将一些元素提升到单独的图层中进行绘制。这些图层最终会被合成(compositing)成一个完整的页面图像。图层可以减少重排(reflow)和重绘(repaint)操作的开销,因为图层中的元素变化不会影响其他图层。
图层的创建条件
浏览器通常在以下情况下创建新的图层:
0. CSS 属性:使用具有 3D 变换(如 transform: translateZ(0)),或其他可能导致提升为独立图层的属性(如 will-change)。
0. 显示属性:使用 CSS 属性 position: fixed 或 position: sticky。
0. 动画和过渡:对包含动画(如 @keyframes)的元素会尝试提升为图层,以提高动画性能。
0. CSS 滤镜和混合模式:使用 filter 或 mix-blend-mode。
0. Canvas 和 视频元素:HTML5 的 <canvas> 和 <video> 元素通常会被提升为独立图层

mix-blend-mode 是一个 CSS 属性,用于设置元素的内容与其父元素的背景或其他内容混合的方式


svg-sprite-loader svgo-loader webpack-ant-icon-loader 
preload-webpack-plugin

 

Storybook

 

标签:缓存,渲染,摘要,笔记,loader,使用,CSS,加载
From: https://www.cnblogs.com/sybboy/p/18464004

相关文章

  • DRÆM – A discriminatively trained reconstruction embedding for surface anomaly
    异常检测目的:检测与正常外观显著偏离的局部图像区域。近期异常检测方法缺点:1.缺点1:重建异常区域失败近期的异常检测方法通过生成模型来重建图像,在正常区域里成功,但异常区域里重建失败缺点2:阻碍优化特征提取因为这些方法只在无异常的图像上训练,且通过人工的方式定位......
  • perl学习笔记14_安装模块
    目录1.问题2.手工下载模块3.安装模块到本地目录4.使用模块1.问题在工作站内网,安装perl模块会有两个问题:没有网络,需要手工下载模块.没有perl目录权限,需要把模块安装到本地.2.手工下载模块在外网进入cpan网站:https://metacpan.org/.在搜索框输入要下载的模......
  • 吴恩达机器学习笔记(2-1到2-7)
    吴恩达机器学习笔记(2-1到2-7)https://www.bilibili.com/video/BV164411b7dx?p=5https://www.bilibili.com/video/BV164411b7dx?p=6https://www.bilibili.com/video/BV164411b7dx?p=7https://www.bilibili.com/video/BV164411b7dx?p=8https://www.bilibili.com/video/BV164411b......
  • 【C++学习】核心编程之类和对象(上)黑马学习笔记—超详细
    目录(一)封装1.1封装的意义:意义一:在设计类的时候,属性和行为写在一起,表现事物意义二:类在设计时,可以把属性和行为放在不同的权限下,加以控制1.2struct和class区别 1.3成员属性设置为私有(二)对象的初始化和清理2.1构造函数和析构函数2.2构造函数的分类及调用两种分类......
  • 24/10/13 ABC375补题笔记
    A典,属于显而易见的水题,这数据范围直接暴力做就行了。#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn; cin>>n; strings; cin>>s; intcnt=0; if(n<2)returncout<<0<<endl,0; for(inti=0;i<s.size()-2;i++)......
  • 笔记本中vscode设置
    笔记本中的vscode设置修改界面的隐藏和显示时,会提示Unabletowriteintousersettingsbecausethefilehasunsavedchanges.Pleasesavetheusersettingsfilefirstandthentryagain.就把第二段删除了问题暂时解决{"terminal.integrated.commandsToSkipSh......
  • 2024年软件设计师中级(软考中级)详细笔记【5】软件工程基础知识下(分值10+)
    第5章软件工程目录前言第5章软件工程基础知识(下)5.5系统测试5.5.1系统测试与调试5.5.2传统软件的测试策略5.5.5测试方法5.5.5.1黑盒测试5.5.5.2白盒测试白盒测试+McCabe度量法伪代码+白盒测试+McCabe5.6运行和维护知识【以背为主】5.6.2系统维护概述5.6.2.1......
  • Web前端开发入门学习笔记之CSS 43-47 --新手超级友好版-复合选择器+css特性篇
         Foreword写在前面的话: 大家好,我是一名刚开始学习HTML的新手。这篇文章是我在学习html过程中的一些笔记和心得,希望能和同样在学习HTML的朋友们分享。由于我的知识有限,文章中可能存在错误或不准确的地方,欢迎大家在评论区提出建议和指正。我非常期待大家的反馈,以便......
  • 深度学习神经网络笔记--卷积神经网络
    为什么要用卷积捕捉特征,如文末的图)不受位置影响(左右,前后,上下)可以参考下图:卷积操作可移动的小窗口与图像数据逐元素相乘后相加小窗口是滤波器,卷积核,(权重矩阵)需要注意的问题:stride:步长卷积核的个数:决定输出的depth,卷积核个数填充值zerp-padding:外圈补0......
  • DAY3 MySQL学习笔记
    DAY3MySQL学习笔记DDL-表操作-数据类型MySQL中数据类型主要分为三类:数值型、字符串型、日期时间类型数值类型分类类型大小有符号(SIGNED)范围无符号(UNSIGNED)范围描述TINTING1byte(-128,127)(0,255)小整数值SMALLINT2bytes(-32768,32767)(0,65536)大整数值MEDIUMINT3bytes......