OHIF Viewers 项目介绍

项目结构

项目架构

│
├── extensions
│   ├── default               # 默认功能
│   ├── cornerstone           # 使用 Cornerstonejs 处理 2D/3D 图像
│   ├── cornerstone-dicom-sr  # 结构化报告 (DICOM SR)
│   ├── measurement-tracking  # 测量追踪功能
│   └── dicom-pdf             # 在视口中查看 DICOM 包装的 PDF 文件
│   # 还有更多扩展功能...
│
├── modes
│   └── longitudinal          # 纵向测量追踪模式
│   └── basic-dev-mode        # 使用 Cornerstone 的基础查看器 (面向开发者的模式)
│   # 还有更多模式...
│
├── platform
│   ├── core                  # 业务逻辑核心
│   ├── i18n                  # 国际化支持
│   ├── ui                    # React 组件库
│   └── app                   # 连接平台和扩展项目
│
├── ...                      # 其他共享配置文件
├── lerna.json               # MonoRepo (Lerna) 设置
├── package.json             # 共享的开发依赖项和命令
└── README.md                # 项目说明文档

OHIF v3 由以下组件组成,将在进一步中详细描述 部分:

  • @ohif/app:控制扩展注册、模式的核心框架 组合和路由。
  • @ohif/core:一个有用且可重复使用的医学成像功能库 对于网络。
  • @ohif/ui:一个可重用的组件库,用于构建 OHIF 风格的应用程序 跟。
  • Extensions:一组用于构建应用程序的构建块。OHIF组织 维护一些核心库。
  • Modes:告诉 @ohif/app 如何撰写的配置对象 扩展,用于在平台的不同路线上构建应用程序。

OHIF 为一些常见的使用场景维护了少量功能强大的扩展。这些扩展与 OHIF/Viewers 仓库一起存放在项目的根目录下的 extensions/ 文件夹中。

下面那个表格展示了 OHIF 中各种类型模块的功能描述。

OHIF V3 组件库

@ohif/app​

此库是使用模式、扩展和构建的核心库 一个应用程序。扩展可以作为应用配置传入,并且将 应用程序在适当的时间使用和初始化。后 初始化 Viewer 将使用扩展和模式并构建 所需的路线,然后可以通过研究列表访问这些内容,或直接通过 URL 参数。

发布时,模式也将通过配置插入到应用程序中,但这 仍然是一个正在开发/讨论的领域,他们目前正在 在测试版中从窗户拉出。

这个框架的未来想法只涉及添加模式和获取 在运行时或构建时都需要扩展版本,但此决定 还有待商榷。

视口重新渲染优化

我们利用 React 记忆模式来防止不必要的重新渲染 除非视口属性的某些方面发生变化。你可以采取 查看组件中的函数以 看看这是如何完成的。areEqualOHIFCornerstoneViewport

