Calling ko.toJS on Breeze entity causes slow long running script

时光怂恿深爱的人放手 提交于 2019-12-11 14:02:16

问题


When calling ko.toJS(entity) on any Breeze entity that has navigation properties or is part of a large object graph IE7-8 complain of long running script errors and even chrome can get bogged down for over 1 second.

What gives?!?


回答1:


I have had this plague me before and seen various forums or Github issues where this became an issue for devs. I wanted to share some knowledge in hopes that it helps others.

The problem

Breeze.js provides your client-side libraries or frameworks with an object graph. Calling JSON.stringify() on the entity will cause the dreaded stack overflow because some of the properties reference each other. Example -

Person -> Company -> Persons

Since a person has a navigation property of company that also has a navigation property of persons they continue to find each other.

ko.toJS() gets around this by detecting duplicates and stopping the serialization at that point.

Why is it slow?

The serialization takes longer depending on the number of entities in the object graph. Don't believe me? Load your app and call ko.toJS() then go load up a bunch more entities in the same object graph. It will take longer, guaranteed. The problem is that even if you call ko.toJS() on a single person Knockout isn't finding duplicates until it has serialized every person in the original persons company. This isn't a problem of Knockout nor Breeze - it is caused by how well interconnected everything is.

What can I do to fix it?

Using a projection query is the best solution, if you can. The problem is usually we need deeper nested levels of entities, not just the current entity. If your entity has a navigation property that has many related entities there is no easy way to perform a projection query, so we need to take it a step further in one of two manners -

  1. Write a custom serializer

  2. Vote for IdeaBlade (the company behind Breeze.js) to support unwrapping more efficiently

My opinion - expose a method on the entity manager to 'unwrap' that accepts the following parameters -

entityManager.unwrap(entity || [entities], [addtlTypesToUnwrap])

Where addtlTypesToUnwrap is either an array of strings or comma separated strings that define which related entity types to unwrap.

Example usage -

var thisEntity = manager.fetchEntityByKey('Person', 1, true);
var relatedProps = ['Company', 'Address']
entityManager.unwrap(thisEntity, relatedProps);

Which would unwrap Person, their address, their company, and the companies address (if it existed)



来源:https://stackoverflow.com/questions/22550560/calling-ko-tojs-on-breeze-entity-causes-slow-long-running-script

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!