2

所以我正在制作这个有大量图像的水平滚动网站。我计划在整个网站上使用 svg,但是页面中只使用了 20-30 个中到高复杂度的 svg 图片,而且 chrome 似乎已经显示出 som jank 和高绘制时间(而 Firefox 更糟糕,虽然野生动物园似乎做得更好)。

滚动时间线

长帧时间

查看站点(滚动仅适用于 mac,windows 用户可以使用箭头键)

我的问题是,如果我使用 pngs 而不是 svgs,它会减少绘画时间并因此减少卡顿吗?为什么浏览器只能处理大约 20 张 svg 图像?

4

2 回答 2

3

正如我所怀疑的那样,问题原来是完全不同的东西。浏览器不仅能够处理多个矢量图像。但是他们不擅长(并且可以理解)是经常重绘这些图像。

问题

我的长水平滚动站点非常宽(30,000 像素)。我有一个background-color属性应用于一个较低z-index的 'ed div 来代表整个滚动站点的天空。我不希望天空拉伸整个 30,000 像素,因为它基本上没有太大变化,因此给了它视口宽度和高度,其中:

position:fixed;

不是一个非常聪明的举动。事实证明,这个属性导致我的文档层在每一帧上都被重新绘制。最初,我认为浏览器在滚动时这样做是正常的,因为我用作参考的 Robby Leonardi 的网站也重新绘制了每一帧

解决方案

感谢chrome dev tools 开发者的这篇文章,我抛开传统智慧,做了天空层

position:absolute;

并将其拉伸到整个站点的宽度,然后繁荣!油漆矩形消失了。滚动性能比黄油更顺畅。

我尝试过的其他解决方案

  • 正如@philipp 所建议的那样,隐藏不在视口附近的元素以使绘画更轻,但没有产生任何明显的差异。此外,它感觉超级hacky,并且它没有针对问题的根本原因。

  • 我尝试将我的站点模块化为场景并translateZ(0)在每个场景上使用 hack,以便仅重新绘制较小的场景而不是文档。这实际上有很大帮助,并且滚动很不错。然后,我使用translateZ(0). 我现在开始获得大约 60 的 FPS,但同样,这不是正确的做事方式。

于 2015-11-05T22:30:06.197 回答
1

我曾经有过类似的事情。SVG 的宽度是上图的 10 倍或更多,它包含约 20k 个元素,大小约为 3MB。唯一带来性能的东西(因为它是一个跳跃和跑步游戏)是一种能够找到边界框与视口重叠的所有元素的算法。有了这个,我可以display: none;用来隐藏所有不可见的东西。

这将可见元素的数量减少到每帧约 150 个,并且游戏再次流畅地运行。

我使用了平衡二叉树(avl 树)和一维范围查询,因为视口的高度始终与图像相同。

祝你好运!

[编辑]

忘记留下诸如anwer之类的东西。根据我的经验,大型/巨大的 SVG 图形是渲染的瓶颈,尤其是在发生大量脚本的情况下。如果您不需要与 Graphic 中的元素进行任何交互,因此只需要一个大的背景图像,我建议使用基于 PNG 图像的 Tile 地图,这是 Jump'n'Run 游戏中的标准方式»worlds«,因此您可以在两点上获得性能:

  1. 渲染速度更快,
  2. 您可以根据可见性“延迟 ajax 加载”图块,以防止用户在启动时下载“整个世界”。

此外,您可以使用 PIXI.js 之类的东西来使用 WebGL 进行渲染,这将极大地提高性能,并支持 Tilemaps 和 Spritesheets。

如果您坚持 Vector Grafics(缩放、交互)的优势,那么您需要找到一种方法来隐藏尽可能多的元素以保持较高的帧速率。

于 2015-11-04T08:22:46.163 回答