salesforce performance hacks - client side
Post on 16-Apr-2017
1.250 Views
Preview:
TRANSCRIPT
Salesforce Performance hacks
Client side
© Jean-Luc Antoine - @ApexAPI – January 2016
Agenda
• Understanding client side performance
• Designing for performance
• Analyzing
• Benefits of Service Workers
• A Performance Framework
“80-90% of the end-user response time is spent on the frontend. Start there.”
Steve Souders – (Yahoo/Google)
Foreword
• Performance impacts
Productivity
Revenue loss
Employee satisfaction
Customer satisfaction
Brand reputation
Poor performance
Signup
Self care
Application
renewal
Waiting time
Operations/hour
Response time
Project rework
Performance fix
Project cost increase
Man days
Cost of analysis Scalability Infrastructure
costs
Compensate
Introduction to client side perf
Browser configuration
• Use a recent version
• Enable browser caching
• Configure cache size (>50 Mb but not too big)
• Cache behavior to check automatically for new version
• Allow saving encrypted pages on disk
• You can do some cleaning by clearing cache and cookies – Cookies are increasing bandwidth required per page
Page optimization
• Reduce viewstate
• Reduce hits
• Leverage CDN
• Keep it light (amount of data, DOM)
• Async (scripts, computation, loading…)
• Minimize
• Low RAM
JS/CSS delivery
• Minified
• Combine into 1 file – Reducing hits
• Avoid inline style to reduce the size of the page – Using style from the css will get the Cache benefits
• Avoid frameworks if not required – Ex : loading jQuery just to hide a DOM element
• Use static resource – Leveraging the CDN
Images optimization hacks
• Image format (PNG, GIF, JPEG, SVG…) – Image encoding
• Image size, quality and metadata
• Quantity (hits and DOM)
• Lazy loading
• Cookie-free CDN and caching
• CSS and sprites (reducing hits)
Real life example https://www.salesforce.com/content/dam/blogs/us/December2015/Butterfly16.png
412x360 pixels, 22452 bytes Can be recompressed using Zopfli into 20024 bytes (12% gain)
https://partners.salesforce.com/s/rsz_spring_16.png?v=1 190x166 pixels, 29 517 bytes smaller but heavier !!
A poor conversion from a small image can be 47.4% heavier than a good compression on a big image !!
4kb cookies in the request
Pictures count for 62% of the weight of a page and 65% of the hits
Performance analysis in the browser
• Browser Developer Tools
• The Cache Effect – same page – 68 requests, 349 kb, 12 secs 59 requests, 30 kb, 2 seconds
Focusing on the essential On the platform
Size and complexity (downloading) Network
Content of page has loaded (parsing finished)
Page resource finished loading Issue
Removing noise • <apex:page showHeader="false" standardStylesheets="false">
Still injecting 1 script No conventional way to remove it
<html><head><script src="/static/111213/js/perf/stub.js" type="text/javascript"></script></head><body>
Blocking and synchroneous
Sometimes side effects
Findings
• Injected javascript in the header is blocking and can add 0.3 seconds response time
• A simple picture that is not found can generate 0.8 seconds response time increase
Introducing Service Workers
• HTTPS • Same domain
– Page, js file, scope
• Scope /apex/ • Dedicated .js file
– Using Promises (async)
• Running in background, event driven
• Commonly used for offline purpose (managing cache) as a replacement for AppCache
• We will use it as a local proxy
XMLHttp Window.fetch() Src= PAGE SW Resource
HIT
Using Service Workers in VF VisualForce
<apex…> Your Content … <script> •Register Service Worker </script> </apex>
Javascript file (Rendered through VisualForce to be on the same domain) Service Worker •Registered •Installed (oninstall) •Activated (onactivate)
Loading VF Page
Registering SW
Installing
Activating
VisualForce
Any included resource (hit)
(re)Loading Controlling (proxy/fetch)
Response
Improvements with SW 1/3
• Removing unwanted platform scripts
– Returning empty script without fetching the real script • This will avoid any network hit
• This will still trigger SW code
– Removing the script from the source code • No hit, no SW trigger
Good choice but not the best
Best strategy
Improvements with SW 2/3
• Removing noise (404 on static files)
– Checking the status code from each fetch() • If 404 code returned, remember the request and next time serve
an empty file
• No maintenance required
– Removing the script from the source code • No hit, no SW trigger
• Not adaptive (to be maintained on a regular basis to identify new 404 or remove old filtered files)
Best strategy
Quick win
Improvements with SW 3/3
• Removing unwanted headers
– Ex : cookies when querying pictures, css or js files
• Forcing some content into the cache
Code : Activating the SW
• No need to put the code on all VF pages
– Once it is activated, it will work for any page in the scope.
– Example : the page can be added in a VF page on the home
Scope is Visualforce
Visualforce page name that is hosting the SW javascript
Improvement only if SW enabled
Code : the SW
• Hosted in a Visualforce page (same domain, https)
Not supported by Salesforce
• We have worked on the Visualforce scope only.
• You should not inject script on Standard pages even if you can do it. The risk to break the user interface is too high.
A performance framework
• We need to:
– Access the whole performance metrics, finest grain
– Automate performance retrieval
– Store measures
– Automate analysis
– Have nice reports/dashboards
– Have no deployment
– Have no performance impact !
The Idea
• Existing systems designed to measure performance have performance impacts on the targeted system and can’t split the time spent into the right areas – Including a script is adding a network roundtrip to the web page
– Custom logic of the script is taking time during the page load
– Using old fashioned Date().now() is lacking accuracy (browser timer error: rounded to 15ms) • High resolution timers are required
• We need a system that will have an extremely light footprint on the targeted system – Requiring no network access during the page load
– Using an high resolution timer
– Consuming no CPU during the page load
• This system could be used by any of Salesforce customers
• The benefits – Performance analysis made easily
– Capability to extend to a notification system in case of threshold definition or performance degradation
– Can be easily enabled/disabled
– Can be used in production globally (vs a system such as google pagespeed that can be used only for a unit test)
Architecture overview
End user workstation
Centralized Data storage
Transmit data
Data analysis
3 parts -Collecting performance metrics -Storing data -Data visualization
1
2
3
For demo purpose External storage to demonstrate Salesforce Connect (it would be easier to store directly in Salesforce)
The Agent
• The Agent will run locally in the browser of any end-user – Leveraging HTML5 performance API – Providing extremely fine duration (ms) – Splitting time spent into all areas (network, dns…) – With an option to have measures locally consolidated or pushed centrally
• Must have no performance impact – Very low bandwidth, CPU, RAM, Dom impact
• extremely light script that can be included in any custom webpage
– Transparent, not noticeable by end-user – Will do everything “after” “onload”
• As duration of “onload” will be computed
– Must be easy to deploy
• Will do in 2 steps
– Collect information • Need to keep info of previous pages as long as there is user activity
– Transmit information • Later, when there is no user activity such as navigating from page to page
1
The Agent – performance API 1
• We will use it and combine information to get
– Min/max/average and day-time values + per page info + per user
– Complementary information declined from these values
• Network latency (): responseEnd-fetchStart
• The time taken for page load once the page is received from the server: loadEventEnd-responseEnd
• The whole process of navigation and page load: loadEventEnd-navigationStart.
Compatibility : http://caniuse.com/#feat=nav-timing
Performance API - example JSON.stringify(window.performance.timing); Référence à un objet de chronométrage des performances.
{
prompt for unload :
"navigationStart":1442679841366, Time after the previous document begins unload. new Date(1442679841366).toLocaleString() => "19/9/2015 18:24:01"
Redirect :
"redirectStart":0, Time of fetch that initiated a redirect.
unload :
"unloadEventStart":0, Time just before the unload event is fired.
"unloadEventEnd":0, Time after the previous document is unloaded.
"redirectEnd":0, Time after last redirect response ends.
App cache
"fetchStart":1442679841863, Time when the resource starts being fetched.
DNS
"domainLookupStart":1442679841866, Time just before domain name lookup.
"domainLookupEnd":1442679841866, Time after domain name lookup.
TCP
"connectStart":1442679841866, Time just before server connection begins.
"secureConnectionStart":1442679841973, //Non supporté par IE
"connectEnd":1442679842195, Time when server connection is finished.
Request
"requestStart":1442679842195, Time just before a server request.
Response
"responseStart":1442679846204, Time just before the start of a response.
"domLoading":1442679846206, Time just before readiness set to loading.
"responseEnd":1442679846342, Time after the end of a response or connection.
Processing
"domInteractive":1442679846349, Time just before readiness set to interactive.
"domContentLoadedEventStart":1442679846349, Time just before DOMContentLoaded starts. - $(document).ready()
"domContentLoadedEventEnd":1442679846349, Time after DOMContentLoaded event completes.
"domComplete":1442679847992, Time just before document readiness completes.
Onload
"loadEventStart":1442679847992, Time just before the load event is fired. (window onLoad)
"loadEventEnd":1442679848105 Time when the load event is complete.
}
1
The Agent – technical overview
• Pure JavaScript – Nothing required to run on server side. – Hosted in a Visualforce Component to make it easy to include in Visualforce pages
• No controller No server impact • Conditional rendering can be defined in the Visualforce page : per profile, per user, per country, if developer mode is
enabled, or any logic
– 0.5 Kb
• The logic – No DOM manipulation or access – Retrieve the AppId (or org id) to be able to group your data – Listen to the “load” event – During the load invent, inject a timer that will call a post-load function – The post-load function will store locally (localstorage) the collected data (Performance
counter, AppId, Page Name) and prepare a function to trigger a few seconds later – This late function will send collected data to the centralized storage – No impact on user navigation
• Roadmap: – A Lightning Component – Capability to retrieve Apex code / VF duration as it is included at the end of the body of a VF
page – Stand alone capability (no server)
1
The Agent – code 1
Perf component inserted into the Visualforce Page
The Storage
• The system will:
1. receive data collected on all browsers
2. Enrich data with other information (browser used, IP address, country, meta data (composite data) …
3. Serve the data for reporting or analysis purpose
2
The Storage – technical overview
• The server requires:
– HTTPS
– CORS headers
– High performance : short time to process + scalability
– Store incoming data (insert)
– Serve reporting data (queries)
– Enhance incoming data • Convert IP to country…
2
The rendering
• The system will:
– Retrieve the data
– Compute some logic to reveal information • With dashboards allowing you to identify the evolution along the
day
• Provide reporting and analysis in Salesforce
• Leverage Salesforce Connect (lightning connect)
– The Data Source is the Storage
3
The rendering, technical overview
• 1 page will serve the dashboards – Dashboard values can be served using a lightning connect
custom adapter, or through a direct service call
– We will use Google chart api • https://developers.google.com/chart/interactive/docs/gallery
• Dashboards can present – comparison between pages,
– detailed user info,
– brute dump,
– any analysis axis…
• We will use a Visualforce page
3
Lightning Connect Configuration 1/5
• Create a new class “PerfDataSourceConnection” extending DataSource.Provider
PerfDataSourceConnection.cls
External Data Source
configuration
PerfDataSourceProvider.cls
Impact the configuration layout and options
Use for Data connection
•sync the external system’s metadata schema • handle queries and searches of the external data
Perf data repository
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_connector_start_connection_class.htm
•sync() •query() •search() •upsertRows() •deleteRows()
Lightning Connect Configuration 2/5
• Reading the Perf Data – The performance data storage provides a JSON based API to retrieve the data.
– Use the JSON message with AdminBooster JSON-To-Apex tool to generate the class • https://www.adminbooster.com/tool/json2apex
public class PerfFromJSON{ public cls_perf[] perf; class cls_perf { public String Created; //2016-01-16T18:06:48.000Z public Integer navigationStart; //1452634789484 public Integer deltaUnloadEventStart; //1486 public Integer deltaUnloadEventEnd; //1487 public Integer deltaRedirectStart; //0 public Integer deltaRedirectEnd; //0 public Integer deltaFetchStart; //21 public Integer deltaDomainLookupStart; //21 public Integer deltaDomainLookupEnd; //21 public Integer deltaConnectStart; //21 public Integer deltaSecureConnectionStart; //0 public Integer deltaConnectEnd; //21 public Integer deltaRequestStart; //24 public Integer deltaResponseStart; //824 public Integer deltaResponseEnd; //1479 public Integer deltaDomLoading; //1493 public Integer deltaDomInteractive; //1660 public Integer deltaDomContentLoadedEventStart; //1660 public Integer deltaDomContentLoadedEventEnd; //1660 public Integer deltaDomComplete; //4780 public Integer deltaLoadEventStart; //4780 public Integer deltaLoadEventEnd; //4790 public String AppId; //00Di0000000GzZGEA0 public String Page; //admin__PagePerf public String uuid; //569a86b8527d7 public String geoip; //FR } public static PerfFromJSON parse(String json){ return (PerfFromJSON) System.JSON.deserialize(json, PerfFromJSON.class); } }
Lightning Connect Configuration 3/5 • Create a new class extending DataSource.Provider and using
PerfDataSourceConnection class
Lightning Connect Configuration 4/5
• Create an external Data source
– Setup | Develop | External Data Sources | New • Define the type as lightning connect
Custom, related to your Apex class
– Validate and sync
Lightning Connect Configuration 5/5
2 standard fields
Tip: Create a Tab to see your data
Remote site setting
• Don’t forget to configure it, or you get the following error:
Data set displayed in Salesforce
• Result :
• Limitations: – No reporting – Cannot add new formula fields to compute macro values
(download time, etc…) • Workaround : must implement everything in the DataSource Connection class
– Strange behavior of counted rows (total displayed != total counted)
– 15 fields limitation in views views cannot replace reports
Reporting
…
Various approaches Solution Benefits Concerns
Stored in the browser No impact on current data storage limit No server/infrastructure
No consolidated view
Stored externally with Salesforce access
No impact on current data storage limit Dedicated server required Cost of Salesforce connect Cost of custom Apex development No standard reporting
Stored externally with browser access
Javascript development only Dedicated server required
Stored in Salesforce objects
Standard reporting Configuration capabilities Very low development Capability to pre-compute with Roll-up Summary fields Capability to configure notifications (wkf)
Price of high volume storage Risk on high volume
Stored in Salesforce Big Objects
Capability to manage high volume Long term history/data trend analysis Wave integration (data sets using data pipeline)
Additional fees Read-only (can add field but cannot change/remove fields). BO cannot be deleted No Apex access : all complementary data must be computed in the javascript code No Numeric field Limited SOQL
Other resources
• Server side : – A Guide to Application Performance Profiling in Force.com
• https://developer.salesforce.com/page/A_Guide_to_Application_Performance_Profiling_in_Force.com
– Performance Testing Your Force.com Application • https://developer.salesforce.com/blogs/engineering/2013/09/performance-testing-force-com-
application.html
– Performance Tuning for Visualforce and Apex • https://www.youtube.com/watch?v=aYMY2VES2bY
– Network Best Practices for Salesforce Architects • https://developer.salesforce.com/page/Network_Best_Practices_for_Salesforce_Architects
• Client Side – Visualforce Best Practices
• http://resources.docs.salesforce.com/latest/latest/en-us/sfdc/pdf/salesforce_visualforce_best_practices.pdf
Annex – Page generation time
• How to identify server side duration for standard pages and VisualForce?
– Take a look at the end of the generated HTML
59"
top related