Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn off observables in stache to help performance #691

Open
justinbmeyer opened this issue May 19, 2019 · 0 comments
Open

Turn off observables in stache to help performance #691

justinbmeyer opened this issue May 19, 2019 · 0 comments

Comments

@justinbmeyer
Copy link
Contributor

This example renders slow: https://codepen.io/anon/pen/yWgmoq?editors=0011

Part of the issue is that there is a decent amount of live binding within 2 levels (actually 3) of nested looping:

200 rows X 6 columns X 7 bindings = 8400

That means there's likely tens of thousands of observables that need to be created to render this template.

However, it's likely that we could create a single observable for each row. This would limit the number of observables to some multiple of 200 (probably 2x). We could do this by having a single observable for an entire row's content:

image

When any part of the row changed, we could simply replace the entire row again. This wouldn't be as efficient as diffing (which could come later), but it would still improve performance quite a bit.

This could work with a special helper that would wrap some stache logic. It could look like:

{{#for(row of visibleItems)}}
  {{#logicOnly}}
    <tr>
            {{#for(entity of row)}}  ... {{/for}}
    </tr>
  {{/logicOnly}}
{{/for}}

{{#logicOnly}} would tell stache to build logic-only expressions. Instead of new Call, it could build new CallLogic(). EXPRESSIONLogic constructors would only perform the logic and not return an observable.

{{#logicOnly}} would probably need to work on parse-time.

Testing this

To test if this is a viable strategy, we should have a helper render equivalent JS code that produces the content of a row. It could look like:

stache.addHelper("rowContent", function(row){
  var fragment = document.createDocumentFragment();
  for( let entity of row ){
    var tr = document.createElement("tr");
    tr.appendChild( BUILD_STUFF_THAT_GOES_IN_TR( ... )
    fragment.appendChild( tr );
  }
  return fragment;
})

rowContent will wrap the building of that fragment with a single observable, just like {{#logicOnly}} would do. If this is much faster, then we should continue looking at this method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants