Cornerstone3D导致浏览器崩溃的踩坑记录

WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost

⛳️ 问题描述

在使用vue3+vite重构Cornerstone相关项目后,在Mac本地运行良好,但是部署测试环境后,在window系统的Chrome浏览器中切换页面会导致页面崩溃。查看Chrome的任务管理器,单个Tab标签内存占用量会高达2G。

🔥 解决方案

  1. 对于性能较好的设备:在新版本中升级了Cornerstone的版本1.58 → 1.81,由于在1.69版本中Cornerstone升级了vtk.js的大版本,导致存在内存泄露不回收的问题,回退至1.58版本解决了页面崩溃的问题。

  2. 对于性能较差的设备:依照下文【2️⃣ 排查崩溃时的具体报错信息】设置浏览器配置项

🎯 复盘

主要排查流程如下:
在这里插入图片描述

1️⃣ 排查内存占用量

当收到测试反馈在windows系统上会崩溃的第一反应是:会不会内存占用过大导致了页面崩溃,所以查看了谷歌浏览器的任务管理器,果然一个Tab的占用量高达2G左右,从Cornerstone的A页面切换到B页面后,专用线程没有被销毁,当前页面的内存占用量在不断累加。

在任务管理器中可以查看有一个回退页面缓存,猜想是否是因为回退页面缓存导致了无法释放内存。

  • 尝试禁用回退页面缓存
# 在谷歌配置项中找到 back-forward-cache 项,设置为disabled,禁用浏览器回退缓存
chrome://flags/#back-forward-cache 
  • 禁用bfcache后,页面的worker会立即消失,消失内存占用空间没有释放,并没有解决页面崩溃的问题。

2️⃣ 排查崩溃时的具体报错信息

WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost

在github上查找是否有相关的issues,找到相关解决方案,设置后确实解决了页面崩溃问题

  • https://github.com/cornerstonejs/cornerstone3D/issues/453

  • https://github.com/OHIF/Viewers/issues/3207

大概翻译一下issues的解决方案就是:

  • 问题原因:Windows用户在使用某些型号的集成Intel GPU时,Chrome存在一个bug。导致OHIF和/或Cornerstone3D演示在渲染时出现问题,GPU进程在处理Volume视图时消耗过多的内存。因此,webGL上下文可能会丢失,进而导致浏览器崩溃。但是这个bug被确定是来自Chrome内部,而不是Cornerstone的问题,更具体地说是来自Chromium的Angle后端组件。

  • 解决方案:

    1. 确保自己的GPU没有被浏览器列入黑名单 - 在Chrome:flags中启用忽略黑名单功能,进入 chrome://flags/#ignore-gpu-blocklist 并设置为enable

    2. 使用最新的WebGL后端的Angle - 进入 chrome://flags/#use-angle 并设置值为最新值

      1. 对于Mac用户:推荐使用default,大多数情况下Mac的default值为 openGl

      2. 对于windows用户:如果有openGL选项,推荐使用openGl,如果是d3d11或d3d11on12,使用d3d11on12(PS:经测试,使用1.58版本时,windows系统的默认配置项d3d11也可以正常渲染,但是1.69+版本需要更高性能的配置项d3d11on12或openGl才可以保证正常渲染)

    3. 对于Edge用户:通过 edge://flags/#use-angle 设置同样的值; 对于firefox用户:通过 https://wiki.mozilla.org/Blocklisting/Blocked_Graphics_Drivers 设置

3️⃣ 排查导致原因

由上面第二条大约已经能确认导致页面崩溃卡死的是 WebGL后端的Angle ,但是vue3重构前的版本是没有问题的,于是去查看了Cornerstone3D的更新文档:https://github.com/cornerstonejs/cornerstone3D/releases,其中最有关联的为vtk的版本更新:从29.7→30.3, 那在vtk的30版本中主要更新了以下内容:

  • 自定义体积组件颜色混合

  • 曲面格式化

  • 👉 GPU 加速的图像重切片

  • 👉共享渲染窗口上下文

所以猜测是由该版本升级导致的,Cornerstone3D回退至 1.58版本暂时解决了windows下崩溃问题。对于性能比较差的在1.5x版本时也会崩溃的机器只能采取以上【2】中的处理方式,暂无更好的解决方案。

📣 其他解决方案可以重点关注上面两个issues的进展。

