我在 Angular.JS 中使用路由器(使用内置路由器,现在使用 ui-route,但两者的解决方案都很好)在控件/模板对之间切换。在这些页面之间来回切换时,每次设置 DOM 都需要一秒钟的时间,这看起来很糟糕。无论如何,是否有角度保留在 DOM 树周围,而不是每次都重新创建它。我想我只想隐藏/播种每一页的位,而不是每次都删除/重新创建它们。
欢迎任何建议!
我在 Angular.JS 中使用路由器(使用内置路由器,现在使用 ui-route,但两者的解决方案都很好)在控件/模板对之间切换。在这些页面之间来回切换时,每次设置 DOM 都需要一秒钟的时间,这看起来很糟糕。无论如何,是否有角度保留在 DOM 树周围,而不是每次都重新创建它。我想我只想隐藏/播种每一页的位,而不是每次都删除/重新创建它们。
欢迎任何建议!
您必须编写自己的 ng-view 指令来创建此类功能。
其背后的基本思想是:
在路由更改之前,您只需将其放入一个不可见的缓存 DIV 中,并取消注册范围侦听器,而不是破坏当前视图元素和范围。给元素一个 data 属性,$$route.templateUrl
以便能够取回它。然后从服务器获取下一个视图。
在路由更改之前,您检查缓存项是否存在,如果它在您的缓存 div 中,则从缓存中获取元素,重新注册侦听器并将当前视图放入缓存。
棘手的部分是不要把$scope
s 搞砸。所以你可能需要一个构造函数和析构函数$scope
来处理事件,也可能需要 $watchers。我不确定。
但说实话,如果你使用模板缓存仍然需要 1 秒左右的时间来渲染,那么你可能会有一些低效$watch
的表达,或者一个巨大的ng-repeat
. 你应该考虑一些重构。
我自己一直在研究这个。我正在一个未加速的浏览器中使用相当旧的硬件。初始渲染是个问题。正如您所尝试的那样,我早期的解决方法是缓存预编译的模板。我发现这仅提供了最小的速度改进。
真正的瓶颈来自我的 ng-repeat 指令、导致的回流次数以及我在每次迭代中构建的 DOM 节点/观察者的数量。
一些消息来源建议创建一个自定义指令,手动组装 dom 并一次性附加它。结果是非常小的回流并且没有观察者。缺点非常大。不再有角度的乐趣和大量不必要的工作。更重要的是,这些都没有提供足够大的速度改进来证明这项工作的合理性。
我最终发现,最好的速度提升来自于每次 ng-repeat 迭代强制硬件加速。如上所述,新版本 angular 中的 ng-animate 指令使这变得相对微不足道。
您将看到立即呈现页面,并有轻微的回流打嗝。ng-cloak 在这里没有帮助。由于动画请求,页面不应该在重复渲染时被隐藏。然而,这些可以通过一些巧妙的乐趣相当好地呈现。我实际上隐藏了 ng-repeat 直到 $location 更改,同时显示进度指示器,然后切换我的 ng-show。这真的很好用。
说了这么多,预编译你的模板应该如下完成。
1)当您的应用程序启动时,为自己创建一个新的缓存。请参阅http://docs-angularjs-org-dev.appspot.com/api/ng .$cacheFactory
2) 使用已编译的模板填充此缓存。注入 $compile 并在每个模板上调用它。编译返回一个函数,您稍后将针对您的范围调用该函数。在您认为合适的情况下将此功能键入您的缓存中。
3) 创建一个接受缓存键作为属性的自定义指令。在这个指令中,查询你的编译缓存以获得正确的编译函数。针对当前范围调用该函数,并将生成的 DOM 附加到传递给指令的元素。
4)排序胜利:)。
如果你升级到 Angular 1.1.5,你可以在你的 ng-view 标签上使用 ng-animate 属性。
我不是 100% 确定,但我认为它会进行一些 DOM 缓存以使过渡效果更好。您可以尝试在标签中添加添加 ng-animate 属性。那可能会为您解决。