SlideShare a Scribd company logo
Building Efficient Visualforce Pages
Steve Bobrowski, salesforce.com, @sbob909
Markus Spohn, salesforce.com, @markus_spohn
Joseph Ferraro, Mavens Consulting, @joeferraro
Safe harbor
Safe harbor statement under the Private Securities Litigation Reform Act of 1995:
This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties
materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results
expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be
deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other
financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any
statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services.
The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new
functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our
operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any
litigation, risks associated with completed and any possible mergers and acquisitions, the immature market in which we operate, our
relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our
service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to
larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is
included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on Form 10-Q for the most recent
fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of the Investor
Information section of our Web site.
Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently
available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions
based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these
forward-looking statements.
Your company uses
Salesforce/Force.com …
You are a developer or architect
maintaining your org …
Many Visualforce pages
are slow & hurting user
productivity …
You need to find and rework slow
Visualforce pages.
Today’s Agenda
Common problems & practical
solutions for finding & fixing
slow Visualforce pages
Steve Bobrowski
Architect Evangelist
@sbob909
Markus Spohn
Architect Evangelist
@markus_spohn
What makes for an efficient Visualforce page?
Two keys to building efficient Visualforce pages …
Database access

Memory usage

Visualforce page
Happy, productive users …
Use tools to find and fix inefficient source code …
Related DevZone hands-on, mini-workshop

Two available times:
- Wednesday: 12 noon
- Thursday: 11am
Designing memory-efficient
Visualforce pages
Visualforce page view state
How can you ______ it?
Understand Visualforce page
view state
Visualforce page view state comes from … forms
<apex:page showHeader="true" controller="invoiceController" tabstyle="Invoice__c" sidebar="false">
<apex:form >
<apex:pageBlock >
<h1>Open Invoices</h1>

<apex:pageBlockTable id="invoiceList" value="{!invoices}" var="i">
<apex:column headerValue="Name">
<apex:outputLink value="/{!i.Id}">{!i.Name}</apex:outputLink>
</apex:column>
<apex:column value="{!i.Status__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
<apex:actionPoller action="{!pollAction}" reRender="invoiceList" interval="15"/>
</apex:form>
</apex:page>

<apex:form>
Visualforce page view state supports postbacks
postback
Error

Browser
page with
form

Server

Submit

post
Visualforce page view state is encrypted …
Less view state is better for response time …
Examine Visualforce page
view state
Force.com development mode … configuration
Advanced user details …
Force.com development mode … view state
Live demo page
Avoid unnecessary
Visualforce page
view state
Minimize data … examine data page uses
<apex:page showHeader="true" controller="invoiceController" tabstyle="Invoice__c" sidebar="false">
<apex:form >
<apex:pageBlock >
<h1>Open Invoices</h1>
<apex:pageBlockTable id="invoiceList" value="{!invoices}" var="i">
<apex:column headerValue="Name">
<apex:outputLink value="/{!i.Id}">{!i.Name}</apex:outputLink>
</apex:column>
<apex:column value="{!i.Status__c}"/>
</apex:pageBlockTable>
</apex:pageBlock>
<apex:actionPoller action="{!pollAction}" reRender="invoiceList" interval="15"/>
</apex:form>
</apex:page>
Minimize data … examine data controller gets
public class invoiceController {

Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c, Invoice_Total__c, CreatedDate,
LastModifiedDate, LastModifiedById, OwnerId FROM Invoice__c ORDER BY Status__c ASC’
LIMIT 1000;
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Minimize data … match page and controller data
public class invoiceController {

Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c ORDER BY Status__c ASC LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Minimize data … only get the rows that page needs
public class invoiceController {

Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c != 'Closed'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Live demo page
Use transient controller variables for read-only data
public class invoiceController {

Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c != 'Closed'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Use transient controller variables for read-only data
public class invoiceController {

Transient Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c != 'Closed'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Live demo page
Avoid Visualforce page
view state altogether
Refresh data without actionPoller (and view state)
Traditional polling alternatives to actionPoller:

Long polling/streaming updates:
Recap: Examine, reduce, or eliminate view state
Building database-efficient
Visualforce pages
Database-efficient Visualforce controllers
Key characteristics:
 SOQL
 logic

______
Execute efficient SOQL
Minimize record width
public class invoiceController {

Transient Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c, Invoice_Total__c, CreatedDate,
LastModifiedDate, LastModifiedById, OwnerId FROM Invoice__c ORDER BY Status__c ASC
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Minimize record count
public class invoiceController {

Transient Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c != 'Closed'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Query & Search Optimization Cheat Sheet

http://developer.force.com/architect
Fetch target rows with optimizable filter conditions
public class invoiceController {

Transient Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c = ’Open'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Leverage field indexes in filter conditions
public class invoiceController {
Transient Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c = ’Open'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Live demo page
Leverage the Salesforce sharing architecture
public with sharing class invoiceController {
Transient Invoice__c[] invoices;
String query = 'SELECT Id, Name, Status__c FROM Invoice__c
WHERE Status__c = ’Open'
LIMIT 1000';
public Invoice__c[] getInvoices() {
invoices = Database.query(query);
return invoices;
}
public PageReference pollAction() {
invoices = Database.query(query);
return null;
}
}
Recap: Execute efficient SOQL queries

(And don’t forget to use the sharing architecture)
Design efficient controller logic
Use standard set controllers, when possible

Use whenever possible: don't reinvent things
Place DML and SOQL outside of loops
Use bulk processing best practices
Make efficient design choices
openInvoices page, revisited

Refreshes … every 15 seconds
Reconsider traditional polling

Invoice
pull (polling)
Use long polling with the Force.com Streaming API
Update
pull (polling)

Invoice
Live demo page
Recap: Use efficient overall page designs
Using tools to find and fix
common problems …

FAST!
Be aware of available tools
Force.com browser-based tools
Force.com IDE (Eclipse)
Third-party Force.com application development tools
MavensMate
All about Joe Ferraro and Mavens Consulting
Mavens Consulting is the Life Science industry’s premier
salesforce.com implementation partner focused exclusively
on delivering optimized Force.com solutions.
 Certified Force.com and Veeva Experts
 Unparalleled Global Knowledge in Life Sciences
 Specialists in Service Cloud Implementations for MedInfo Contact
Centers and Multi-Channel Portals for Physicians and Reps
MavensMate
MavensMate
Leverage the power
of your tools
MavensMate Project Health Check
Live demo page
Recap: Find and fix common problems proactively
Session summary
Session Recap: Building Efficient Visualforce Pages
Related DevZone hands-on, mini-workshop

Two available times:
- Wednesday: 12 noon
- Thursday: 11am
Steve Bobrowski

Markus Spohn

Joseph Ferraro

Salesforce.com
@sbob909

Salesforce.com
@markus_spohn

Mavens Consulting
@joeferraro
Building Efficient Visualforce Pages

More Related Content

Similar to Building Efficient Visualforce Pages

Building Efficient Visualforce Pages
Building Efficient Visualforce PagesBuilding Efficient Visualforce Pages
Building Efficient Visualforce Pages
SFDCSregan
 
His master's voice, take command of Einstein Analytics
His master's voice, take command of Einstein AnalyticsHis master's voice, take command of Einstein Analytics
His master's voice, take command of Einstein Analytics
rikkehovgaard
 
Force.com Friday: Intro to Force.com
Force.com Friday: Intro to Force.comForce.com Friday: Intro to Force.com
Force.com Friday: Intro to Force.com
Salesforce Developers
 
S1 and Visualforce Publisher Actions
S1 and Visualforce Publisher ActionsS1 and Visualforce Publisher Actions
S1 and Visualforce Publisher Actions
Peter Chittum
 
Intro to Apex Programmers
Intro to Apex ProgrammersIntro to Apex Programmers
Intro to Apex Programmers
Salesforce Developers
 
Build Amazing Website without coding using Salesforce SiteForce
Build Amazing Website without coding using Salesforce SiteForceBuild Amazing Website without coding using Salesforce SiteForce
Build Amazing Website without coding using Salesforce SiteForcevraopolisetti
 
Build System Performance Data Analytics Using Wave
Build System Performance Data Analytics Using WaveBuild System Performance Data Analytics Using Wave
Build System Performance Data Analytics Using Wave
Salesforce Developers
 
Lightning Data Service: Eliminate Your Need to Load Records Through Controllers
Lightning Data Service: Eliminate Your Need to Load Records Through ControllersLightning Data Service: Eliminate Your Need to Load Records Through Controllers
Lightning Data Service: Eliminate Your Need to Load Records Through Controllers
Salesforce Developers
 
Visualforce Hack for Junction Objects
Visualforce Hack for Junction ObjectsVisualforce Hack for Junction Objects
Visualforce Hack for Junction Objects
Ritesh Aswaney
 
Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2
Salesforce Developers
 
Building Visualforce Custom Events Handlers
Building Visualforce Custom Events HandlersBuilding Visualforce Custom Events Handlers
Building Visualforce Custom Events Handlers
Salesforce Developers
 
Cutting Edge Mobile Development in the App Cloud
Cutting Edge Mobile Development in the App CloudCutting Edge Mobile Development in the App Cloud
Cutting Edge Mobile Development in the App Cloud
Salesforce Developers
 
Force.com Friday : Intro to Visualforce
Force.com Friday : Intro to VisualforceForce.com Friday : Intro to Visualforce
Force.com Friday : Intro to Visualforce
Salesforce Developers
 
Seattle Dev Garage
Seattle Dev GarageSeattle Dev Garage
Seattle Dev GarageJoshua Birk
 
How We Built AppExchange and our Communities on the App Cloud (Platform)
How We Built AppExchange and our Communities on the App Cloud (Platform)How We Built AppExchange and our Communities on the App Cloud (Platform)
How We Built AppExchange and our Communities on the App Cloud (Platform)
Dreamforce
 
Javascript and Remote Objects on Force.com Winter 15
Javascript and Remote Objects on Force.com Winter 15Javascript and Remote Objects on Force.com Winter 15
Javascript and Remote Objects on Force.com Winter 15
Peter Chittum
 
Spring '16 Release Overview - Bilbao Feb 2016
Spring '16 Release Overview - Bilbao Feb 2016Spring '16 Release Overview - Bilbao Feb 2016
Spring '16 Release Overview - Bilbao Feb 2016
Peter Chittum
 
Spring '14 Release Developer Preview Webinar
Spring '14 Release Developer Preview WebinarSpring '14 Release Developer Preview Webinar
Spring '14 Release Developer Preview Webinar
Salesforce Developers
 
Turbo-charge Your Skuid Page with Apex
Turbo-charge Your Skuid Page with ApexTurbo-charge Your Skuid Page with Apex
Turbo-charge Your Skuid Page with Apex
Salesforce Developers
 
Force.com Friday : Intro to Apex
Force.com Friday : Intro to Apex Force.com Friday : Intro to Apex
Force.com Friday : Intro to Apex
Salesforce Developers
 

Similar to Building Efficient Visualforce Pages (20)

Building Efficient Visualforce Pages
Building Efficient Visualforce PagesBuilding Efficient Visualforce Pages
Building Efficient Visualforce Pages
 
His master's voice, take command of Einstein Analytics
His master's voice, take command of Einstein AnalyticsHis master's voice, take command of Einstein Analytics
His master's voice, take command of Einstein Analytics
 
Force.com Friday: Intro to Force.com
Force.com Friday: Intro to Force.comForce.com Friday: Intro to Force.com
Force.com Friday: Intro to Force.com
 
S1 and Visualforce Publisher Actions
S1 and Visualforce Publisher ActionsS1 and Visualforce Publisher Actions
S1 and Visualforce Publisher Actions
 
Intro to Apex Programmers
Intro to Apex ProgrammersIntro to Apex Programmers
Intro to Apex Programmers
 
Build Amazing Website without coding using Salesforce SiteForce
Build Amazing Website without coding using Salesforce SiteForceBuild Amazing Website without coding using Salesforce SiteForce
Build Amazing Website without coding using Salesforce SiteForce
 
Build System Performance Data Analytics Using Wave
Build System Performance Data Analytics Using WaveBuild System Performance Data Analytics Using Wave
Build System Performance Data Analytics Using Wave
 
Lightning Data Service: Eliminate Your Need to Load Records Through Controllers
Lightning Data Service: Eliminate Your Need to Load Records Through ControllersLightning Data Service: Eliminate Your Need to Load Records Through Controllers
Lightning Data Service: Eliminate Your Need to Load Records Through Controllers
 
Visualforce Hack for Junction Objects
Visualforce Hack for Junction ObjectsVisualforce Hack for Junction Objects
Visualforce Hack for Junction Objects
 
Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2Coding Apps in the Cloud with Force.com - Part 2
Coding Apps in the Cloud with Force.com - Part 2
 
Building Visualforce Custom Events Handlers
Building Visualforce Custom Events HandlersBuilding Visualforce Custom Events Handlers
Building Visualforce Custom Events Handlers
 
Cutting Edge Mobile Development in the App Cloud
Cutting Edge Mobile Development in the App CloudCutting Edge Mobile Development in the App Cloud
Cutting Edge Mobile Development in the App Cloud
 
Force.com Friday : Intro to Visualforce
Force.com Friday : Intro to VisualforceForce.com Friday : Intro to Visualforce
Force.com Friday : Intro to Visualforce
 
Seattle Dev Garage
Seattle Dev GarageSeattle Dev Garage
Seattle Dev Garage
 
How We Built AppExchange and our Communities on the App Cloud (Platform)
How We Built AppExchange and our Communities on the App Cloud (Platform)How We Built AppExchange and our Communities on the App Cloud (Platform)
How We Built AppExchange and our Communities on the App Cloud (Platform)
 
Javascript and Remote Objects on Force.com Winter 15
Javascript and Remote Objects on Force.com Winter 15Javascript and Remote Objects on Force.com Winter 15
Javascript and Remote Objects on Force.com Winter 15
 
Spring '16 Release Overview - Bilbao Feb 2016
Spring '16 Release Overview - Bilbao Feb 2016Spring '16 Release Overview - Bilbao Feb 2016
Spring '16 Release Overview - Bilbao Feb 2016
 
Spring '14 Release Developer Preview Webinar
Spring '14 Release Developer Preview WebinarSpring '14 Release Developer Preview Webinar
Spring '14 Release Developer Preview Webinar
 
Turbo-charge Your Skuid Page with Apex
Turbo-charge Your Skuid Page with ApexTurbo-charge Your Skuid Page with Apex
Turbo-charge Your Skuid Page with Apex
 
Force.com Friday : Intro to Apex
Force.com Friday : Intro to Apex Force.com Friday : Intro to Apex
Force.com Friday : Intro to Apex
 

More from Salesforce Developers

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Salesforce Developers
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
Salesforce Developers
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
Salesforce Developers
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
Salesforce Developers
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
Salesforce Developers
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
Salesforce Developers
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
Salesforce Developers
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
Salesforce Developers
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
Salesforce Developers
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
Salesforce Developers
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
Salesforce Developers
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce data
Salesforce Developers
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
Salesforce Developers
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
Salesforce Developers
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
Salesforce Developers
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
Salesforce Developers
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
Salesforce Developers
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
Salesforce Developers
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
Salesforce Developers
 

More from Salesforce Developers (20)

Sample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce DevelopersSample Gallery: Reference Code and Best Practices for Salesforce Developers
Sample Gallery: Reference Code and Best Practices for Salesforce Developers
 
Maximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component PerformanceMaximizing Salesforce Lightning Experience and Lightning Component Performance
Maximizing Salesforce Lightning Experience and Lightning Component Performance
 
Local development with Open Source Base Components
Local development with Open Source Base ComponentsLocal development with Open Source Base Components
Local development with Open Source Base Components
 
TrailheaDX India : Developer Highlights
TrailheaDX India : Developer HighlightsTrailheaDX India : Developer Highlights
TrailheaDX India : Developer Highlights
 
Why developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX IndiaWhy developers shouldn’t miss TrailheaDX India
Why developers shouldn’t miss TrailheaDX India
 
CodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local DevelopmentCodeLive: Build Lightning Web Components faster with Local Development
CodeLive: Build Lightning Web Components faster with Local Development
 
CodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web ComponentsCodeLive: Converting Aura Components to Lightning Web Components
CodeLive: Converting Aura Components to Lightning Web Components
 
Enterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web ComponentsEnterprise-grade UI with open source Lightning Web Components
Enterprise-grade UI with open source Lightning Web Components
 
TrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer HighlightsTrailheaDX and Summer '19: Developer Highlights
TrailheaDX and Summer '19: Developer Highlights
 
Live coding with LWC
Live coding with LWCLive coding with LWC
Live coding with LWC
 
Lightning web components - Episode 4 : Security and Testing
Lightning web components  - Episode 4 : Security and TestingLightning web components  - Episode 4 : Security and Testing
Lightning web components - Episode 4 : Security and Testing
 
LWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura InteroperabilityLWC Episode 3- Component Communication and Aura Interoperability
LWC Episode 3- Component Communication and Aura Interoperability
 
Lightning web components episode 2- work with salesforce data
Lightning web components   episode 2- work with salesforce dataLightning web components   episode 2- work with salesforce data
Lightning web components episode 2- work with salesforce data
 
Lightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An IntroductionLightning web components - Episode 1 - An Introduction
Lightning web components - Episode 1 - An Introduction
 
Migrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCPMigrating CPQ to Advanced Calculator and JSQCP
Migrating CPQ to Advanced Calculator and JSQCP
 
Scale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in SalesforceScale with Large Data Volumes and Big Objects in Salesforce
Scale with Large Data Volumes and Big Objects in Salesforce
 
Replicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data CaptureReplicate Salesforce Data in Real Time with Change Data Capture
Replicate Salesforce Data in Real Time with Change Data Capture
 
Modern Development with Salesforce DX
Modern Development with Salesforce DXModern Development with Salesforce DX
Modern Development with Salesforce DX
 
Get Into Lightning Flow Development
Get Into Lightning Flow DevelopmentGet Into Lightning Flow Development
Get Into Lightning Flow Development
 
Integrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS ConnectIntegrate CMS Content Into Lightning Communities with CMS Connect
Integrate CMS Content Into Lightning Communities with CMS Connect
 

Recently uploaded

De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 

Recently uploaded (20)

De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 

Building Efficient Visualforce Pages