function areEqual(prevProps, nextProps) {  
if (prevProps.displaySets.length !== nextProps.displaySets.length) {   return false;  
}  
if (    prevProps.viewportOptions.orientation !==    nextProps.viewportOptions.orientation  ) 
{    return false;  }  // rest of the code

如您所见,我们检查道具是否为真,如果是,我们将 如果属性或方向发生变化,请重新渲染视口 变化。needsRerenderingdisplaySets

我们使用 viewportId 来标识视口,并在 React 中将其用作键 渲染。这很重要,因为它允许我们跟踪视口 以及它的状态,并且还让 React 在 网格而不重新渲染它。但是,在某些情况下,我们需要这样做 强制重新渲染视口,例如,当视口被冻结时 具有新的细分。对于这些情况,我们使用 prop 强制重新渲染视口。您可以将其添加到needsRerenderingviewportOptions

视口组件由组件管理。哪个视口 组件的使用取决于:ViewportGrid

  • 挂起协议
  • 布局配置
  • 已注册的 SopClassHandlers

@ohif/core​

OHIF核心是一套经过精心维护和测试的基于网络的医学成像设备 函数和类。此库包括用于以下位置的管理器和服务 在查看器应用程序中。

OHIF 核心在很大程度上类似于 v2 中的 @ohif/core 库,但是很多 逻辑已移至扩展:但是,有关 DICOMWeb 和其他的所有逻辑 数据获取机制已被拉出,因为这些机制现在存在于扩展中, 稍后再述。

@ohif/ui​

首先,我们发现一个巨大的时间消耗/进入壁垒正在建造新的 UI及时符合OHIF的主题。出于这个原因,我们建立了一个新的 UI组件库,其中包含构建其所需的所有组件 自己的观众。

这些组件仅是演示性的,因此您可以将它们与任何内容重复使用 你想要的逻辑。由于组件是演示性的,因此您可以换掉 如果您希望为白标,请使用具有符合 API 的自定义 UI 库的 @ohif/ui 观众。UI 库是为了让开发更轻松、更快捷,但 扩展组件不是强制性的。

OHIF V3体系结构

Video Tutorials | OHIF 扩展模式

OHIF CLI 促进了创建、链接和发布 OHIF 模式和扩展。以下视频演示了如何使用 CLI 进行

  • 创建模式和扩展
  • 链接本地模式和扩展
  • NPM 的发布模式和扩展
  • 向 OHIF 添加已发布的模式和扩展
  • 向 OHIF 提交模式

更新数据源的配置

可以使用该方法更新现有数据源的配置。以下代码片段 代码演示了如何使用来更新 配置现有 DICOMWeb 数据源(名为 ),并使用 Google Cloud Healthcare API 数据源的配置。ExtensionManager.updateDataSourceConfigurationupdateDataSourceConfigurationdicomweb

extensionManager.updateDataSourceConfiguration( "dicomweb",  {    name: 'GCP',    wadoUriRoot:      'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',    qidoRoot:      'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',    wadoRoot:      'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',    qidoSupportsIncludeField: true,    imageRendering: 'wadors',    thumbnailRendering: 'wadors',    enableStudyLazyLoad: true,    supportsFuzzyMatching: true,    supportsWildcard: false,    dicomUploadEnabled: true,    omitQuotationForMultipartRequest: true,  },);

模板:布局模式

概述

LayoutTemplates是 v3 中的一个新概念,模式使用它来控制布局 的路线。布局模板是一个 React 组件,它被赋予了一组 定义 API 以访问工具栏状态、命令和热键的管理器,如 以及布局模板定义的属性。

例如,默认的 LayoutTemplate 接受 leftPanels、rightPanels 和 视口作为属性,它使用它来构建其视图。

此外,对结构具有完全的控制权。 应用。你可以在左侧放置工具,或者有严格的指导 工作流 通过以编程方式设置工具,您可以选择适合您的用例。layout template

const getLayoutTemplateModule = (/* ... */) => [{id: 'exampleLayout',name: 'exampleLayout',component: ExampleLayoutComponent,},
];

传递给的是经理和服务 使用定义的模式左/右面板、模式定义的视口和 OHIF 。LayoutTemplate 利用 extensionManager 来抓取类型 扩展模块条目:propslayoutTemplateViewportGridComp*.getModuleEntry(id)

布局模板的简化代码为:Default extension

extensions/default/src/ViewerLayout/index.jsx

import React from 'react';
import { SidePanel } from '@ohif/ui';function Toolbar({ servicesManager }) {const { ToolBarService } = servicesManager.services;return (<>// ToolBarService.getButtonSection('primary') to get toolbarButtons{toolbarButtons.map((toolDef, index) => {const { id, Component, componentProps } = toolDef;return (<Componentkey={id}id={id}{...componentProps}bState={buttonState}isActive={isActive}onInteraction={args => ToolBarService.recordInteraction(args)}/>);})}</>);
}function ViewerLayout({// From Extension Module ParamsextensionManager,servicesManager,hotkeysManager,commandsManager,// From ModesleftPanels,rightPanels,viewports,ViewportGridComp,
}) {const getPanelData = id => {const entry = extensionManager.getModuleEntry(id);const content = entry.component;return {iconName: entry.iconName,iconLabel: entry.iconLabel,label: entry.label,name: entry.name,content,};};const getViewportComponentData = viewportComponent => {const entry = extensionManager.getModuleEntry(viewportComponent.namespace);return {component: entry.component,displaySetsToDisplay: viewportComponent.displaySetsToDisplay,};};const leftPanelComponents = leftPanels.map(getPanelData);const rightPanelComponents = rightPanels.map(getPanelData);const viewportComponents = viewports.map(getViewportComponentData);return (<div><Toolbar servicesManager={servicesManager} /><div>{/* LEFT SIDEPANELS */}<SidePanelside="left"defaultComponentOpen={leftPanelComponents[0].name}childComponents={leftPanelComponents}/>{/* TOOLBAR + GRID */}<ViewportGridCompservicesManager={servicesManager}viewportComponents={viewportComponents}commandsManager={commandsManager}/>{/* Right SIDEPANELS */}<SidePanelside="right"defaultComponentOpen={rightPanelComponents[0].name}childComponents={rightPanelComponents}/></div></div>);
}

悬挂协议

悬挂协议是任何放射学观察器的重要组成部分。 OHIF 使用悬挂协议来处理视口中图像的排列。在 简而言之,已注册的协议将与 DisplaySet 匹配 可用。每个协议都会得到一个分数,并且它们会被排名。这 应用获胜协议(最高分)并运行其设置以用于视口 待安排。

在挂起协议中,您可以:OHIF-v3

  • 定义视口应从什么布局开始(例如,2x2 布局)
  • 指定视口的类型及其方向(例如,堆栈、带有 Sagittal 视图的体积)
  • 定义在布局的哪个视口中显示哪个 displaySets(例如,具有“CT”模态的 displaySet 和 “Coronary Arteries” 的 “SeriesDescription” 将显示在布局的第一个视口中)
  • 应用某些初始视口设置(例如,反转对比度、跳转到特定切片等)
  • 为视口添加特定的同步规则(例如,同步索引 1、2 的视口缩放,或同步索引 2、3 的视口的 VOI)

使用您可以提供/注册 OHIF 的协议以 利用。hangingProtocolModule

这是一个示例协议,如果使用该协议,它将悬挂一个 1x3 布局,第一个视口显示 CT 图像,第二个视口显示 PT 图像,第三个视口显示它们的融合,所有这些都以矢状方向实现视图

const oneByThreeProtocol = {id: 'oneByThreeProtocol',locked: true,name: 'Default',createdDate: '2021-02-23T19:22:08.894Z',modifiedDate: '2022-10-04T19:22:08.894Z',availableTo: {},editableBy: {},imageLoadStrategy: 'interleaveTopToBottom',protocolMatchingRules: [{attribute: 'ModalitiesInStudy',constraint: {contains: ['CT', 'PT'],},},],displaySetSelectors: {ctDisplaySet: {seriesMatchingRules: [{weight: 1,attribute: 'Modality',constraint: {equals: {value: 'CT',},},required: true,},{weight: 1,attribute: 'isReconstructable',constraint: {equals: {value: true,},},required: true,},],},ptDisplaySet: {seriesMatchingRules: [{attribute: 'Modality',constraint: {equals: 'PT',},required: true,},{weight: 1,attribute: 'isReconstructable',constraint: {equals: {value: true,},},required: true,},{attribute: 'SeriesDescription',constraint: {contains: 'Corrected',},},],},},stages: [{id: 'hYbmMy3b7pz7GLiaT',name: 'default',viewportStructure: {layoutType: 'grid',properties: {rows: 1,columns: 3,},},viewports: [{viewportOptions: {viewportId: 'ctAXIAL',viewportType: 'volume',orientation: 'sagittal',initialImageOptions: {preset: 'middle',},syncGroups: [{type: 'voi',id: 'ctWLSync',source: true,target: true,},],},displaySets: [{id: 'ctDisplaySet',},],},{viewportOptions: {viewportId: 'ptAXIAL',viewportType: 'volume',orientation: 'sagittal',initialImageOptions: {preset: 'middle',},},displaySets: [{id: 'ptDisplaySet',},],},{viewportOptions: {viewportId: 'fusionSAGITTAL',viewportType: 'volume',orientation: 'sagittal',initialImageOptions: {preset: 'middle',},syncGroups: [{type: 'voi',id: 'ctWLSync',source: false,target: true,},],},displaySets: [{id: 'ctDisplaySet',},{options: {colormap: 'hsv',voi: {windowWidth: 5,windowCenter: 2.5,},},id: 'ptDisplaySet',},],},],createdDate: '2021-02-23T18:32:42.850Z',},],numberOfPriorsReferenced: -1,
};function getHangingProtocolModule() {return [{id: 'oneByThreeProtocol',protocol: oneByThreeProtocol,},];
}

协议

id

协议的唯一标识符,此 ID 可以在模式配置中使用 指定应为特定模式使用哪个协议。一种模式可以 通过其 ID 请求协议(这使得 OHIF 在没有的情况下应用该协议 matching),或者提供一个 ID 数组,该数组将 使 ProtocolEngine 选择最佳匹配协议(基于 protocolMatching rules,这是下一节)。

imageLoadStrategy

图像加载策略指定了一个函数(按名称),其中包含要重新排序的逻辑 图像加载请求。这允许加载之前查看的图像 比装得更晚的早。可用的策略包括:

  • interleaveTopToBottom 从顶部开始,然后向底部工作,用于正在加载的所有序列
  • interleaveCenter 就像从上到下一样,但从中心开始
  • 第 n 个实例是加载每 n 个实例的策略,从中心开始 和终点,然后沿着图像逐渐填充。这导致部分 图像查看非常快。
protocolMatchingRules

协议的标准列表以及提供的排名分数。

  • weight:匹配规则的权重。最终,所有注册的 协议根据权重进行排序,获胜的协议获得 应用于查看器。
  • attribute:需要匹配的标签。这可以是 研究级元数据或自定义属性,例如“StudyInstanceUID”, “StudyDescription”, “ModalitiesInStudy”, “NumberOfStudyRelatedSeries”, “NumberOfSeriesRelatedInstances” 除了这些标签之外,您还可以使用之前注册的自定义属性。 我们稍后将对此进行详细了解。
  • from:表示属性的来源。这允许获取值 从其他对象(如实例对象)而不是从 当前的一个。prior
  • constraint:属性需要满足的约束。它接受的 a 可以是 [、、、、、validatorequalsdoesNotEqualcontainsdoesNotContainstartsWithendsWidth]
from 属性

该属性允许您从另一个对象中检索要测试的属性,例如上一个研究、研究的整个列表或模块中提供的其他值。from

OHIF 提供的值可供您使用:

  • activeStudy:使用活动研究的元数据进行匹配
  • studies:使用研究列表(所有研究)的元数据进行匹配
  • allDisplaySets:所有可用的显示集
  • displaySets:如果选择器与某个研究匹配,则这些是该研究的显示集
  • prior:研究列表中第一个研究的元数据,该研究不是活动研究
  • options:在匹配过程中,我们还提供了一个 Options 对象,其中包含您可以用作值的以下信息:from
  • studyInstanceUIDsIndex:研究列表中的研究索引
  • instance:被匹配实例的元数据,恰好是 displaySet.instance 元数据。
displaySetSelectors(必需)

定义协议将用于排列的显示集。

  displaySetSelectors: {ctDisplaySet: {seriesMatchingRules: [{weight: 1,attribute: 'Modality',constraint: {equals: {value: 'CT',},},required: true,},{weight: 1,attribute: 'isReconstructable',constraint: {equals: {value: true,},},required: true,},],},ptDisplaySet: {seriesMatchingRules: [{attribute: 'Modality',constraint: {equals: 'PT',},required: true,},{weight: 1,attribute: 'isReconstructable',constraint: {equals: {value: true,},},required: true,},{attribute: 'SeriesDescription',constraint: {contains: 'Corrected',},},],},}

如上所述,我们指定了两个 displayset:1) ctDisplaySet 、 2) ptDisplaySet ctDisplaySet 将与所有 CT 和可重构的系列匹配 ptDisplaySet 将与所有 PT 和可重构的系列匹配。

