SlideShare a Scribd company logo
1 of 26
CLIENT CODE BEST
PRACTICES
Yuval Dagai
Agenda
• Why?
• Performance as a feature
• Request the minimal data needed for operation
• Minimize the use of observables
• Bindings
• Batch queries
• Knockout tips
• Style
Why?
• Lessons learned from R2
• Raise awareness
• Performance as a feature
• Knowledge sharing
• Writing better code
Performance as a feature
• Critical rendering path
• Optimizing the Critical Rendering Path – By Ilya Grigorick (Google)
• Youtube - http://www.youtube.com/watch?v=YV1nKLWoARQ
• Perceived performance vs. Actual performance
http://www.mobify.com/blog/beginners-guide-to-perceived-
performance/
Request minimal data needed – Why?
• Improve performance
• Promote perceived performance.
• Reduce the network bandwidth required for the request.
• Reduce server time handling the request.
• Simple requests may help optimizing cache control.
• Give better control on data.
• Control data bindings.
• Memory considerations
• Less data received less memory to consume.
• Reduce GC cycles when loading and removing the view.
Request minimal data needed - how
• Only get data for the immediate visible view or operation.
• Try to split large query into smaller queries.
• This will enable a more flexible control on data requests.
• For lists limit the request for the amount of possible visible elements plus 50%.
• This will create overflow that enables live scroll to get the next results.
• For extensive calculations:
• Best if server can do it.
• Try to do a special background request for calculation logic.
• Defer the calculation until after applyBinding (after calling loading.resolve())
and run it in a setTimeout(calc, 0) so it will not block any rendering.
• Consider web worker (threading).
Request minimal data needed - how
• Any user click data related should be requested when the
user clicks.
• Use projection wherever possible.
• Projection limits the number of properties retrieved for the entity
request.
• It is equivalent to the select clause in SQL. Represent as $select
parameter in OData querystring.
• In JayData use the map function.
Projection usage
• JayData map function defines
the object retrieved in the
results.
• Note that the object in the
results will not be JayData
entity.
Request minimal needed data - how
• Example: Goal page
• Ux requirement:
• View mode:
• Show expanded goal hierarchy down to initiative
• Only name, short description, description and status is visible
• Investments are collapsed but their count should be visible.
• Some strategy info is needed for authorization
• Investment allocation aggregated calculation is needed
• On user menu selection
• Edit entity form
• Add entity form
• Delete entity
• Entity details popup
Example - Goal Page
Example – Autocomplete solution
• R1 autocomplete (filter box)
• Get everything on load
• Enable filtering on the full list
• Practically it was filter box not an
autocomplete.
• R2 autocomplete
• On load get enough data to create the
overflow and scrollbars.
• As a rule of thumb we can use 150% of
visible items.
• Query server on user typing to filter the list.
• Use live scroll to get next paged data.
Minimize the use of observables – why?
• Observables are great way to sync between view and view-model,
However, they have costs.
• Each observable is a function that internally can be related to other
observables by subscriptions.
• This is great when we gain the advantages of data synchronization
but its better to avoid it’s overkill when unnecessary.
Minimize the use of observables - how
• Use observables only when necessary.
• 2 way binding:
• Edit modes when user input is needed.
• Updated content:
• Show or hide according to user action.
• Updated counter or calculations.
• etc...
• Any static binding use simple js object.
• Do not use it as variable
• komap is evil
• komap.fromJS (fromJD) is a brut force – it maps whole object with observables
• komap on JD entity clone the JD object and creates observables on each property destroying
the JD behavior.
• The process create a block and produce many GC events. This can be illustrated in next slide…
komap is evil – Test case
There are 3 lists of
initiatives include strategy
all get the first 200 items.
The only binded property is
the initiative name
1. Left list use projection
on the initiative name.
2. Middle use no projection
and no komap.
3. Right list do komap.
The width of the flame chart
express the time to do the
rendering of the list after
response.
komap alternatives
• There is a JayData module for Knockout that integrates
both libraries we name it JDKO.
• JDKO add behavior to JD toArray function that detects an
observableArray passed as parameter and then add knockout
observable behavior to it, BUT keep JD behavior in tact.
• komap have a mapping options object that you can pass
as an optional parameter to the fromJS function.
• Using this mapping you can define what properties should be
observed, ignored, copy or include.
Bindings
• Use on demand binding.
• Defer binding of hidden elements to display time.
• Views that are not visible should be fetched and bind at the time they
needed mainly when user click to show.
• Handle data processing before setting binded observable.
• Example: A list is binded to an observableArray. The list needs to
be processed or even filtered.
• In this case do the filter or process the array and then when it is
ready for display set it on the observableArray to be displayed.
• This will do the rendering process in one pass and not force the
browser to parse html, calculate style layout and paint on each item
pushed into the observableArray.
Bindings
• Binded observable register to the change event by default. Therefore:
• Avoid binding change events. Use subscribe or computed observables
instead.
• Bad
• totalValueHasChanged is a function – could be subscribe to totalPlanned, which
includes the validateNum logic as well. Alternatively use the writable computed
observable.
• Good
• totalPeriod is a computed observable.
Bindings
• The subscribe function can be done on any event. Just
pass the event name as the third parameter to the
subscribe callback.
• Example: The beforeChange event can be used to get the
old value before the change. See how it is done for attach
detach:
Bindings
• One last thing… please write maintainable bindings!
• Bad… bad example: Its only 3 <a> tags
Batch queries - why
• Batch query aggregate multiple queries into one and send
it to the server as one query. Server execute all queries
and create one response.
• Reduce the amount of requests and all it’s overhead.
• Reduce the risk of server/db deadlocks.
• Reduce the risk of cache synchronization issues.
Batch queries - how
• Currently server supports only POST/PUT queries in
batch queries.
• Batch query protocol allows queries in batch to reference
each other and have dependencies between them.
• Batch query
URL:http://localhost:8080/sp/osvc/Batch/$batch?$format=j
son
• JayData create batch query automatically when context
(db) has more than one entity to change/add.
Batch queries - how
• Example for JayData query that creates batch query:
Knockout tips
• ko.utils.unwrapObservable(x) – get the value of x
whether it is observable or not. No need to check for
function.
• ko.isObservable(x) – check if x is observable.
• ko.isWriteableObservable(x) – check if x is a writable
observable. Non writable observable can be a read only
computed observable.
• ko.dataFor(element) - returns the data that was available
for binding against the element.
• ko.contextFor(element) - returns the context that was
available for binding against the element.
Style
• Avoid using selectors
specific to the view’s DOM
• Favor element, classes and
id’s selectors
• Page view should have a
specific id
Performance of Style JS changes
• When changing style in a loop, cache the object style
property before the loop and use cached value.
• Bad example, Good Example
Q & A

