首页 > 其他分享 >记录--浏览器渲染15M文本导致崩溃怎么办

记录--浏览器渲染15M文本导致崩溃怎么办

时间:2023-08-10 18:40:55浏览次数:40  
标签:分界点 浏览器 -- range end 文本 15M 节点

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

最近,我刚刚完成了一个阅读器的txt文件阅读功能,但在处理大文件时,遇到了文本内容过多导致浏览器崩溃的问题。

一般情况下,没有任何样式渲染时不会出现什么问题,15MB的文件大约会有3秒的空白时间。

<div id="content"></div>
fetch('./dp.txt').then(resp => resp.text()).then(text => {
  document.getElementById('content').innerText = text
})

尽管目前还没有严重的问题,但随着文件继续增大,肯定会超过浏览器内存限制而导致崩溃。

在开发阅读器的过程中,我添加了下面的样式,结果导致浏览器直接崩溃:

* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body {
  column-fill: auto;
  column-width: 375px;
  overflow-x: auto;
}

预期结果应该是像下面这样分段显示:

 然而,实际出现了下面的问题:

因此,文件内容太多会导致浏览器崩溃。即使进行普通的渲染,我们也要考虑这个问题。

如何解决

解决这个问题的方法有点经验的前端开发工程师应该都知道可以使用虚拟滚动,重点是怎么对文本分段分段,最容易的可能就是按照一定数量字符划分,但是这个导致文本衔接不整齐出现文本跳动。如图,橙色和蓝色表示两端文本的衔接,虚拟滚动必然会提前移除橙色那块内容,那么就会导致蓝色文本位置发生改变。

要解决这个问题,我们需要想办法用某个元素替代原来的位置。当前页橙色部分删除并计算位置,问题会变得复杂并且误差比较大,因此这一部分直接保留,把这部分前面的内容移除,然后用相同长度的元素占据,接下来重点就是怎么获取到橙色部分与前面内容的分界点。

获取分界点可以使用document.createRange()document.createRange()是 JavaScript 中用于创建Range对象的方法。Range对象表示一个包含节点与文本节点之间一定范围的文档片段。这个范围可以横跨单个节点、部分节点或者多个节点。

// 创建 Range 对象
const range = document.createRange();

range.setStart(textNode, 0); // 第一个参数可以是文本节点,第二个参数表示偏移量
range.setEnd(textNode, 1);
const rect = range.getBoundingClientRect(); // 获取第一个字符的位置信息

利用Range对象的特性,我们可以从橙色部分的最后一个字符开始计算,直到找到分界点的位置。

阅读器如果仅仅只是从左往右阅读,按照上面的方法已经可以实现,但是阅读器可能会出现页面直接跳转,跳转之后的文本起点你并不知道,并且页面总页码你也无法知道。因此从一开始就要知道每一页的分界点,也就是需要做预渲染。以下是一个简单的示例:

let text = '...'
const step = 300
let end = Math.min(step, value.length) // 获取结束点

while (text.length > 0) {
  node.innerText = value.substring(0, end) // 取部分插入节点
  const range = document.createRange()
  range.selectNodeContents(node)
  const rect = range.getBoundingClientRect() // 获取当前内容的位置信息

  if (rect.height > boxHeight) {
    // 判断当前内容高度是否会超出显示区域的高度
    // 如果超出,从 end 最后一个字符开始计算,直到不超出范围
    while (bottom > boxHeight) {
      // node.childNodes[0] 表示文本节点
      range.setStart(node.childNodes[0], end - 1)
      range.setEnd(node.childNodes[0], end)
      bottom = range.getBoundingClientRect().bottom
      end--
    }
  } else {
    // 如果没有超出,end 继续增加
    // ...
  }
}

上面只是简单的实现原理,可以达到精确区分每一页的字符,但是计算量有点太大,15MB文本大约500多万字,循环次数估计也在几十万到上百万。在本人的电脑上测试大约需要20秒,每个人设备的性能不同,所需时间也会有所不同。很明显,这种实现方式并不太理想。

后来我对这个方案进行了优化,实际上我们不需要计算每一页的分界点,可以计算出多页的分界点,例如10页、20页、50页等。优化后的代码是将step增大,比如设为10000,然后将不能组成一页的尾部内容去掉。优化后,15MB的文本大约需要4秒左右。需要注意的是,step并不是越大越好,太大会导致渲染页面占用时间过长。

这就是我目前用来解决页面渲染大量文本的方法。如果你有更好的方案,欢迎留言。

本文转载于:

https://juejin.cn/post/7261231729523965989

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

标签:分界点,浏览器,--,range,end,文本,15M,节点
From: https://www.cnblogs.com/smileZAZ/p/17621185.html

相关文章

  • 关于多行文本框默认选中内容样式
    有的项目页面是禁止选中文本的,但是输入框是个特例,需要单独设置样式,即选中内容时的背景颜色;textarea{outline:none;background:transparent;outline:medium;}*:focus{outline:none;background-c......
  • Hadoop集群启停命令以及Web UI界面的相关介绍
    1、Hadoop集群的启停命令(我是将文件都配置好了,直接使用最方便的启停命令就能进行使用)start-all.shstop-all.sh2、HDFS集群的WebUI界面主要是通过命令行:ifconfig获取到本虚拟机的ip地址,然后输入:ip:9870进行访问即可3、YARN集群的WebUI界面可以使用以下命令访问:ht......
  • Arctime字幕插件——影视剧字幕神器
    到官网上面去下载这个软件把素材导入进来打开文本,把文本导入到ArctimePro里面选中这个然后就可以在上面拖拽了可以改变样式导出就好了......
  • Linux:find命令
     1、前言从各个维度(类型、时间、权限、大小……)查找文件2、用法find路径选项动作3、选项选项说明时间①内容修改时间(modificationtime,mtime)文件内容变更时,会更新该时间②状态修改时间(statustime,ctime)文件状态变更(权限、属性……)时,会更新该时间③访问......
  • Spring Cloud Alibaba全解析:构建可靠的分布式系统
    标题:SpringCloudAlibaba全解析:构建可靠的分布式系统引言:随着互联网技术的不断发展,分布式系统的概念和应用越来越广泛。作为构建可靠和弹性的分布式系统的关键技术之一,SpringCloudAlibaba提供了一套完整的解决方案,帮助开发者更轻松地构建和管理分布式系统。本文将全面解析Spri......
  • Next.js - App Router Vs. Pages Router 详细对比
    多年来,我们将页面放置在Next的“pages”目录中。现在这种情况即将改变。不久前,Next.js推出了新的AppRouter,显着改变了我们创建页面的方式。但不仅是我们存储应用程序页面的目录发生了变化,而且可用的功能也发生了变化。我们的下一个项目过去是这样的:└──pages├......
  • 分布式系统架构设计思想
    1.计算与存储分离 2.接口幂等,业务幂等,防重提交 3.功能性需求,非功能性需求之间的取舍平衡 4.数据的冷热分离 5.高内聚,低耦合,模块化设计,分层,防腐层,DDD  6.分布式系统,三大件  Redis,MQ,分布式数据库(1.满足事务处理简单,2.能快速......
  • docker初识
    docker什么是Docker微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦。分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署,环境不一定一致,会遇到各种问题应用部署的环境问题大型项目组件较多,运行环境也......
  • 二叉树和B树
    1、树(Tree)的基本概念 节点、根节点、父节点、子节点、兄弟节点一棵树可以没有任何节点,称为空树一棵树可以只有1个节点,也就是只有根节点子树、左子树、右子树节点的度(degree):子树的个数树的度:所有节点度中的最大值叶子节点(leaf):度为0的节点非叶子节点:度不为0的节点......
  • pip离线下载安装工具包
    1,为什么需要pip离线安装工具包开发需要进行环境配置,如果在服务器上配置开发环境,由于各种各样的原因,可能会遇到服务器端是封闭环境,只能连接内网的情况。这就需要提前下载好安装包,在使用pip本地安装。2,如何安装单个离线包(1)如果环境配置端有联网条件,则直接在线安装即可:#pipinst......