如您所见,每个选择器都由一个作为键和一组 (displaySetMatchingRules) 组成,后者为 displaySet 提供分数 根据匹配规则。得分最高的 displaySet 将用于 。idseriesMatchingRulesid

阶段

每个协议都可以定义一个或多个阶段。每个阶段都定义了特定的布局和视口规则。因此,该属性是一个对象数组,每个对象都是一个阶段。stages

viewportStructure(视口结构)

定义查看器的布局。您可以定义 和 的数量。应该有数量 属性中的视口配置。请注意,视口的顺序是首先是行,然后是列。rowscolumnsrows * columnsviewports

viewportStructure: {type: 'grid',properties: {rows: 1,columns: 2,viewportOptions: [],},
},

除了相等的视口大小外,您还可以定义视口以跨越多行或多列。

viewportStructure: {type: 'grid',properties: {rows: 1,columns: 2,viewportOptions: [{x: 0,y: 0,width: 1 / 4,height: 1,},{x: 1 / 4,y: 0,width: 3 / 4,height: 1,},],},
},
视口

此字段包括将挂在查看器上的视口。

viewports: [{viewportOptions: {viewportId: 'ctAXIAL',viewportType: 'volume',orientation: 'sagittal',initialImageOptions: {preset: 'middle',},syncGroups: [{type: 'voi',id: 'ctWLSync',source: true,target: true,},],},displaySets: [{id: 'ctDisplaySet',},],},// the rest
],