More Related Content

What's hot

What's hot (9)

Ajax
AjaxAjax
Ajax
 
Hibernate performance tuning
Hibernate performance tuningHibernate performance tuning
Hibernate performance tuning
 
Struts2-Spring=Hibernate
Struts2-Spring=HibernateStruts2-Spring=Hibernate
Struts2-Spring=Hibernate
 
Before you optimize: Understanding Execution Plans
Before you optimize: Understanding Execution PlansBefore you optimize: Understanding Execution Plans
Before you optimize: Understanding Execution Plans
 
jQuery
jQueryjQuery
jQuery
 
Pentest Application With GraphQL | Null Bangalore Meetup
Pentest Application With GraphQL | Null Bangalore Meetup Pentest Application With GraphQL | Null Bangalore Meetup
Pentest Application With GraphQL | Null Bangalore Meetup
 
SharePoint 2010 Content Query Web Part
SharePoint 2010 Content Query Web PartSharePoint 2010 Content Query Web Part
SharePoint 2010 Content Query Web Part
 
ASP.NET Routing & MVC
ASP.NET Routing & MVCASP.NET Routing & MVC
ASP.NET Routing & MVC
 
Query Tuning Azure SQL Databases
Query Tuning Azure SQL DatabasesQuery Tuning Azure SQL Databases
Query Tuning Azure SQL Databases
 

Viewers also liked

Non-Physical Violence 8.12.2014
Non-Physical Violence 8.12.2014Non-Physical Violence 8.12.2014
Non-Physical Violence 8.12.2014
Jacquie Pinkerton
 
Series-RioCommunitiesIncorporation-Dec2012-Jan2013
Series-RioCommunitiesIncorporation-Dec2012-Jan2013Series-RioCommunitiesIncorporation-Dec2012-Jan2013
Series-RioCommunitiesIncorporation-Dec2012-Jan2013
Julia Dendinger
 

Viewers also liked (11)

