【问题标题】:How to let angularjs show fast part first, then render slow part?如何让angularjs先显示快速部分,然后渲染慢速部分?
【发布时间】:2013-02-21 04:00:45
【问题描述】:

我有一个很大的angularjs html页面,angularjs的渲染会花很多时间。所以页面一开始几乎是空白的,过了一会儿,它突然显示一切。

不知道有没有什么办法可以让快的部分先显示,慢的部分在后显示,这样用户就不会对空白页感到惊讶了。

我做了一个简单的演示:

<!DOCTYPE html>

<html ng-app>
<head>
    <meta charset="UTF-8">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
</head>
<body ng-controller="Ctrl">
<button ng-click="go()">Go</button>
<hr/>
<div>Fast</div>
<button ng-repeat="name in fastNames">{{name}}</button>
<hr/>
<div>Slow</div>
<button ng-repeat="name in slowNames">{{name}}</button>
</body>
</html>
<script type="text/javascript">
    function Ctrl($scope) {
        $scope.fastNames = [];
        $scope.slowNames = [];

        $scope.go = function () {
          $scope.fast();
          $scope.slow();
        }

        $scope.fast = function() {
          $scope.fastNames = ["F1", "F2"];
        };

        $scope.slow = function() {
          for (var i = 0; i < 50000000; i++) {
            new Date();
          }
          $scope.slowNames = ["S1", "S2"];          
        }


    }
</script>

您可以看到有两个部分——“快速名称”和“慢速名称”。我希望快的名字能尽快出现,然后是慢的名字。不过暂时先不显示,过段时间再一起显示。

我创建了一个现场演示:http://plnkr.co/edit/9lW2TbLBkCB1hhgBVGmo?p=preview

我该怎么办?

【问题讨论】:

  • 在 go() 返回之前,视图不会更新。将你的 go() 函数分成两部分:gofast() 和 goslow()。在超时或其他情况下调用 goslow() 以允许 gofast() 在 goslow() 启动之前返回。
  • 似乎可行:plnkr.co/edit/uI7gROjmlA6SCFD0SpXh?p=preview>,但它是“angularjs 方式”吗?我需要手动添加$scope.$digest()
  • 我刚刚发现它可以在 chrome 上运行,但不能在 firefox 上运行。
  • 使用$timeout 服务,您无需调用$digest。然后你可以做$timeout($scope.slow)
  • 谢谢,它适用于 chrome。在 Firefox 上仍然无法正常工作?

标签: angularjs


【解决方案1】:

正如 cmets 中提到的,浏览器在go() 返回之前不会有机会呈现(JavaScript 是单线程的)。拆分go() 函数并将慢速部分放入一个单独的函数中,该函数通过$timeout 异步调用。为确保浏览器在调用 $timeout 回调之前有机会呈现,请给 $timeout 50 毫秒的延迟。

$scope.go = function () {
   $scope.fast();
   $timeout(function() {
      $scope.slow();
   },50);  // give browser time to render
};

Plunker

【讨论】:

  • 如何确定最佳超时延迟? 50ms 是否始终适用于主流浏览器?
  • @Freewind,无法确定浏览器何时完成渲染。在这篇 stackoverflow.com/questions/11125078/… 的帖子中,Nic 定期检查 DOM 中的某些内容以确定渲染是否完成。
猜你喜欢
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 2023-03-22
  • 2010-09-13
  • 2016-01-25
相关资源
最近更新 更多