【问题标题】:AngularJS and big JSON dataAngularJS 和大 JSON 数据
【发布时间】:2018-10-23 19:47:45
【问题描述】:

对于使用来自我一直在创建的 API 的数据的自定义 AngularJS 应用程序,我遇到了 Angular oboe 的使用。 Oboe 是一个 Bower 包,可帮助将大型 JSON 文件流式传输到视图。因此,经过反复试验,我设法构建了一个不错的双簧管GET 方法,该方法在大约 2 秒内获得了大约 4000 个 JSON 项目。但是当向同一个视图添加更多 GET 方法时,我的问题就开始了。

起初没有任何问题,但最终,加载时间越来越长。所以我尝试使用双簧管Cached: true 配置。可悲的是它根本不起作用。每次我加载页面时,所有数据都会再次加载,而不是从browser Cache获取

在下面的示例中,您可以看到我一直在尝试缓存的双簧管功能之一的结构。下面还添加了一个 JSfiddle 链接。

函数和视图

 function createProduct(id, name) {
        this.id = id;
        this.name = name;
    }

    $scope.products = [];

    oboe({
        url: 'config/get/getProducts.php',
        method: 'GET',
        cached: true
    }).path('products.product.*', function () {
        // we don't have the person's details yet but we know we
        // found someone in the json stream. We can eagerly put
        // their div to the page and then fill it with whatever
        // other data we find:
    }).start(function () {
        console.log("start");
    }).node('products.product.*', function (products) {
        // we just found out their name, lets add it
            // to their div:
            $scope.products.push({
                id: products.id,
                name: products.name.language
            });
            $scope.totalItems = $scope.products.length;
            return new createProduct(products.id, products.name);
    }).done(function () {
        console.log( $scope.products );
    });

    // Refresh data
    $scope.refreshData = function() {
        cartService.refreshData()
            .then(function(response) {
                $scope.cartItems = response.cartItems;
                $scope.totalCartItems = response;
                $scope.selectedCustomer = response;
            })
    };
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="productimg col-lg-4 col-md-4" ng-repeat="product in products | limitTo : limit : (currentPage - 1) * limit track by product.id"
             ng-class="{lastItem: $last}" scroll-bottom="event">
            <div class="row">
                <div class="col-md-12" ng-bind="product.id"></div>
                <div class="col-md-12">
                    <a ng-bind="product.name" href="{{product.id}}.nl"></a>
                </div>
            </div>
        </div>
        <div class="col-lg-12 text-center margin-t-30">
            <ul uib-pagination
                total-items="totalItems"
                ng-model="currentPage"
                items-per-page="limit">
            </ul>
        </div>

JSfiddle 你可以看到代码。我无法让 JSON 在 JSfiddle 上运行,但将其视为以下行,然后是大约 10000 个“产品”行。

{"products":{"product":[{"id":"1240","id_manufacturer":"0","id_supplier":"0","id_category_default":"2","id_tax_rules_group":"8","quantity":"0","id_shop_default":"1","reference":{},"ean13":"0","price":"0.000000","active":"0","date_add":"2014-07-15 12:06:34","date_upd":"2018-04-21 12:22:37","name":{"language":"zie voorschot factuur 03"}},{"id":"1241","id_manufacturer":"0","id_supplier":"0","id_category_default":"2","id_tax_rules_group":"8","quantity":"0","id_shop_default":"1","reference":{},"ean13":"0","price":"0.000000","active":"0","date_add":"2014-07-15 12:06:41","date_upd":"2018-04-21 12:22:37","name":{"language":"zie voorschot factuur 04"}},{"id":"8908","id_manufacturer":"0","id_supplier":"15","id_category_default":"2","id_tax_rules_group":"8","quantity":"0","id_shop_default":"1","reference":"041002","ean13":"5712084210057","price":"45.454545","active":"1","date_add":"2015-11-12 18:03:47","date_upd":"2017-11-18 09:57:27","name":{"language":"Vaavud Sleipnir smartphone wind meter"}}}}

所以我面临的真正困难是从网络选项卡获取数据大约需要十秒钟。 (“getProducts.php”中有一个 API 请求)。然后将其解析到视图大约需要 30 秒。 (太长了)。其次,我想缓存getProducts请求,以便下次加载视图时直接获取产品。使用普通的$http.get()cache: true。它有效,但我仍然面临着缓慢的绑定,即使是双簧管。

如果需要更多信息,请在下面的 cmets 中告诉我。

一如既往,提前致谢!

【问题讨论】:

  • 一次性发送所有产品本身更像是一个糟糕的设计。您应该使用分页以及只传递所需的数据。
  • @TarunLalwani 首先它是一个基于 REST API 的 HTTP 请求。所以我确实需要在一个请求中调用完整的数据。其次,知道这不是最好的方法,但它是搜索所有项目所必需的。这是一个单页应用程序,这意味着不应调用任何刷新。我尝试使用分页,但我需要找到一个中间解决方案来说
  • 产品多久更换一次?因为一个小改动就意味着缓存失效,这种方法将变得毫无用处
  • @TarunLalwani 不那么频繁,可能一天两次,或者如果添加了新产品则更频繁
  • 我对其他事情无能为力,但您不应该每次都直接推送到范围变量。创建一个常规数组推入其中,一旦流完成,将其分配给范围数组。如果是 10000 个项目,它应该确实有助于绑定。

标签: javascript html angularjs json oboe.js


【解决方案1】:

我们有一个像这样的项目,它有太多的 API 和大量的对象数据。我们使用的一些技巧如下:

1-数组而不是对象

通过对这些数据结构的一些搜索和阅读,您会发现对象消耗的内存比数组使用的内存要多。因此,将您的对象数组转换为服务器端的数组数组。

2-多使用一级缓存

将数据存储在服务器端缓存中,例如 MongoDb 和 Redis。使用以下步骤处理请求:

  1. 检查浏览器缓存。如果数据可用且是最新的,请使用此数据。

  2. 如果浏览器中没有数据,则向服务器发送请求。检查服务器端缓存。如果数据可用且是最新的,则将此数据发送给客户端并将其存储在缓存中并使用它。

  3. 如果服务器缓存中没有数据,则向API发送请求并获取数据,将其存储在服务器缓存中,然后将其发送回客户端并将其存储在缓存中并使用它。

3-每次发送客户端所需的最少数据

客户可能不会停留在页面中并查看显示的所有数据。准备每个页面所需的最少数据,如果客户要求,请携带其他数据。

对于您的情况,而不是 10,000 个产品,只需准备其中的 1000 个,如果客户需要更多,准备更多数据,附加到您的客户端缓存并显示它。

如果客户需要所有 10,000 种产品,请在多个请求中准备它们。

阅读更多here

4-在浏览器中缓存数据,模块好,以正确的方式再次读取数据

为 AngularJs 准备了一些模块。了解他们、他们的标准和最佳实践。拥有良好的客户端缓存非常重要。

ngStorage

希望这些提示对您有所帮助。

【讨论】:

  • 5.切勿在大型阵列上使用任何角度过滤器
  • 这是最好的评论,它是对多个组件和技巧的回答,可以并且会在开发应用程序时帮助我。我没有测试上述所有内容,但我确实看到了这些技巧的一些改进,所以谢谢。 @Petr Averyanov,过滤器应该是独立的,以提高数据速度。 PS:当我在我的电脑上时,我会奖励赏金。
猜你喜欢
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多