服务

具体的可以查看ohif官方文档哦~~~

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

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

相关文章

FTP服务器(服务名vsftpd,端口tcp/20和tcp/21)

目录 前言 配置文件 FTP服务器的配置 FTP服务的下载 配置防火墙 编辑配置文件 常用字段&#xff1a; 常用字段&#xff08;匿名用户&#xff09;&#xff1a; 常用字段&#xff08;系统用户&#xff09;&#xff1a; 指定系统用户访问&#xff1a; 编辑名单/etc/vsf…

leetcode_001_两数之和解析

两数之和解析 题目: 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。你可以按任意顺序…

代码随想录(day8)—环形链表

题目 预备知识点&#xff1a; for和while的区别 while语句属于循环语句&#xff0c;在判断是&#xff0c;如果条件为true&#xff0c;则会继续判断&#xff0c;直到false为止&#xff0c;即会进行多次判断&#xff08;除非一开始条件就是错的&#xff09;。 if语句属于条件判…

【Material-UI】Slider中的 Continuous Sliders 与 Sizes 详解

文章目录 一、Slider 组件概述1. 组件介绍2. 使用场景 二、Continuous Sliders 的详解1. Continuous Sliders 的作用2. Continuous Sliders 的基本用法3. 禁用状态下的 Continuous Sliders4. Continuous Sliders 的实际应用5. Continuous Sliders 的优缺点 三、Slider 的尺寸控…