How to avoid being marked as spam christoph pass next lead generation (long v...
How to avoid being marked as spam christoph pass next lead generation (long v...How to avoid being marked as spam christoph pass next lead generation (long v...
How to avoid being marked as spam christoph pass next lead generation (long v...
 
Non-Physical Violence 8.12.2014
Non-Physical Violence 8.12.2014Non-Physical Violence 8.12.2014
Non-Physical Violence 8.12.2014
 
Elmhurst TechNet Stirling 090915
Elmhurst TechNet Stirling 090915Elmhurst TechNet Stirling 090915
Elmhurst TechNet Stirling 090915
 
Default file icengine
Default file icengineDefault file icengine
Default file icengine
 
Rajamundry
RajamundryRajamundry
Rajamundry
 
4 Examples of How Postup Can Help Retailers & eCommerce
4 Examples of How Postup Can Help Retailers & eCommerce4 Examples of How Postup Can Help Retailers & eCommerce
4 Examples of How Postup Can Help Retailers & eCommerce
 
Lighthouse Publishing Ministry Presentation
Lighthouse Publishing Ministry PresentationLighthouse Publishing Ministry Presentation
Lighthouse Publishing Ministry Presentation
 
Resume (Sales)
Resume (Sales)Resume (Sales)
Resume (Sales)
 
Presentation1
Presentation1Presentation1
Presentation1
 
Eaganathan
EaganathanEaganathan
Eaganathan
 
Series-RioCommunitiesIncorporation-Dec2012-Jan2013
Series-RioCommunitiesIncorporation-Dec2012-Jan2013Series-RioCommunitiesIncorporation-Dec2012-Jan2013
Series-RioCommunitiesIncorporation-Dec2012-Jan2013
 

Similar to Client Best Practices

Multi-tier-performance-analysis-of-ADF-applications.pptx
Multi-tier-performance-analysis-of-ADF-applications.pptxMulti-tier-performance-analysis-of-ADF-applications.pptx
Multi-tier-performance-analysis-of-ADF-applications.pptx
Kuncoro21
 
State management 1
State management 1State management 1
State management 1
singhadarsh
 
How Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting PlatformHow Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting Platform
Hien Luu
 
Drupal Site Audit - SFDUG
Drupal Site Audit - SFDUGDrupal Site Audit - SFDUG
Drupal Site Audit - SFDUG
Jon Peck
 

Similar to Client Best Practices (20)

Multi-tier-performance-analysis-of-ADF-applications.pptx
Multi-tier-performance-analysis-of-ADF-applications.pptxMulti-tier-performance-analysis-of-ADF-applications.pptx
Multi-tier-performance-analysis-of-ADF-applications.pptx
 
Cloud dwh
Cloud dwhCloud dwh
Cloud dwh
 
DrupalSouth 2015 - Performance: Not an Afterthought
DrupalSouth 2015 - Performance: Not an AfterthoughtDrupalSouth 2015 - Performance: Not an Afterthought
DrupalSouth 2015 - Performance: Not an Afterthought
 
Dynamics CRM high volume systems - lessons from the field
Dynamics CRM high volume systems - lessons from the fieldDynamics CRM high volume systems - lessons from the field
Dynamics CRM high volume systems - lessons from the field
 
Day 7 - Make it Fast
Day 7 - Make it FastDay 7 - Make it Fast
Day 7 - Make it Fast
 
State management 1
State management 1State management 1
State management 1
 
Auditing Drupal Sites for Performance, Content and Optimal Configuration - SA...
Auditing Drupal Sites for Performance, Content and Optimal Configuration - SA...Auditing Drupal Sites for Performance, Content and Optimal Configuration - SA...
Auditing Drupal Sites for Performance, Content and Optimal Configuration - SA...
 
Performance tuning Grails applications SpringOne 2GX 2014
Performance tuning Grails applications SpringOne 2GX 2014Performance tuning Grails applications SpringOne 2GX 2014
Performance tuning Grails applications SpringOne 2GX 2014
 
How Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting PlatformHow Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting Platform
 
.NET Fest 2019. Halil Ibrahim Kalkan. Implementing Domain Driven Design
.NET Fest 2019. Halil Ibrahim Kalkan. Implementing Domain Driven Design.NET Fest 2019. Halil Ibrahim Kalkan. Implementing Domain Driven Design
.NET Fest 2019. Halil Ibrahim Kalkan. Implementing Domain Driven Design
 
AngularJS
AngularJSAngularJS
AngularJS
 
Performance tuning Grails applications
Performance tuning Grails applicationsPerformance tuning Grails applications
Performance tuning Grails applications
 
ASP.NET MVC 5 - EF 6 - VS2015
ASP.NET MVC 5 - EF 6 - VS2015ASP.NET MVC 5 - EF 6 - VS2015
ASP.NET MVC 5 - EF 6 - VS2015
 
Performance tuning Grails Applications GR8Conf US 2014
Performance tuning Grails Applications GR8Conf US 2014Performance tuning Grails Applications GR8Conf US 2014
Performance tuning Grails Applications GR8Conf US 2014
 
Framework Enabling End-Users to Maintain Web Applications (ICICWS2015)
Framework Enabling End-Users to Maintain Web Applications (ICICWS2015)Framework Enabling End-Users to Maintain Web Applications (ICICWS2015)
Framework Enabling End-Users to Maintain Web Applications (ICICWS2015)
 
Drupal Site Audit - SFDUG
Drupal Site Audit - SFDUGDrupal Site Audit - SFDUG
Drupal Site Audit - SFDUG
 
Boosting the Performance of your Rails Apps
Boosting the Performance of your Rails AppsBoosting the Performance of your Rails Apps
Boosting the Performance of your Rails Apps
 
Advanced Analytics using Apache Hive
Advanced Analytics using Apache HiveAdvanced Analytics using Apache Hive
Advanced Analytics using Apache Hive
 
AWS re:Invent 2016| DAT318 | Migrating from RDBMS to NoSQL: How Sony Moved fr...
AWS re:Invent 2016| DAT318 | Migrating from RDBMS to NoSQL: How Sony Moved fr...AWS re:Invent 2016| DAT318 | Migrating from RDBMS to NoSQL: How Sony Moved fr...
AWS re:Invent 2016| DAT318 | Migrating from RDBMS to NoSQL: How Sony Moved fr...
 
Grails Services
Grails ServicesGrails Services
Grails Services
 

Client Best Practices

  • 2. Agenda • Why? • Performance as a feature • Request the minimal data needed for operation • Minimize the use of observables • Bindings • Batch queries • Knockout tips • Style
  • 3. Why? • Lessons learned from R2 • Raise awareness • Performance as a feature • Knowledge sharing • Writing better code
  • 4. Performance as a feature • Critical rendering path • Optimizing the Critical Rendering Path – By Ilya Grigorick (Google) • Youtube - http://www.youtube.com/watch?v=YV1nKLWoARQ • Perceived performance vs. Actual performance http://www.mobify.com/blog/beginners-guide-to-perceived- performance/
  • 5. Request minimal data needed – Why? • Improve performance • Promote perceived performance. • Reduce the network bandwidth required for the request. • Reduce server time handling the request. • Simple requests may help optimizing cache control. • Give better control on data. • Control data bindings. • Memory considerations • Less data received less memory to consume. • Reduce GC cycles when loading and removing the view.
  • 6. Request minimal data needed - how • Only get data for the immediate visible view or operation. • Try to split large query into smaller queries. • This will enable a more flexible control on data requests. • For lists limit the request for the amount of possible visible elements plus 50%. • This will create overflow that enables live scroll to get the next results. • For extensive calculations: • Best if server can do it. • Try to do a special background request for calculation logic. • Defer the calculation until after applyBinding (after calling loading.resolve()) and run it in a setTimeout(calc, 0) so it will not block any rendering. • Consider web worker (threading).
  • 7. Request minimal data needed - how • Any user click data related should be requested when the user clicks. • Use projection wherever possible. • Projection limits the number of properties retrieved for the entity request. • It is equivalent to the select clause in SQL. Represent as $select parameter in OData querystring. • In JayData use the map function.
  • 8. Projection usage • JayData map function defines the object retrieved in the results. • Note that the object in the results will not be JayData entity.
  • 9. Request minimal needed data - how • Example: Goal page • Ux requirement: • View mode: • Show expanded goal hierarchy down to initiative • Only name, short description, description and status is visible • Investments are collapsed but their count should be visible. • Some strategy info is needed for authorization • Investment allocation aggregated calculation is needed • On user menu selection • Edit entity form • Add entity form • Delete entity • Entity details popup
  • 11. Example – Autocomplete solution • R1 autocomplete (filter box) • Get everything on load • Enable filtering on the full list • Practically it was filter box not an autocomplete. • R2 autocomplete • On load get enough data to create the overflow and scrollbars. • As a rule of thumb we can use 150% of visible items. • Query server on user typing to filter the list. • Use live scroll to get next paged data.
  • 12. Minimize the use of observables – why? • Observables are great way to sync between view and view-model, However, they have costs. • Each observable is a function that internally can be related to other observables by subscriptions. • This is great when we gain the advantages of data synchronization but its better to avoid it’s overkill when unnecessary.
  • 13. Minimize the use of observables - how • Use observables only when necessary. • 2 way binding: • Edit modes when user input is needed. • Updated content: • Show or hide according to user action. • Updated counter or calculations. • etc... • Any static binding use simple js object. • Do not use it as variable • komap is evil • komap.fromJS (fromJD) is a brut force – it maps whole object with observables • komap on JD entity clone the JD object and creates observables on each property destroying the JD behavior. • The process create a block and produce many GC events. This can be illustrated in next slide…
  • 14. komap is evil – Test case There are 3 lists of initiatives include strategy all get the first 200 items. The only binded property is the initiative name 1. Left list use projection on the initiative name. 2. Middle use no projection and no komap. 3. Right list do komap. The width of the flame chart express the time to do the rendering of the list after response.
  • 15. komap alternatives • There is a JayData module for Knockout that integrates both libraries we name it JDKO. • JDKO add behavior to JD toArray function that detects an observableArray passed as parameter and then add knockout observable behavior to it, BUT keep JD behavior in tact. • komap have a mapping options object that you can pass as an optional parameter to the fromJS function. • Using this mapping you can define what properties should be observed, ignored, copy or include.
  • 16. Bindings • Use on demand binding. • Defer binding of hidden elements to display time. • Views that are not visible should be fetched and bind at the time they needed mainly when user click to show. • Handle data processing before setting binded observable. • Example: A list is binded to an observableArray. The list needs to be processed or even filtered. • In this case do the filter or process the array and then when it is ready for display set it on the observableArray to be displayed. • This will do the rendering process in one pass and not force the browser to parse html, calculate style layout and paint on each item pushed into the observableArray.
  • 17. Bindings • Binded observable register to the change event by default. Therefore: • Avoid binding change events. Use subscribe or computed observables instead. • Bad • totalValueHasChanged is a function – could be subscribe to totalPlanned, which includes the validateNum logic as well. Alternatively use the writable computed observable. • Good • totalPeriod is a computed observable.
  • 18. Bindings • The subscribe function can be done on any event. Just pass the event name as the third parameter to the subscribe callback. • Example: The beforeChange event can be used to get the old value before the change. See how it is done for attach detach:
  • 19. Bindings • One last thing… please write maintainable bindings! • Bad… bad example: Its only 3 <a> tags
  • 20. Batch queries - why • Batch query aggregate multiple queries into one and send it to the server as one query. Server execute all queries and create one response. • Reduce the amount of requests and all it’s overhead. • Reduce the risk of server/db deadlocks. • Reduce the risk of cache synchronization issues.
  • 21. Batch queries - how • Currently server supports only POST/PUT queries in batch queries. • Batch query protocol allows queries in batch to reference each other and have dependencies between them. • Batch query URL:http://localhost:8080/sp/osvc/Batch/$batch?$format=j son • JayData create batch query automatically when context (db) has more than one entity to change/add.
  • 22. Batch queries - how • Example for JayData query that creates batch query:
  • 23. Knockout tips • ko.utils.unwrapObservable(x) – get the value of x whether it is observable or not. No need to check for function. • ko.isObservable(x) – check if x is observable. • ko.isWriteableObservable(x) – check if x is a writable observable. Non writable observable can be a read only computed observable. • ko.dataFor(element) - returns the data that was available for binding against the element. • ko.contextFor(element) - returns the context that was available for binding against the element.
  • 24. Style • Avoid using selectors specific to the view’s DOM • Favor element, classes and id’s selectors • Page view should have a specific id
  • 25. Performance of Style JS changes • When changing style in a loop, cache the object style property before the loop and use cached value. • Bad example, Good Example
  • 26. Q & A

Editor's Notes

  1. Best Practices Request the minimal data needed for operation. De-couple view from view-model. Minimum binding Code complexity Knockout Use observable only on dynamic parts komap is evil Minimize bindings Use on demand binding – don’t bind all data at once. Minimize the use of observable Handle data processing before setting observable (before binding) Avoid binding change events Use ko.utils.unwrapObservable JayData Projection ($select, map) Batch queries Use JD behavior of changedProperties JDKO ResetChanges Style Avoid view’s DOM specific selectors Favor element, classes and id’s selectors Page view should have a specific id Performance Performance as a feature Critical rendering path Time for first pixel paint Perceived performance vs. Actual performance Get only displayed data in init method Split requests GC issues DevTools