🏆 扩展

1. 回退页面缓存

页面回退缓存(Page Back-Forward Cache,简称 bfcache)是一种优化浏览器性能和用户体验的技术,它允许浏览器在用户通过浏览器的前进或后退按钮导航网页时,将页面保存在内存中以便快速加载,而不是重新加载整个页面。
但是页面缓存会占用浏览器的内存空间,对于一些本身内存就较小的设备可能会产生性能问题。

原理

当用户访问一个网页并随后导航到另一个页面时,浏览器会将第一个页面的状态(包括 DOM 树、JavaScript 状态、滚动位置等)保存在内存中。当用户点击浏览器的后退按钮返回到之前的页面时,浏览器可以直接从内存中恢复该页面,而不需要重新从网络加载。这大大加快了页面加载速度,并提供了更流畅的用户体验。

工作机制

缓存页面:

  • 当用户离开一个页面(导航到新页面)时,浏览器会判断当前页面是否可以被保存在 bfcache 中。

  • 如果页面符合条件,浏览器会将页面的整个状态保存到 bfcache 中。

页面恢复:

  • 当用户通过浏览器的前进或后退按钮导航回到之前的页面时,浏览器会从 bfcache 中检索页面并恢复其状态。

  • 这包括恢复 DOM 结构、JavaScript 状态、滚动位置等。

缓存条件

并不是所有页面都可以被保存到 bfcache 中,以下是一些常见的限制条件:

  1. 页面使用的资源:

    • 如果页面中有未完成的网络请求,或者有需要保持连接的资源(如 WebSocket => 这就是为什么本地运行Vue项目时没有bfcache,热更细机制基于websocket),那么该页面通常不会被保存到 bfcache 中。
  2. 页面生命周期事件:

    • 一些页面生命周期事件(如 unload 事件)可能会阻止页面被保存到 bfcache 中。
  3. 页面安全性:

    • 对于包含敏感信息的页面,浏览器可能会出于安全考虑而不将其保存到 bfcache 中。

2. webGL的angle

ANGLE(Almost Native Graphics Layer Engine)是一个图形引擎抽象层,旨在将OpenGL ES API转换为各种本地图形API。它最初是由Google开发,用于在不支持OpenGL ES的设备上实现图形兼容性。ANGLE在多个平台上提供了跨平台的图形渲染支持,特别是用于WebGL渲染的浏览器

angle产生的背景

OpenGL ES 是移动和嵌入式设备上广泛使用的图形API,但桌面平台(如Windows)并不天然支持OpenGL ES。为了使WebGL应用能够在更多的平台上运行,Google开发了ANGLE。

ANGLE提供了一个兼容OpenGL ES的实现,使得WebGL应用可以在更多的平台上运行而无需修改,能够提高跨平台图形应用的兼容性和性能。

angle 工作原理

ANGLE的核心功能是将OpenGL ES API调用转换为适用于不同平台的本地图形API调用,以下主要介绍两种(Direct3D 和 openGl)

  • Direct3D(d3d11,d3d11on12):在Windows平台上,ANGLE可以将OpenGL ES API转换为Direct3D 9或Direct3D 11的调用,d3d11on12 是一种特殊模式,使用Direct3D 12的功能来支持Direct3D 11的API调用。

  • OpenGL:对于支持原生OpenGL的设备,ANGLE可以直接使用OpenGL进行渲染。

angle 的常见问题

  • 内存消耗:在某些情况下,使用特定的ANGLE后端可能导致高内存消耗,导致WebGL上下文丢失或浏览器崩溃。可以尝试切换到不同的ANGLE后端来解决。

  • 兼容性问题:某些显卡或驱动程序可能与特定的ANGLE后端不兼容,导致渲染问题。检查和更新显卡驱动程序,或者切换到兼容的后端可以解决这些问题。

3. Direct3D 11(d3d11)和Direct3D 11 on 12(d3d11on12)

在上面复盘中,我们了解到在windows系统下,angle的配置项由 d3d11 切换为 d3d11on12,可以解决页面卡顿的问题,那简单介绍一下两者的区别

d3d11: Direct3D 11 是DirectX 11中的图形API,用于开发高性能的2D和3D图形应用,广泛应用于Windows平台上的游戏和图形应用。
d3d11on12: Direct3D 11 on 12 是一种特殊的运行时层,允许Direct3D 11的应用程序在Direct3D 12的基础上运行。目的是让现有的Direct3D 11应用程序能够利用Direct3D 12的优势,如更低的CPU开销和更好的多GPU支持。

底层实现的区别

  • Direct3D 11:直接与GPU驱动进行通信。

  • Direct3D 11 on 12:通过Direct3D 12层进行通信,将Direct3D 11 API调用转换为Direct3D 12命令。

性能优化

  • Direct3D 11:传统的单线程驱动调用,CPU开销较高。(🔥 所以在1.69+版本上,渲染volume时会使CPU飙升至100%导致导致页面卡顿甚至崩溃)

  • Direct3D 11 on 12:利用Direct3D 12的多线程和低开销特性,提高CPU效率和整体性能。

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

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

相关文章

浅析Kafka Streams消息流式处理流程及原理

以下结合案例&#xff1a;统计消息中单词出现次数&#xff0c;来测试并说明kafka消息流式处理的执行流程 Maven依赖 <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-streams</artifactId><exclusio…

【三维AIGC】扩散模型LDM辅助3D Gaussian重建三维场景

标题&#xff1a;《Sampling 3D Gaussian Scenes in Seconds with Latent Diffusion Models》 来源&#xff1a;Glasgow大学&#xff1b;爱丁堡大学 连接&#xff1a;https://arxiv.org/abs/2406.13099 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何…

Spring Security学习笔记(一)Spring Security架构原理

前言&#xff1a;本系列博客基于Spring Boot 2.6.x依赖的Spring Security5.6.x版本 Spring Security中文文档&#xff1a;https://springdoc.cn/spring-security/index.html 一、什么是Spring Security Spring Security是一个安全控制相关的java框架&#xff0c;它提供了一套全…

海外ASO:iOS与谷歌优化的相同点和区别

海外ASO是针对iOS的App Store和谷歌的Google Play这两个主要海外应用商店进行的优化过程&#xff0c;两个不同的平台需要采取不同的优化策略&#xff0c;以下是对iOS优化和谷歌优化的详细解析&#xff1a; 一、iOS优化&#xff08;App Store&#xff09; 1、关键词覆盖 选择关…

用node.js写一个简单的图书管理界面——功能:添加,删除,修改数据

涉及到的模块&#xff1a; var fs require(‘fs’)——内置模块 var ejs require(‘ejs’)——第三方模块 var mysql require(‘mysql’)——第三方模块 var express require(‘express’)——第三方模块 var bodyParser require(‘body-parser’)——第三方中间件 需要…

打造你的智能家居指挥中心:基于STM32的多协议(zigbee、http)网关(附代码示例)

1. 项目概述 随着物联网技术的蓬勃发展&#xff0c;智能家居正逐步融入人们的日常生活。然而&#xff0c;市面上琳琅满目的智能家居设备通常采用不同的通信协议&#xff0c;导致不同品牌设备之间难以实现互联互通。为了解决这一难题&#xff0c;本文设计了一种基于STM32的多协…

ant design form动态增减表单项Form.List如何进行动态校验规则

项目需求&#xff1a; 在使用ant design form动态增减表单项Form.List时&#xff0c;Form.List中有多组表单项&#xff0c;一组中的最后一个表单项的校验规则是动态的&#xff0c;该组为最后一组时&#xff0c;最后一个表单项是非必填项&#xff0c;其他时候为必填项。假设动态…

docker inspect 如何提取容器的ip和端口 网络信息?

目录 通过原生Linux命令过滤找到IP 通过jq工具找到IP 使用docker -f 的过滤&#xff08;模板&#xff09; 查找端口映射信息 查看容器内部细节 docker inspect 容器ID或容器名 通过原生Linux命令过滤找到IP 通过jq工具找到IP jq 是一个轻量级且灵活的命令行工具&#xf…

(视频演示)基于OpenCV的实时视频跟踪火焰识别软件V1.0源码及exe下载

本文介绍了基于OpenCV的实时视频跟踪火焰识别软件&#xff0c;该软件通过先进的图像处理技术实现对实时视频中火焰的检测与跟踪&#xff0c;同时支持导入图片进行火焰识别。主要功能包括相机选择、实时跟踪和图片模式。软件适用于多种场合&#xff0c;用于保障人民生命财产安全…

OpenGL笔记二之glad加载opengl函数以及opengl-API(函数)初体验

OpenGL笔记二之glad加载opengl函数以及opengl-API(函数)初体验 总结自bilibili赵新政老师的教程 code review! 文章目录 OpenGL笔记二之glad加载opengl函数以及opengl-API(函数)初体验1.运行2.重点3.目录结构4.main.cpp5.CMakeList.txt 1.运行 2.重点 3.目录结构 01_GLFW_WI…

Python-PLAXIS自动化建模技术与典型岩土工程

有限单元法在岩土工程问题中应用非常广泛&#xff0c;很多软件都采用有限单元解法。在使用各大软件进行数值模拟建模的过程中&#xff0c;您是否发现GUI界面中重复性的点击输入工作太繁琐&#xff1f;从而拖慢了设计或方案必选进程&#xff1f; 搭建自己的Plaxis模型&#xff…

设计模式的七大原则

1.单一职责原则 单一职责原则(Single responsibility principle)&#xff0c;即一个类应该只负责一项职责。如类A负责两个不同职责&#xff1a;职责1&#xff0c;职责2。当职责1需求变更而改变A时&#xff0c;可能造成职责2执行错误&#xff0c;所以需要将类A的粒度分解为A1、…

安卓14中Zygote初始化流程及源码分析

文章目录 日志抓取结合日志与源码分析systemServer zygote创建时序图一般应用 zygote 创建时序图向 zygote socket 发送数据时序图 本文首发地址 https://h89.cn/archives/298.html 最新更新地址 https://gitee.com/chenjim/chenjimblog 本文主要结合日志和代码看安卓 14 中 Zy…

C/C++ 进阶(7)模拟实现map/set

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 一、简介 map和set都是关联性容器&#xff0c;底层都是用红黑树写的。 特点&#xff1a;存的Key值都是唯一的&#xff0c;不重复。 map存的是键值对&#xff08;Key—Value&#xff09;。 set存的是键…

Git的命令使用与IDEA内置git图形化的使用

Git 简介 Git 是分布式版本控制系统&#xff0c;它可以帮助开发人员跟踪和管理代码的更改。Git 可以记录代码的历史记录&#xff0c;并允许您在不同版本之间切换。 通过历史记录可以查看&#xff1a; 进行了哪些更改&#xff1f;谁进行了更改&#xff1f;何时进行了更改&#…

网络安全高级工具软件100套

1、 Nessus&#xff1a;最好的UNIX漏洞扫描工具 Nessus 是最好的免费网络漏洞扫描器&#xff0c;它可以运行于几乎所有的UNIX平台之上。它不止永久升级&#xff0c;还免费提供多达11000种插件&#xff08;但需要注册并接受EULA-acceptance–终端用户授权协议&#xff09;。 它…

在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——聚合与搜索(三)

#在生产环境中部署Elasticsearch&#xff1a;最佳实践和故障排除技巧——聚合与搜索&#xff08;三&#xff09; 前言 文章目录 前言- 聚合和分析- 执行聚合操作- 1. 使用Java API执行聚合操作- 2. 使用CURL命令执行聚合操作- 1. 使用Java API执行度量操作- 2. 使用CURL命令执…

谷粒商城实战笔记-34-前端基础-ES6-promise异步编排

文章目录 一&#xff0c;回调地狱&#xff08;Callback Hell&#xff09;二&#xff0c;实战Promise1&#xff0c;场景说明2&#xff0c;回调地狱-传统实现3&#xff0c;使用Promise重构3.1 用Promise实现上述需求3.2 进一步重构 在ES6中&#xff0c;Promise是一个用于异步编程…

网络安全-内网安全加固方案

内网接入限制(MAC地址白名单) 只允许信任设备接入内网&#xff0c;且每次自动获取的IP地址不变(后续就可根据IP地址控制访问权限) 开启DHCP服务根据MAC地址静态分配固定IP地址 只允许可信的DHCP服务器分配IP地址(防止私建DHCP服务器) DHCP Snooping 信…

在Vue中,子组件向父组件传递数据

在Vue中&#xff0c;子组件向父组件传递数据通常通过两种方式实现&#xff1a;事件和回调函数。这两种方式允许子组件与其父组件进行通信&#xff0c;传递数据或触发特定的行为。 1. 通过事件传递数据 子组件可以通过触发自定义事件&#xff0c;并将数据作为事件的参数来向父组…