005-CircuitBreaker断路器-Resilience4J

文章目录 1 CircuitBreaker1.1 实现原理1.2 一句话 2 Resilience4J2.1 是什么2.2 能干嘛2.3 怎么用 3 熔断(CircuitBreaker)(服务熔断服务降级)3.1 断路器三大状态3.2断路器3大状态之前的转换3.3断路器所有配置参数参考3.4 熔断降级案例需求说明3.5 COUNT_BASED(计数的滑动窗口…

科讯档案管理系统存在SQL注入漏洞(0day)

漏洞描述 安徽科迅教育装备20年来来始终坚持智慧校园集成方案产品的开发和部署应用&#xff0c;我们有完善的智慧校园和数字校园建设方案&#xff0c;根据不同的学校不同的实际情况量身定做系统集成方案。产品主要是为了实现校园的智慧网络、智慧OA、智慧教学、智慧学习、数字医…

整理了100个Python精选库,建议收藏!

Python为啥这么火&#xff0c;这么多人学&#xff0c;就是因为简单好学&#xff0c;功能强大&#xff0c;整个社区非常活跃&#xff0c;资料很多。而且这语言涉及了方方面面&#xff0c;比如自动化测试&#xff0c;运维&#xff0c;爬虫&#xff0c;数据分析&#xff0c;机器学…

三. Spring Boot 当中的“容器功能” 和 “配置绑定” 的详细剖析(附+源代码流程)

三. Spring Boot 当中的“容器功能” 和 “配置绑定” 的详细剖析(附源代码流程) 文章目录 三. Spring Boot 当中的“容器功能” 和 “配置绑定” 的详细剖析(附源代码流程)1. Spring Boot 是继续支持了 Spring 当中的注解的1.2 Spring 当中的 Component&#xff0c;Controller…

Unraid 手动安装docker

目录 常用镜像链接一.安装示例1[firefox浏览器]:1.离线下载docker镜像2.将xxx.tar镜像数据加载到 Docker 中3.手动添加docker 二.安装示例2[等我有东西需要安装再回来补教程吧]:三.获取UDI和GID 常用镜像链接 特别版 emby 文件管理器 filebrowser内外穿透 zerotierNAS媒体库管…

JavaEE 第16节 线程安全的集合类

目录 前言 顺序表 队列 哈希表 1、Hashtable 2、ConcurrentHashMap&#xff08;重点&#xff09; 前言 本文章主要介绍在多线程环境下&#xff0c;如何线程安全的使用一些常用的集合类&#xff08;顺序表和哈希表&#xff09;。 顺序表 1、自己使用同步锁机制&#xff…

大数据技术

4v特点 volume&#xff08;体量大&#xff09; velocity&#xff08;处理速度快&#xff09; variety&#xff08;数据类型多&#xff09; value&#xff08;价值密度低&#xff09; 核心设计理念 并行化 规模经济 虚拟化 分布式系统满足需求 系统架构 大数据处理流程 结构化…

CocosCreator 3.8 IOS 热更新失败问题解决方案

CocosCreator 3.8 IOS 热更新失败问题解决方案 问题描述 Creator 版本&#xff1a; 3.8.0目标平台&#xff1a; ios 模拟器/真机重现方式&#xff1a;安卓构建版本生成的热更新包&#xff0c;上传到OSS&#xff0c;使用ios进行更新。 19:18:36 [ERROR]: [ERROR] file /Applica…

动态读取nacos中修改的项目配置文件

本项目用的还是springboot项目&#xff0c;咱们直接上代码 一&#xff1a;首先看下nacos中需要动态获取的属性 二&#xff1a;把需要动态读取的配置类中的属性整理一个实体类 mport lombok.Data; import org.springframework.boot.context.properties.ConfigurationPropert…

PyCharm汉化:简单一步到胃!PyCharm怎么设置中文简体

最近在弄python的项目 一起加油哦 步骤&#xff1a; PyCharm的汉化可以通过两种主要方法完成&#xff1a; 方法一&#xff1a;通过PyCharm内置的插件市场安装中文语言包 1. 打开PyCharm&#xff0c;点击File -> Settings&#xff08;在Mac上是PyCharm -> Preferences…

[报错] nvcc -V 找不到

报错&#xff1a; nvcc : 无法将“nvcc”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;ObjectNotFound: (nvcc:String) [], CommandNotFoundExceptionFullyQualifiedErrorId : CommandNotFoundException 找不到 nvcc -V&#xff0c;试过…

erlang学习:用OTP构建系统1

书上案例学习并测试 23.1 通用事件处理 -module(event_handler). %% API -export([make/1, add_handler/2, event/2]).%% 制作一个“什么都不干”的事件处理器Name&#xff08;一个原子&#xff09;。这样消息就有地方发送了。 make(Name) ->register(Name, spawn(fun() -…

SoftMaker Office Pro 2024:高效办公的全方位解决方案

SoftMaker Office Pro 2024是一款集高效、专业、全面于一体的办公软件套件&#xff0c;专为满足现代办公需求而设计。这款套件不仅包含了文字处理、电子表格、演示文稿等核心功能&#xff0c;还集成了项目管理、文档管理和客户管理等实用工具&#xff0c;为用户提供了全方位的办…

微前端集成优化:让所有子应用体积更小,加载更快!

简介 随着前端的日益发展&#xff0c;微前端架构越来越受到青睐。它通过将前端应用拆分为多个独立的子应用&#xff0c;每个子应用可以独立开发、部署和运行&#xff0c;从而提升了开发效率和团队协作。目前主流的微前端方案应该是qiankun了。 以笔者公司为例&#xff0c;采用…

Go锁 详解

锁 - Go 函数并发编程中&#xff0c;锁是一种同步机制&#xff0c;用于协调对共享资源的访问&#xff0c;防止数据竞争 - Go 中提供了多种类型的锁&#xff0c;每种锁都有不同的特性和适用场景类型 互斥锁&#xff08;mutex&#xff09; 基础锁&#xff0c;只能同时允许一个 g…

okhttp异步请求连接阻塞问题排查

表现&#xff1a; 使用okhttp请求外部大模型接口时&#xff0c;当并发在2-5左右&#xff0c;出现请求被阻塞在建立http连接之前&#xff0c;阻塞时间超长&#xff08;>20s&#xff0c;从日志看有160s存在&#xff09;。但是httpconfig的connTimeout时间配置为100s&#xff…