  • 1. Building Efficient Visualforce Pages Steve Bobrowski, salesforce.com, @sbob909 Markus Spohn, salesforce.com, @markus_spohn Joseph Ferraro, Mavens Consulting, @joeferraro
  • 2. Safe harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of any litigation, risks associated with completed and any possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-K for the most recent fiscal year and in our quarterly report on Form 10-Q for the most recent fiscal quarter. These documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
  • 4. You are a developer or architect maintaining your org …
  • 5. Many Visualforce pages are slow & hurting user productivity …
  • 6. You need to find and rework slow Visualforce pages.
  • 7. Today’s Agenda Common problems & practical solutions for finding & fixing slow Visualforce pages
  • 10. What makes for an efficient Visualforce page?
  • 11. Two keys to building efficient Visualforce pages … Database access Memory usage Visualforce page
  • 13. Use tools to find and fix inefficient source code …
  • 14. Related DevZone hands-on, mini-workshop Two available times: - Wednesday: 12 noon - Thursday: 11am
  • 16. Visualforce page view state How can you ______ it?
  • 18. Visualforce page view state comes from … forms <apex:page showHeader="true" controller="invoiceController" tabstyle="Invoice__c" sidebar="false"> <apex:form > <apex:pageBlock > <h1>Open Invoices</h1> <apex:pageBlockTable id="invoiceList" value="{!invoices}" var="i"> <apex:column headerValue="Name"> <apex:outputLink value="/{!i.Id}">{!i.Name}</apex:outputLink> </apex:column> <apex:column value="{!i.Status__c}"/> </apex:pageBlockTable> </apex:pageBlock> <apex:actionPoller action="{!pollAction}" reRender="invoiceList" interval="15"/> </apex:form> </apex:page> <apex:form>
  • 19. Visualforce page view state supports postbacks postback Error Browser page with form Server Submit post
  • 20. Visualforce page view state is encrypted …
  • 21. Less view state is better for response time …
  • 23. Force.com development mode … configuration Advanced user details …
  • 24. Force.com development mode … view state
  • 27. Minimize data … examine data page uses <apex:page showHeader="true" controller="invoiceController" tabstyle="Invoice__c" sidebar="false"> <apex:form > <apex:pageBlock > <h1>Open Invoices</h1> <apex:pageBlockTable id="invoiceList" value="{!invoices}" var="i"> <apex:column headerValue="Name"> <apex:outputLink value="/{!i.Id}">{!i.Name}</apex:outputLink> </apex:column> <apex:column value="{!i.Status__c}"/> </apex:pageBlockTable> </apex:pageBlock> <apex:actionPoller action="{!pollAction}" reRender="invoiceList" interval="15"/> </apex:form> </apex:page>
  • 28. Minimize data … examine data controller gets public class invoiceController { Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c, Invoice_Total__c, CreatedDate, LastModifiedDate, LastModifiedById, OwnerId FROM Invoice__c ORDER BY Status__c ASC’ LIMIT 1000; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 29. Minimize data … match page and controller data public class invoiceController { Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c ORDER BY Status__c ASC LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 30. Minimize data … only get the rows that page needs public class invoiceController { Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c != 'Closed' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 32. Use transient controller variables for read-only data public class invoiceController { Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c != 'Closed' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 33. Use transient controller variables for read-only data public class invoiceController { Transient Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c != 'Closed' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 35. Avoid Visualforce page view state altogether
  • 36. Refresh data without actionPoller (and view state) Traditional polling alternatives to actionPoller: Long polling/streaming updates:
  • 37. Recap: Examine, reduce, or eliminate view state
  • 39. Database-efficient Visualforce controllers Key characteristics:  SOQL  logic ______
  • 41. Minimize record width public class invoiceController { Transient Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c, Invoice_Total__c, CreatedDate, LastModifiedDate, LastModifiedById, OwnerId FROM Invoice__c ORDER BY Status__c ASC LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 42. Minimize record count public class invoiceController { Transient Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c != 'Closed' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 43. Query & Search Optimization Cheat Sheet http://developer.force.com/architect
  • 44. Fetch target rows with optimizable filter conditions public class invoiceController { Transient Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c = ’Open' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 45. Leverage field indexes in filter conditions public class invoiceController { Transient Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c = ’Open' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 47. Leverage the Salesforce sharing architecture public with sharing class invoiceController { Transient Invoice__c[] invoices; String query = 'SELECT Id, Name, Status__c FROM Invoice__c WHERE Status__c = ’Open' LIMIT 1000'; public Invoice__c[] getInvoices() { invoices = Database.query(query); return invoices; } public PageReference pollAction() { invoices = Database.query(query); return null; } }
  • 48. Recap: Execute efficient SOQL queries (And don’t forget to use the sharing architecture)
  • 50. Use standard set controllers, when possible Use whenever possible: don't reinvent things
  • 51. Place DML and SOQL outside of loops
  • 52. Use bulk processing best practices
  • 56. Use long polling with the Force.com Streaming API Update pull (polling) Invoice
  • 58. Recap: Use efficient overall page designs
  • 59. Using tools to find and fix common problems … FAST!
  • 60. Be aware of available tools
  • 65. All about Joe Ferraro and Mavens Consulting Mavens Consulting is the Life Science industry’s premier salesforce.com implementation partner focused exclusively on delivering optimized Force.com solutions.  Certified Force.com and Veeva Experts  Unparalleled Global Knowledge in Life Sciences  Specialists in Service Cloud Implementations for MedInfo Contact Centers and Multi-Channel Portals for Physicians and Reps
  • 68. Leverage the power of your tools
  • 71. Recap: Find and fix common problems proactively
  • 73. Session Recap: Building Efficient Visualforce Pages
  • 74. Related DevZone hands-on, mini-workshop Two available times: - Wednesday: 12 noon - Thursday: 11am
  • 75. Steve Bobrowski Markus Spohn Joseph Ferraro Salesforce.com @sbob909 Salesforce.com @markus_spohn Mavens Consulting @joeferraro

Editor's Notes

  1. STEVE: So what are we going to cover in today’s session? Well, I’m assuming that most of you work somewhere that uses Salesforceapps or perhaps a custom Force.com app.
  2. STEVE: Perhaps you are a developer, maybe an architect, and you are in charge of maintaining an org.
  3. STEVE: Let’s say the org has been around for a while. And there’s a bunch of Visualforce pages that are sloooowwww. So slow that they are hurting user productivity, which is obviously something we don’t want. Problem is, you’re not sure why they’re slow to begin with.
  4. STEVE: So today, in this session, your job is to find all the pages that are implemented poorly and make them more efficient.
  5. STEVE: And that’s what we are going to cover today. We are going to take a look at the most common problems that cause slow Visualforce pages, and then we’ll show you how to find and fix these problems in your org. Using the skills you learn today, you’ll be able to go back to work and make old, and new, Visualforce pages execute efficiently.
  6. STEVE: My name is Steve Bobrowski, and I’m part of the Customer Centric Engineering group here at salesforce.com. But when I go out and talk to folks about Salesforce implementations and architecture, I think of myself as an “architect evangelist”, someone that can help you learn more about how Salesforce works under the hood so that you can implement better solutions on our platform.
  7. STEVE: With me today is another member of our team, Markus Spohn, and together, we’d like to discuss what everyone should know about building efficient Visualforce pages.
  8. STEVE: So what makes a Visualforce page efficient? Well, we all know that Visualforce is completely flexible to the way that you want to develop your app. You could use pure Visualforce, or you might use some custom JavaScript libraries, adjust HTML to your liking—the possibilities are almost endless. Considering this, we could throw together a really long list of things to watch out for, things that might or might not apply to your environment. Stuff about efficient Web technologies like HTML, CSS, and JavaScript. Then maybe discuss efficient user interface designs. And countless other things.
  9. STEVE: But when you consider everything that you could do, there are two key things to focus on that will have the most effect on how well your Visualforce pages respond: how much memory they use, and how efficiently they access your databaseThese two things, if you make them efficient, have the biggest impact on Visualforce page response time. And that indirectly supports what we are after …
  10. STEVE: … user productivity and satisfaction.
  11. STEVE: Alright, so after we learn all about designing memory- and database-efficient Visualforce pages, you need to know how to go about finding the pages that could use some improvement. Maybe you already know about some problem pages from user feedback. But there’s a good chance there are others in your org that need attention. And finding those can be a real challenge … unless … you have the right tools to do the job. So in the final part of today’s session, we’re going to introduce you to various tools that you can use for Visualforce and Apex development. And we have a special guest, Joe Ferraro, that’s going to show you a great new feature in his open-source IDE, MavensMate, that lets you scan your entire org and identify source code that could use some improvement … all with a single mouse click.Now before we get started …
  12. STEVE: I want to briefly mention that there will be related mini-workshops in the Dev Zone on Wednesday and Thursday. So if you want to apply all the things you learn today in this session, hands-on in a live org, make sure to register for the workshop with the same name.
  13. STEVE: Let’s talk about designing memory-efficient Visualforce pages. Markus, why don’t you take us through this please.MARKUS: Thanks Steve. Hi everyone.
  14. MARKUS: The most important contributor to a Visualforce page’s memory usage is something called view state. So let’s focus on view state for a few minutes and learn what it is, where it comes from, and then explore ways to examine it, reduce it, and eliminate it altogether.
  15. MARKUS: First, let’s make sure we all understand what view state is.
  16. MARKUS: Force.com automatically creates and manages view state for all Visualforce pages that contain an &lt;apex:form&gt; component. A page with a form has view state so that the information is available to rebuild a page when a postback happens.
  17. MARKUS: A postback happens when a user submits a form to a server, something happens like a data validation error, and the server posts the submitted data back to the browser, which reconstructs the state of the page including the form data that was previously submitted.
  18. MARKUS: When view state is grows, page rendering time and perceived page response time can suffer. This is particularly true with mobile clients that have limited memory available.
  19. MARKUS: So your job, as a Visualforce page designer, is to make sure that pages with forms use the minimum amount of view state, which helps make pages more efficient and users happy.
  20. MARKUS: So to repeat, here are the key things to understand about view state.View state comes from managing form data to support postbacks, and less view state makes your pages more efficient and responsive.
  21. MARKUS: Next, let’s discuss how you can examine view state.
  22. MARKUS: Considering this is an intermediate-level session, we’re going to assume that all of you know how to enable and already use “development mode” when you access Salesforce in your browser. What you also want to check that you have enabled is the “Show View State in Development Mode” option, which is right next to the Development Mode option on the Advanced User Details page.
  23. MARKUS: After these settings are enabled, when you load a Visualforce page, the development mode footer displays information about the page’s view state when you click on the View State tab.
  24. MARKUS: So before we go any further, let’s take a look at an example Visualforce page and controller. As we go along in this session, we’ll revisit the page and make the various improvements to the page that we suggest and see how things change. Steve, can you take us through the demo?STEVE: Sure thing.=====Switch screen to org with workshop org’s /apex/openInvoices page open.Explain purpose of the page: Shows open invoices above closed invoices, refreshes every 15 seconds to keep data current. Provides a list that users can start workflow on open invoices.Click on View State tab, discuss tree structure. Mention that max view state size is 135K.Briefly discuss page and controller source code. Make sure to point out that the page uses actionPoller to auto refresh every 15 seconds.Return to session deck.[TIMING: 7m]
  25. MARKUS: Thanks Steve.Now everyone should know how to view and examine view state. Next, let’s learn how to reduce unnecessary view state to make your Visualforce pages more responsive.
  26. MARKUS: One of the first things to check is that your page’s controller doesn’t get more data from the Force.com database than your page uses. For example, notice how this page uses the Id, Name, and Status field values for Invoices. Yet …
  27. MARKUS: … the page’s controller fetches many more fields than the page uses. Considering that the page maintains all of this data within a form, there’s a bunch of unnecessary view state being maintained for data that the page doesn’t even utilize. That’s wasteful. Simple fix … just remove the fields that aren’t necessary from the query in the controller.
  28. MARKUS: Like so. We’ve culled the SOQL query’s SELECT list to minimize the amount of fields retrieved from the database. But wait … there’s more that we can do to make this page’s controller more efficient. Considering that the purpose of the page is to present a list of all Invoices that are Open, can anyone tell me what else I can do to improve the efficiency of this controller?… audience responses …Correct, we can include a filter condition, or a WHERE clause, to fetch only the database records that meet our criteria. So let’s go ahead and add a filter condition that will suffice.
  29. MARKUS: There … that’ll fetch just the records that are OPEN … or all records that are not CLOSED, in this case. Now if you see something wrong here with our new WHERE clause, just bite your tongue for a few minutes. We’ll be making some more improvements to the SOQL query in the proper context a bit later in this session. Right now, we are focusing on improving the memory-efficiency of the page itself.[TIMING:8.5m]
  30. MARKUS: So let’s have Steve go back to the live page and make these changes to see what happens to the view state.STEVE: Ok, here we go.=====Switch screen to org with workshop org’s /apex/openInvoices page open.Click on View State tab, remind attendees of view state size and sources.Remove unnecessary fields from query, save controller.Examine view state size change.Add WHERE clause, save controller.Examine view state size change.Return to session deck.[TIMING: 11m]
  31. MARKUS: So, these changes we made to the SOQL query in the page’s controller, minimizing the SELECT field list and adding a WHERE clause, help reduce the amount of view state that the page maintains. What else can we do to reduce things even more?
  32. MARKUS: The next thing we might do is eliminate read-only data from the view state. Remember, view state is there to support postbacks. So whenever possible, make sure to set up your controller to use transient variables for read-only data.Continuing with our invoiceController, notice that the controller creates a list of invoices, which the page maintains in the view state. The more invoice records returned by the controller, the more view state that the page must maintain. It’s really easy to remove this read-only data from the view state …
  33. MARKUS: Just use the transient keyword for variables that maintain read-only data.[TIMING: 12m]
  34. MARKUS: So Steve, let’s go back to the live page and reduce the view state with a transient variable.STEVE: Thanks Marcus.=====Switch screen to org with workshop org’s /apex/openInvoices page open.Click on View State tab, remind attendees of view state size and sources.Make Invoices transient, save controller.Examine view state size change.Return to session deck.[TIMING: 14m]
  35. MARKUS: So this simple change, marking read-only variables as transient, totally removes that data from the page’s view state.Alright, we’ve made some good progress making our Visualforce page more memory-efficient with just a few simple changes. What’s next?
  36. MARKUS: So as we said earlier, the openInvoices page we’ve been working on, maintains a list of read-only data that drives user workflow. But if all the data on the page is read-only, then why do we have to use a form at all, and thus maintain any view state whatsoever? Anyone? We gave you a hint earlier.… audience responses …Correct, because the page is using an actionPoller tag, we have to maintain the query in the page’s view state or else the actionPoller tag won’t work. Thus the need for the form.So that bit of information should get you thinking: How could you redesign this page so that it doesn’t use actionPoller, which would eliminate view state altogether. And do this in such a way that the page still refreshes to show the current open Invoices?
  37. MARKUS: You could do this several ways. For example, you could stick with a traditional polling approach and use either a meta tag or a JavaScript function to replace actionPoller. An even more efficient approach, though, that we’ll be demonstrating a little bit later, is to switch to a long polling approach that streams updates to your page.For now, the key takeaway here is this: Don’t maintain view state at all if you don’t have to. In our example, the only reason our page is maintaining view state is because we want to leverage the convenience of the actionPoller tag.[TIMING:16m]
  38. MARKUS: So this simple change, marking read-only variables as transient, totally removes that data from the page’s view state.Alright, we’ve made some good progress making our Visualforce page more memory-efficient with just a few simple changes. What’s next?
  39. MARKUS: Alright, now that you have a good idea of how to minimize view state and the memory required to render a Visualforce page, let’s switch gears and see how to make database access efficient. And here to help is Steve.STEVE: Thanks Markus. I think we all know, as Visualforce developers, that database access is a common bottleneck in data-driven applications. So the efficiency with which your Visualforce page controller accesses the Force.com database can directly affect the page&apos;s response time.
  40. STEVE: Some key things we’ll be focusing on in the next few minutes include the efficiency of the SOQL in your page controllers, and the logic within your controllers. Both are important factors for database efficiency.
  41. STEVE: First, let’s start with building and executing efficient SOQL queries in page controllers.
  42. STEVE: We already learned a little about SOQL query tuning in the previous section, by minimizing the fields that SOQL queries fetch from the database.
  43. STEVE: And we also learned that queries should use a WHERE clause to only fetch the rows from the database needed by the page. But if you are not careful, you might not be accessing the database as efficiently as you think unless you build your WHERE clause conditions with some specific things in mind. For example, who can tell me why this WHERE clause is not optimal?… audience responses …Correct, it’s because the WHERE clause uses a negative operator, !=. Just like most database query optimizers, the Force.com query optimizer automatically uses a full scan of all Invoice records when the WHERE clause condition uses a negative operator, even when the target result set is highly selective. And if there’s millions of Invoice records, that’s going to be a slow query.
  44. STEVE: If facts like this about internals of the Force.com query optimizer are foreign to you, the Technical Enablement group that Markus and I are part of has produced a ton of helpful “under the hood” type information in the form of articles, webinars, and blog posts, all available from the Architect Core Resources page on Developer Force. Remember that URL and visit it often.One such piece of content is the Force.com Query and Search Optimization Cheat Sheet. You can pick up a hard copy of this cheat sheet in the Dev Zone while you are here at Dreamforce, or download a copy from the Architect Core Resources page.It teaches you all sorts of things about query optimization, including information about indexes, operators, and selectivity thresholds. Let’s apply some of this knowledge from this cheat sheet and see how it can make a difference for query execution times, and ultimately, Visualforce page response time.
  45. STEVE: The easy fix here is to modify the WHERE clause with a condition that leverages an optimizable operator. In this case, we change != Closed to = Open.
  46. STEVE: Now, the best scenario would be ifThe custom Status field has an indexAnd the Open field value is selective within that Status field of the Invoices object.As the cheat sheet points out, several standard fields are indexed. But in this case, there would have to be a custom index on Status, considering it’s a custom field. And the only way we can tell if the field value Open is selective would be to gather some stats about the data distribution of field values in Status.[TIMING: 19M]
  47. STEVE: So let’s go back to our live demo and see how some simple changes to the query’s WHERE clause can affect the execution time and investigate the selectivity of the Open field value.=====Switch screen to Workbench original query in place.Run query and note execution time.Change WHERE clause to WHERE = OpenRun query and note faster execution time. Mention that there happens to be an index on the Status field.Run query that shows selectivity stats for the Status field. Explain vs. selectivity thresholds. Again refer to cheat sheet.Return to session deck.[TIMING: 24m]
  48. STEVE: Let’s cover one last possibility to consider for optimal queries inside your Visualforce controllers: Leveraging the Salesforce sharing architecture.All records in Force.com have an owner. A Salesforce org&apos;s sharing architecture determines which users, other than the record owner, can query records of an object that uses an organization-wide default of Private. Now, you might not realize but that in addition to filter conditions, field selectivity, and indexes, the Force.com query optimizer also considers a sharing filter for private records to build an optimal query execution plan.For example, let’s say that a query has a selective filter condition that targets10% of the records in an object, a condition that uses an indexed field value. That’s pretty efficient. But a particular user executing the query can access only 5% of the records in a private object because of an org&apos;s sharing configuration. In this case, the optimizer would use the sharing filter as the primary selectivity driver for executing the query most efficiently rather than the query’s WHERE clause condition. Make sense?So if your org uses a private organization-wide default setting for objects in a Visualforce page controller, it might be best to leverage sharing in the controller. All that&apos;s necessary is that you add the with sharing keywords to the controller’s class declaration.
  49. STEVE: To recap, make sure that with custom controllers, you do everything you can to make SOQL queries execute as efficiently as possible to minimize page response time. Most notably, build queries with selective WHERE clause conditions that reference indexed fields, and don’t forget to use your org’s sharing architecture as long as it makes sense to do so.
  50. STEVE: Great, we’ve already learned a great deal about tuning database-access for Visualforce page controllers. With the example openInvoices page, you’ve seen how some simple database query tuning can really make a difference. Now let’s continue with some other ways that can improve database efficiency in the context of Visualforce pages.
  51. STEVE: With the openInvoices page, we use a custom controller because the page requires some unique logic to support the actionPoller implementation. But if there weren’t any unique logic requirements for a Visualforce page, you should always leverage the page’s default, standard set controller. It’s optimized in many ways to make your Visualforce page access the Force.com database as efficiently as possible. For example, discuss pagination and query more. Get info from Sean’s pagination article. Discuss query more.
  52. STEVE: If you have to use a custom controller or controller extension, there are some general design principles that they should obey for efficient database access. For example, always place SOQL queries and DML statements outside of for loops. Here we see an example of a loop that fetches rows from the database and updates them one by one. There are governor limits in place that would limit just how many iterations of this loop could execute because it would otherwise consume an extraordinary amount of database resources to process. Instead …
  53. STEVE: … you could use a design like this:A single query populates a collection.A loop processes each member of the collection in memory.A single DML statement updates the database, in bulk, with all members in the collection.One query. One DML statement. No worries about governor limits. A much more efficient design because of bulk processing principles.
  54. STEVE: Efficient design is not just for custom page controllers. What about the overall approach to a page? The overall approach itself should be efficient, otherwise, you risk having a slow page response time no matter how database-efficient you make things.To illustrate this concept, let’s take a step back and reconsider the openInvoices page we’ve been using throughout this session for the live demos.
  55. STEVE: Remember, the openInvoices page displays a list open Invoices. This page design causes the page to refresh the entire list of invoices every 15 seconds, no matter whether any updates actually occur. Is this really the most efficient choice for the page design? And is it the most effective approach for our users who are actively watching the page trying to pick out changes to records within the list of invoices? Besides being inefficient, this page design might make all of our users cross-eyed.
  56. STEVE: The approach actionPoller supports is what’s called traditional polling. The current openInvoices page “pulls” information from the server, and it’s the page itself that drives the update. But as I just stated, this design is very inefficient from a resource consumption perspective. It runs a potentially expensive database query every 15 seconds to refresh the page’s list, whether any new open Invoices arrive or not.So why should you care about this design? As long as it gets your users the information they need, what does it matter? Well, consider that the query you use to support actionPoller targets the Invoice object. When you start out, perhaps there’s a small number of Invoices. But as your business grows … and grows … and grows … the number of Invoice records gets quite large. So large that the time it takes to execute the query exceeds the refresh interval. Not to mention, the page consumes resources on behalf of each user that opens the page. So the more people that use the page concurrently … well, you begin to see this is a recipe for tremendous amount of resource consumption in terms of database access in our data center and lots of network bandwidth in your data center – and in the end, a really slow page implementation.So how might you reimplement the page more efficiently?
  57. STEVE: One way is to switch to a more modern approach that “pushes” information to interested “subscribers” only when a change of interest happens—like when a new open Invoice appears, or an existing Invoice becomes open. In fact, this is the approach that most mobile apps use to get push notifications about things of interest. This type of design is known as long polling, and can easily be implemented with the Force.com Streaming API. And there are some side benefits too:Because you rid the page of actionPoller, it no longer needs a form, and no longer needs to maintain any view state whatsoever.Because you are only doing singleton page updates, the load on the database is much lighter, there’s very little network usage, and the page is more responsive.And finally, because you are not updating an entire list, we can make changes to the page much more readily apparent to users, help make them more productive, and save their eyesight.[TIMING: 29m]
  58. STEVE: So let’s take a look at a reimplementation of the openInvoices page that uses the Streaming API and some cool JavaScript so you can see just what it takes to do the job.=====Demo the streaming pageSwitch screen to workshop org, streamingOpenInvoices page with Invoice list overlaid.Clone an open invoice, notice it appears on the streaming page.Highlights, then fades away.Show the page implementation detailsSwitch to Workbench, show the push topic. Explain.Switch to the workshop org with page.Show the page’s controller source code, then page source code. Walk through the parts of the code.Return to session deck.[TIMING: 34m]
  59. STEVE: To recap this section, the overall reimplementation of the openInvoices page echos two key points that we want you to remember from this session:Minimize or eliminate view state for memory-efficient Visualforce pagesDesign database-efficient Visualforce page controllers
  60. STEVE: Now that you understand some key key techniques for building efficient Visualforce pages and controllers, you can apply your knowledge to revising existing code in your org that might be suboptimal. But how do you find source code that has problems? Tools can help a great deal, and that’s what we are going to discuss now.
  61. STEVE: First, let’s do a quick review of the primary Force.com development tools you should know about.
  62. STEVE: Of course, in your browser, you can use the Force.com Setup tool along with the Developer Console to build Visualforce pages and controllers. These browser-based tools are nice, but they don’t provide any features that let you search the source code across an entire org for things of interest, like pages that poll or controllers that don’t use sharing.
  63. STEVE: Then there’s the Force.com IDE, an Eclipse-based plugin that you can use for Force.com development. This tool lets you leverage the power of Eclipse for the Force.com platform, including the ability to search an entire project&apos;s source code for problems.There’s nothing wrong with the IDE, especially if you are already familiar with Eclipse. But some of us find it a bit heavyweight.
  64. STEVE: As Force.com adoption has grown, several third-party and open source tools have emerged to support Force.com application development. The list here includes a few notable considerations.
  65. STEVE: Here, we see a screen shot from one awesome member in this lineup called MavensMate. And here to discuss it more is it’s primary author, Joe Ferraro from Mavens Consulting. Joe?JOE: Thanks Steve. Hi everyone.
  66. JOE: My name is Joe Ferraro and I’m the CTO of a company called Mavens Consulting. We were founded in 2007 by former Salesforce.com employees and we focus on building cloud software solutions for companies in the Healthcare and Life Sciences space. Mavens is committed to supporting the open source community and MavensMate is a great example of that.
  67. JOE: So what is MavensMate? MavensMate is an open source application that equips Force.com developers with powerful tools to build applications in their favorite editors like Sublime Text. MavensMate utilizes a combination of the Salesforce.com Metadata API and the new Tooling API to provide all the functionality you’ll find in the Force.com IDE, but with some advanced features to make developing your applications easier. And I’m proud to say that we now officially support Windows &amp; Linux as well, so thank you for your patience.
  68. JOE: Here is a brief list of some of the features MavensMate offers: Run Apex tests and visualize test passes, failures, &amp; coverageExecute anonymous apex and have those scripts logged for future useApex &amp; Visualforce code assistSetup and fetch debug logs for any user in your orgGreat set of Apex &amp; Visualforce metadata templates that are crowd-sourced from GitHub
  69. JOE: So as we mentioned earlier, it’s one thing to fix problems with Visualforce pages in your org. But finding such problems can be difficult unless you can scan your org&apos;s source code for specific problems, many of which might be tricky to find. For example, DML statements within a FOR loop would be challenging to find, even if you know how to build regular expressions.Let’s see how a great new feature of MavensMate can help with problems like this.
  70. JOE: I’d like to officially unveil a new feature of MavensMate called Project Health Check. With a single mouse click, MavensMate scan the source code of your entire org and gives you a concise report about common problems. You can even drill into a problem and go right to the line in your source code that corresponds to the problem situation.
  71. JOE: So let me take a few minutes to give you a quick tour of MavensMate, including the new Project Health Check feature.=====DEMO StepsCreate project (connect to demo org with standard Apex/VF metadata)Compile an Apex Class (show that metadata templates are being source in real-time from crowd-sourced GitHub repository)Show code assist in VisualforceRun unit testsRun Health Check against demo projectSelect 1 or 2 Health Check items from the reportShow items in projectResolve an item[TIMING: 5-7m]
  72. JOE: To recap, choose your tools wisely for Visualforce development. You may use more than one. In any case, make sure to use tools that can help you:Implement best practices for Visualforce design and development… and tools that can help you scan your org periodically to quickly identify pages that might need a tune up
  73. STEVE: Wow, thanks Joe. That new feature of MavensMate is awesome. I’m sure everyone here is going to install it tonight and start scanning their orgs to see just how healthy things are.Alright, we’ve covered a lot of material in today’s session. Let’s do a quick summary and make sure that you leave here with three key things in mind.[TIMING: Xm]
  74. STEVE: Remember, we told you at the beginning of today’s session that there are a tremendous number of things that we could have covered to help you implement efficient Visualforce pages that respond well and help your users be more productive. But we’ve decided to focus on two or three key things that will make a difference for everyone here.Build memory-efficient Visualforce pages. Examine, reduce, or eliminate what? … everyone! … that’s right, view stateNext, create database-efficient Visualforce page controllers. Execute efficient SOQL queries that use what? … everyone! … that’s right, selective filter conditions and with sharingAnd finally, make your life easier. Use some of these next generation tools like MavensMate that make it easy for you to build and fix Visualforce page implementations.
  75. STEVE: