当前位置: 首页 > 网络应用技术

性能优化,有时是体育工作

时间:2023-03-07 14:30:46 网络应用技术

  性能优化是一个古老的主题。祖先经常说,但是对于确定几乎所有内容的IDE产品,优化性能优化还为时过早。除非我们这样做(性能问题)除非您直到您不存在,否则直到您不存在直到您的使用者卡无法忍受并表达。该卡主要反映在慢速开放,完成缓慢的完成,接口Katto等。在前几篇文章中,我们逐渐优化了一定程度的启动(并继续)。对于代码完成,我们的基于LSP的机制已优化用于音量压缩。接口渲染性能实际上并未针对。主要原因是对于IDE来说,视图太复杂了,因此在绩效优化方面,似乎无处可寻。

  Opensumi使用React渲染视图层。总的来说,在这方面,官方文件和社区的性能优化不过是。我们的Google可以在该领域找到许多经验和原则。通过非常简单的组件拆分,恒定零件分开以避免昂贵的重复。

  当然,本文的前提是您的申请状态已足够合理。例如,对于只有本地视图的状态而言,避免将它们提高到高水平,这将导致其他组件不关心该州被动更新的国家,但是对于Opensumi来说,不好的消息是我们有大量使用MOBX,并通过分开模型/视图来管理整个应用程序状态。从某种意义上说,这些模型是全球性的。具有可观察到的MOBX的特征,我们可以轻松地使用以下方法来更新服务物种中的状态。

  在正常情况下,父层的层层中将有大量组件。对于子组件的底层,任何更改都会触发组件的渲染,这意味着可以优化本文中的方法。空间非常有限。在删除MOBX的前提下,我们似乎只使用常规和流行并开始优化。

  在React Dev工具的帮助下,您可以快速找到一些明显的性能问题。例如,当我们检查某些操作时,我们会发现一些似乎被渲染的地方也触发了渲染。

  Opensumi将近30w的代码,包括大量的树,列表,输入模型,按钮,菜单等。对于上图中的这些表演,可以说这很糟糕。您可以清楚地看到某些菜单和按钮都在那里。让我们找到一个相对简单的部分开始优化。

  与其他面板相比,搜索仅包含4个输入框和少量按钮,即复选框,似乎更简单地优化。在开始之前,他们就是这样

  可以看出,由于全球状态的影响,任何点击或输入操作都会触发整个面板重新施用,这显然是不合理的。

  除了将局部状态和依赖视图拆分为独立组件(前面提到的),对于大量的全球状态/道具变化,我们仍然可以拆分组件。不同之处在于,这种拆除是拆除的,分裂的想法是尽可能减少全球状态/道具对其他组件的变化的影响。例如,在上面的图中,单击时将修改某个状态,这些状态将在其中引入。这将导致所有组件,例如复选框和图中的输入,因为它们已更改。

  例如,我们将它们分开,例如,根据不同的功能将它们分成组件。目前,我们只需要使用包装即可避免这种过多的渲染。因为react.memo仅比较一个简单的基本类型,因此可以忽略费用。

  当然,由于这里的实施也包括各种规则,因此代码将比此更复杂

  对于特定代码,您可以看到此PR

  菜单看起来不明显,但存在于IDE中,尤其是当Opensumi与VS代码插头兼容时,插头-in可以注入自定义菜单,按钮等。底层是相同的抽象,但是在不同位置呈现不同的样式。

  如图所示,这些不起眼的菜单已被触发为操作。从理论上讲,这些是不必要的,不应该经常渲染。每次是新的。任何面板的启用者都会生成一个新的菜单实例,每个菜单都将重新构建内部menuitem。

  每个菜单实例可能都有数百个微型,而且看似不起眼的菜单实际上非常昂贵。但是,经过简单的调查,发现有多个重复的创作。

  钢琴之手的折叠面板的逻辑每次渲染此组件时都会尝试获取它。如果没有,它将被重新创建。Titlemenu是一个菜单实例,是ID中的ID。

  在实际实施中,返回是直接返回的,不会缓存它。这会导致面板上的任何操作引起的渲染,这将重新创建菜单实例,这将导致内部menuitem重新租赁。

  但是,事实并不是那么简单。当我安装最新版本的gitlens插头-in时,整个面板加载时立即被卡住。加载结束后,Patton结束了,左右拖动,整个接口的帧速率都丢弃了对于数字数字。有些日志发现,目前与Gitlens相关的菜单实例创建了将近900次(这里有另一个坑)。随着拖动面板,该数字仍在上升,最终创建了3K次。尽管这些多余的菜单将被破坏,但此过程仍将带来非常昂贵的性能费用。

  实际上,代码也很简单,只需在插件中注册菜单时添加缓存

  可以看出,任何遗漏都可能导致性能瓶颈。通常,性能瓶颈不是很复杂。

  对于特定代码,您可以看到此PR

  树几乎是IDE的最重要视图部分,例如文件树,符号树,依赖树等。依靠TreeView来实现丰富和多样的功能。它及回收池本身的性能实际上靠近甚至部分超过大多数TreeView。但是,它看起来也是一个非常可靠的组件,如果使用不当,它仍然会导致严重的性能问题。

  TreeView本身不支持拖动,但是大量的TreeView面板支持左右,上下更改大小。如前所述,在Gitlens面板中拖动框架掉落-Off框架。实际上,除了经常创建菜单外,另一个问题是视图阻力后宽度的变化引起的。

  这里没有明显的口吃

  可以清楚地看到由React DevTools录制的屏幕截图,作为拖动操作,整个TreeView中的TimeItem是重新填充的。原因实际上很简单。因为在拖动时面板和两者都会发生变化,并且使用Recycletreein项时,代码的这一部分将通过宽度和高度传递,因此宽度本身是不必要的道具,因此解决方案非常简单。

  整个ID中的Treeview中有很多位置,大多数维修方法都是相似的

  删除不必要的宽度道具后

  M1 Pro也充满了血液,在这里仍然可以看到肉眼。

  相关PR

  请记住,前面提到的吉特伦斯(Gitlens)与性能战斗很长时间,Gitlens Plug -in是测量性能的最佳合作伙伴。Gitlens插头本身以及各种菜单和TreeView都很多,因此此项目就是这个ProjectPackage.JSON实现了惊人的10,000行。

  vscode-gitlens/package.json在main·gitkraken/vscode-gitlens·github

  经过一轮优化后,菜单和树景等性能瓶颈在激活过程中仍然看起来很明显(在另一个Intel CPU的Mac上)。

  英特尔Mac下的屏幕截图可以看到,当提交面板加载时,界面显然出现了,甚至编辑的编码器在结束后也呈现。

  这是一个构造树视图的节点,但是在第一个屏幕上加载的提交未达到此级别。这种卡住更像是大量的dom repainting。在此段落的性能是Chrome devtools的性能,发现确实有2.5秒的JavaScript脚本。这里。单击长期任务以查看呼叫堆栈。最长的时间消耗以前被忽略了。

  我们熟悉的老朋友吉特伦斯(Gitlens)在此处注册了大量的treenode,该图标用于显示commartter avatar。它将拉下社区的头像,将其注册为图标,并区分浅色/暗模式。

  vscode-gitlens/commit.ts,请参见CF771368305DABED8D09393DFE30E181E181E181E260·Gitkraken/vscode-gitlens·github

  但是,即使是数百个图标也不太可能立即引起如此严重的口吃。真正的问题出现在注册图标后将其转换为CSS样式的步骤中。

  数量取决于提交和社区的数量。在这种情况下,当使用VSCODE回购时,第一次将根据注册的图标模式加载400 x 2个图标,该图标将转换为CSS类,即样式类似

  然后将每个图标类样式插入样式标签中,问题是,当此操作重复数千次时,整个DOM树的重新启动将导致非常严重的口吃。要解决此问题,它是为了插入图标类操作从插头 - 插入样式标签中。

  经过简单的优化,再次加载gitlens后的效果是,尽管仍然有点口吃,但它比以前好得多。它不会再陷入几秒钟。同时,编辑编辑将正常加载。

  代码可以直接查看PR。

  如果仔细观察,您会发现几乎所有面板都在整个IDE接口中。当相应的一侧(例如宽度)变化时,计算其新尺寸,这将是相同的,这将是相同的,这将是相同的。事件广播。对于面板的组件,您可以从Props获取一个称为ViewState的对象,该对象包含面板和高度信息。

  实际上,除了前面提到的外,某些组件不需要与宽度更改相关,而且这里确实没有问题。还将触发渲染。

  例如,如果在此处切换任何选项卡,则将其面板重新施加一次。原因是OpenSumi用于监视事件,并且当视图隐藏时(显示:无),该事件仍会触发,并且在显示时也将触发该事件:block。也就是说,一个开关中将有两个渲染费用,但实际上,这是不必要的,因为在开关操作的简单性下,面板的大小没有改变。这里的优化方法是在这种情况下不广播事件。具体来说,使用userf来缓存以前的大小。切换后,如果没有更改或大小直接变为0。那么优化就是这样,它将发送事件

  代码可以看到PR

  本文仅列出了一些相对明显的性能优化过程,并且在这里不会启动一些较小的优化过程。可以看出,大多数性能瓶颈都是由开发过程中的遗漏引起的。严格来说,没有非常困难的优化点。许多可能只是写作的变化。例如,组件的Props功能使用软件包代替匿名函数代替匿名函数。或添加大量数据/视图操作以添加缓存,批处理合并处理和其他策略。或拆分组件,将更改分开并且在视图中不变的部分,并避免由其他道具更新引起的渲染。当然,对于IDE,应该在开始时考虑这些要点。我也希望本文能够为读者带来一些灵感。绩效优化也许有时不是技术问题,而是体力劳动。

  欢迎明星和玩Opensumi

  原始:https://juejin.cn/post/7103353421691879461