Category: Salesforce

Understanding Experienced Page Time

With Winter ‘19, we have exposed Experienced Page Time (EPT) to everyone on the Salesforce Platform. This EPT metric, better understood as Page Load time, can be explored through the Lightning Usage App which highlights the performance at both a browser and page level. This blog post is going to help you understand how we define and calculate EPT.

Lightning Usage App

The Lightning Usage App is a new way to track adoption and usage of Lightning Experience so you can monitor progress and make informed decisions. With insights like daily active users, the number of users switching to Salesforce Classic per day, and the most visited pages in Lightning Experience, you can better understand your users’ needs and focus on the issues that really matter.

The app is available right from Lightning Experience. Simply click the App Launcher icon in the navigation bar, type Usage in the search box, then click Lightning Usage. In the app, you can click tabs in the ACTIVITY or USAGE sections on the left side of the page to view the associated data.

In the graph featured below, we are able to see the performance metrics for an example org leveraging the Lightning Usage App. This graph will vary from org to org as it is tailored to you. In this particular org, we can see that there was a spike in Android use in June and that Salesforce Mobile has the least EPT overall.

A view of the Browser Performance tab of the Lightning Usage App


In our next graph, we can quickly view the performance of our most viewed pages. We can see that in this org, Feed Items tend to load really fast, as well as Chatter.

A view of the Page Performance tab of the Lightning Usage App


Defining EPT

EPT is a performance metric Salesforce uses in Lightning to measure page load time. The idea behind this metric is to time how long it takes for a page to load so it’s in a “usable state” for a user to meaningfully interact with it.

The base definition of EPT may be simple, but a lot of things can affect it. We’ll explain more in the next section.

How do we calculate that?

A major difference between Salesforce Classic and Lightning Experience is that pages load progressively in Lightning, while pages in Classic are generated on request by the server. Due to the progressive loading from the client (that any loaded component in the page might arbitrarily load more sub-components at any point in time), measuring when a page has “finished” loading is not straightforward. Since EPT is the page load time that the end users experience, a lot of factors can come into play in calculating the value.

For instance, component implementation details, errors, and caching can all negatively impact EPT. There are also external factors like network quality, browser performance, and user interactions with the page while it’s loading.

Some other things

A Look at Robotics Ridge (DF18 Edition)

At TrailheaDX in 2018, a few of us Salesforce evangelists had the brilliant idea to build a demo with robots. The idea was centered around the Fourth Industrial Revolution and showing how Robotics and Artificial Intelligence could play a big role in our lives. We wanted to show how Salesforce could be at the center of everything; your customers, partners, employees, and robots.

After the crazy success and fun we experienced with Robotics Ridge, we decided we wanted to bring it back and make it better than ever for Dreamforce 2018. This is the story of what we added to our demo, what we improved and how we overcame the challenges we faced at TrailheaDX. If you want to read more about the original demo and challenges, check out Philippe’s post.

An order fulfillment system

Robotics Ridge was an order fulfillment process with two separate pipelines. We wanted to show that an ordering process could have two simultaneous flows, similar to a real production factory. The left side and the right side of the stage each ran the same demo, but could be controlled independently.

Image of Robotics Ridge before the show began.


If you look carefully at the image above, you’ll notice there are five different robots on stage. From the left to the right you will see an ARM, a custom Linear Robot, an ABB YuMi, another custom Linear Robot and a final ARM. Each of these robots worked together to pick up a requested payload and deliver it the front of the stage near the YuMi.


Image of the ARM robot on its own


The ARM robot is a robot made by the company GearWurx. It is mounted on a tripod and can be controlled in a few ways. It has a manual controller that has a slider for each degree of freedom, but we wanted the arm movements to be automated. We used a Raspberry Pi 3B+ with a servo hat. The ARM was also equipped with a Raspberry Pi Camera attached near the gripper. We wrote a Node.js app to control everything, from the movement to the picture capture.

Linear robot

Image of the Linear Robot robot on its own


Our linear robot was a custom robot we built just for TrailheaDX and then modified for Dreamforce. It is controlled by a Raspberry Pi 3B with a Pi-Plate Motor Plate for movement and an Aurdino Mega to control NeoPixel lights that would guide your eye to where your package is, all controlled via a Python script. The lights, not currently pictured, were attached to the front of the robot on the top bar near the cart. The build was inspired by the OpenBuilds Linear Actuator build and was created using Aluminum V-Slot beams from OpenBuilds.


Image of the YuMi on its own


The YuMi is a robot from ABB. It is a human-friendly robot that has many collision sensors that keep

Building Real-Time Lightning Apps Gets Even Simpler

Building modern apps that react to changes in real-time used to require some implementation effort, but the latest update to our streaming technologies greatly simplifies things. In this post we will go through a brief refresher on the Streaming API and we will introduce you to a new way of subscribing to streaming events using the lightning:empApi component. We’ll give you an overview of this game changer plus some sample code.

A brief refresher on the Streaming API

The Streaming API enables the streaming of near real-time events using push technology. This can be used to react to data changes or to broadcast messages across different systems for integration purposes.

With the release of Change Data Capture (CDC) in Developer Preview in Winter ’19, the Streaming API now includes four types of events: PushTopic events, generic events, platform events and CDC events. Each of these event types have their own characteristics but they all rely on the same routing technology: CometD.

In other words, CometD acts as a radio and all streaming events are registered as channels. These are the streaming channels currently available:

Event type Channel Description Example PushTopic event /topic/<Topic_Name> A PushTopic event /topic/MyPushTopic Generic event /u/<Event_Name> A generic event /u/MyGenericEvent Platform event /event/<Platform_Event_Name> A platform event /event/MyPlatformEvent__e CDC event /data/ChangeEvents All CDC events (standard and custom) CDC event /data/<Standard_Object_Name>ChangeEvent A CDC event associated to a standard object /data/AccountChangeEvent CDC event /data/<Custom_Object_Name>__ChangeEvent A CDC event associated to a custom object /data/MyCustomObject__ChangeEvent

Up till Winter ’19, developers had to manually manage CometD connections in JS in order to subscribe to streaming events in Lightning. Now times are changing! What used to be a rather complex setup is now greatly simplified with lightning:empApi, a new Lightning component that streamlines the use of the Streaming API (pun intended).

A game changer

If you were already establishing and managing CometD connections in Lightning, you’ll quickly see why lightning:empApi is a game changer: it provides an abstraction layer that increases performance and greatly reduces code complexity.

Performance increase

lightning:empApi increases streaming performances by saving some precious time on the CometD server connection initialization and reducing network traffic.

What happens behind the scenes is that as soon as a Lightning page loads, we are establishing a CometD connection in the background. This was already the case prior to Winter ’19 but we were reserving that connection for internal use. You had to establish your own connection in parallel for custom components.

With lightning:empApi you can now benefit from a single shared connection. Thanks to that, you no longer have to configure CometD, establish a connection, and wait for it to become available before subscribing to a streaming event. This reduces network traffic and solves potential connection conflicts you might have experienced in the past. You can now safely and efficiently add multiple lightning:empApi components to the same page.

Reduced code complexity

lightning:empApi greatly reduces code complexity by allowing you to get rid of close to a hundred lines of code for

Introducing New Content Security Policy Options for Lightning Communities

Trust has always been our #1 value here at Salesforce. We hold ourselves accountable for keeping your data secure at all times.

Community Cloud helps you build a digital experience for your customers, partners, and employees to interact with your company. Often, this requires bringing in resources from third parties (such as Google) in order to provide a comprehensive solution that fits your needs. With the Winter ‘19 release, we’ve added additional security options so that your new Lightning community has the flexibility to use the external resources you need.

The browser’s Content Security Policy (CSP) is a defense in-depth mechanism – it reduces the harm that malicious code can cause. CSP works by defining the “Content-Security-Policy” HTTP header, which instructs the browser what resources it can render or execute. It is meant to be used in addition to proper development patterns in order to mitigate potential damage from Cross-Site Scripting (XSS) attacks. To learn more about XSS, check out our Secure Coding Guidelines. We have, and will continue to provide, XSS protection for Salesforce components.

The combined policy

CSP for Lightning Communities is split into two parts. One part references the set of CSP directives shared with Lightning Experience (LEX). The second part is an additional set of script-src directives that are specific to each community.

Shared CSP directives

In LEX , we already support many CSP directives:

connect-src frame-src img-src style-src font-src media-src

As of Winter ‘19 our new Lightning Communities CSP can use these directives as well.

This means that non-script resources included in a Lightning Community will need to have their URLs added to CSP Trusted Sites before going live with the new security options. For example, if you are loading images from a third-party host in your head markup, you will need to whitelist that host on the CSP Trusted Sites page. Entries in the CSP Trusted Sites whitelist can be applied to LEX, all Lightning Communities, or both.

You can modify your CSP Trusted Sites in Setup under Security > CSP Trusted Sites.

Each of the trusted sites that is declared in that UI is given a name (e.g. “GoogleMaps”) which may be referenced elsewhere in our platform. Each of the trusted sites is also persisted in the CSPTrustedSites entity.

Script Src

In addition to the other directives, we are now adding a way to include additional third-party scripts on the page. Script resources can’t be added to CSP Trusted Sites in LEX at this time.

This is a much more complex area, as much of the XSS protection offered by CSP requires you to implement strict CSP. Strict CSP defines tight constraints on the script-src directive so that only trusted scripts can be executed. However, in many business applications, it is not possible to implement strict CSP and include all of the third-party services necessary for your business. To give you flexibility, the Winter ‘19 release offers two new levels of security for Lightning Communities: strict CSP and relaxed CSP.



What’s New in Sample Apps for Winter ’19

Winter ’19 is here with new and exciting features for developers! Like always, we have updated the Sample Gallery applications to leverage the features available in this new release. We are excited to share the Winter ’19 version of the sample apps in this blog post.

New Lightning Components

Winter ’19 comes with new components like lightning:map, lightning:menuDivider, and lightning:menuSubheader. Check out the Component Library to familiarize yourself with these new components as well as the existing ones. There are now 157 components available out-of-the-box!

As an example, the lightning:map component is used in the DreamHouse app to show the property location on the record page.

You can add a map to a component with a single line of code:

<lightning:map mapMarkers=”{!v.mapMarkers}” zoomLevel=”{!v.zoomLevel}” />

Check out the RecordMap component to learn more.

New and easy way to subscribe to Streaming API topics and platform events

lightning:empApi is another new component that makes it easy to subscribe to Streaming API topics and platform events. You no longer have to use a static resource to import a version of a CometD library.

To subscribe to a Streaming API topic or a platform event, simply add lightning:empApi to the markup (.cmp) file of your custom component:

<lightning:empApi aura:id=”empApi” />

Then, add the following code to your component controller or helper:

subscribe: function (component, event) { var empApi = component.find(“empApi”); var channel = “YourChannelName”; var replayId = -2; empApi.subscribe(channel, replayId, $A.getCallback(function(message) { // handle message })); }

Usage in sample apps:

In PureAloe, lightning:empAPI is used to subscribe to the BundleStatusChange Streaming API topic (bundlePath component) and to the Field_Status_Change__e platform event (harvestFieldMap component). In Northern Trail Outfitters, lightning:empAPI is used to subscribe to the MixStatusChange Streaming API topic (MixPath component), and to the Einstein_Event__e platform event (EinsteinTwitterFeed component). New Apex caching annotation

Winter ’19 makes it easy to cache Apex method call responses at the client-side and improve the performance of your applications. Prior to Winter ’19, you had to call setStorable() in JavaScript on every action object that called an Apex method whose response you wanted to cache.

var action = component.get(“c.getItems”); action.setStorable(); action.setCallback(this, function(response) { // handle response }); $A.enqueueAction(action);

In Winter ’19, you can now centralize your caching strategy directly in Apex controllers by annotating methods with @AuraEnabled(cacheable=true).

@AuraEnabled(cacheable=true) public static List<String> getItems() { }

Usage in sample apps:

The new caching annotation is used throughout all the sample apps to improve their performance. For example, check out:

PropertyController.cls in Dreamhouse FundController.cls in DreamInvest MerchandiseController.cls in PureAloe MerchandiseController.cls in Northern Trail Outfitters CustomerServices.cls and MarketServices.cls in Easy Spaces

Read this blog post to learn more about storable (or cacheable) actions, but remember to use the new syntax.

New Lightning Console JavaScript API methods

Winter ’19 changes the default navigation behavior of menu items in console apps. As a developer, you can use new methods of the Navigation Item API (part of the Lightning Console JavaScript API) to programmatically control the


Upcoming Maintenance on Developer Edition Signup for Winter ‘19

Heads up, Salesforce Developers and #AwesomeAdmins – we will be performing maintenance on our sign-up infrastructure this weekend to bring the Winter ’19 Release to new Developer Editions and Admin Playgrounds. During this maintenance window, you will not be able to sign up for brand-new accounts, but you WILL be able to access your existing accounts.

Here’s the timeline for this upcoming maintenance:

Friday, Oct 12th, 2018 at 4 PM PST: New Developer Edition sign-ups pause and maintenance window begins. Saturday, Oct 13th, 2018 at 2 AM PST: Sign-ups resume for users in the AMER (North, Central, & South America) & EMEA (Europe, Middle East & Africa) regions. Saturday, Oct 13th, 2018 at 2 PM PST: Maintenance window ends. Sign-ups resume for all users.

These times are approximate, so make sure you are following @SalesforceDevs on Twitter for updates. If you think you will need a new Developer Edition during the maintenance window, we encourage you to sign up for a new Developer Edition right away. Again, access to existing Developer Editions will not be affected.

Want to learn more about the exciting Winter ‘19 release? Check out our Winter ’19 Release Readiness broadcast.

Configuration First: Replacing Code at Runtime

At Salesforce you have heard the saying “Extend Salesforce with Clicks, Not Code.” However, there are times we must code to extend Salesforce — why not extend code to support clicks? After all, using configuration to change the runtime behavior of code is possible, if you are willing to follow good design principles and use the provided aspects in Apex.

This blog post will provide more details as how one might go about the “configuration first” in code. This post will specifically only address logging (cross-cutting concern); however, the other concerns (caching, exception handling, etc.) follow the same pattern.

Which hammer?

Take Logging for example. It seems easy but it can become an issue no matter how small or large the project is. Here are issues I have experienced (you may as well):

Too verbose Not verbose enough Disagreement on log level Disagreement on which layer to log Inconsistent logging behavior

Figure 1 Complexity of where to log?

Even if you could agree upon some of the above aspects, you still encounter code like:

private void determineCachePartition(String category, String label) { if(Test.isRunningTest()){ System.debug(logginglevel.INFO , ‘Entered ‘ ); } : : if(Test.isRunningTest()){ System.debug(logginglevel.INFO ,‘Exited‘); } }

Figure 2 Example logging code

Why is this considered a problem? The above code is only writing to the system debug log and only during tests. In production, or not running tests, it provides no value when trying to determine entry/exit for users. In addition, the class and method were excluded and only informational data is provided. The tightly coupled dependent code has the following issues:

Dependent upon system debug log Dependent upon test execution Tightly coupled to INFO logging level and system log No means to vary the logging level or output content

As you can see, something like logging is more challenging than you may think. Couple this with different development teams, experience, changing requirements, and needs and the problem becomes more exacerbated — and this is only logging! Taking other cross-cutting concerns into consideration (exception handling, caching, etc.) we begin to see our code becomes very brittle and subject to software rot. We need the right hammer to address these issues.

New hammer / Apex Cross-Cutting Concerns

As discussed previously, these issues with logging surface in other cross-cutting concerns. We need to find a new hammer. This new hammer has a goal. The goal is to split code into loosely-coupled, highly-cohesive components and then glue them back together in a flexible manner to meet different requirements based on environments. To realize this goal, I decided to develop an unmanaged package I called Apex Cross-Cutting Concerns/ACCC (found in GitHub).

Cross cutting concerns are aspects, such as, logging, exception handling, caching, etc. which are found in your basic code layers, i.e., Presentation, Business and Data; thus, cross-cutting

Let’s go back to the original example and compare the old hammer with the new hammer.

Old hammer

private void determineCachePartition (String category, String label) { if (Test.isRunningTest ()) { System.debug (logginglevel.INFO,


Developers at #DF18: Developer Keynote and More on Day 3

The third day of Dreamforce 2018 brought us the Developer Keynote and a very special surprise! Of course, there were lots of sessions presented by our community and other keynotes and events in the Trailhead Zone and around the Dreamforce campus. We’ve got all the highlights right here for you.

Salesforce MVP Gaurav Kheterpal delivered a session on Storefront Reference Architecture (SFRA) in Commerce Cloud, talking about how to leverage it for mobile-first sites.

Learning a lot about @CommerceCloud SFRA from @gauravkheterpal

— Peter Knolle (@PeterKnolle) September 27, 2018

In a Trailblazer Community Campfire session, Radhika Bansal and Daniel Peter spoke about utilizing Trailblazer Community Groups to connect with other developers, even when you’re traveling.

@RadhikaBansalSF & @danieljpeter sharing the experiences and benefits they have had by travelling and connecting with the @Salesforce #TrailheadCommunity #DF18 @AccentureTech

— Kerry Townsend (@KerryTownsend) September 27, 2018

Dan Appleman, CTO of Full Circle Insights, taught developers how to build custom configuration pages with Lightning components and custom metadata.

@danappleman teaching a full Developer Theater about custom configuration pages with Lightning components and custom metadata

— Paul Battisson (@pbattisson) September 27, 2018

John Daniel from Rootstock Software and John Storey from MIL Corp talked about advanced tools and techniques to adopt Salesforce DX for unlocked packages. Did you miss this session today during your time at DF18? They’ll be presenting again tomorrow at 8AM PST!

Absolutely JAM packed session to hear @ImJohnMDaniel & @stohn777 demonstrate how to adopt #SalesforceDX Unlocked Packages #DF18

— Alex Sutherland (@apexsutherland) September 27, 2018

Day 3 across all of Dreamforce focused on Equality, with a couple of fireside chats and the Equality Summit Keynote featuring Tracee Ellis Ross and Adam Rippon.

“When you have access you are given not only the opportunity — but the responsibility to use it!” @Adaripp #DF18 #EqualityForAll

— Office of Equality (@SalesforceEQ) September 28, 2018

We are all using Trailhead to learn, and it is constantly evolving. Sarah Franklin, the EVP of Developer Relations and GM of Trailhead, along with Chris Duarte, Kris Lande, Leah McGowen-Hare and a few Trailblazers, spoke about best practices to drive Salesforce adoption and scale onboarding with your own branded and customized content with myTrailhead.

@TheChrisDuarte: The real magic of @trailhead is that it is hands-on”

💯 agreed. And for me that is also what makes it so fun! #DF18

— Jacob Lehrbaum (@jlehrbaum) September 27, 2018

Last but definitely not least, all eyes were on the Developer Keynote! Christophe Coenraets, Zayne Turner, Qingqing Liu, and Margaret Francis told us all about building apps of the future: faster, more integrated, and smarter. Through demos and Trailblazer stories, we learned all about the latest and exciting developments in building on Salesforce.

A lot of familiar faces at the @SalesforceDevs keynote! #DF18

— Adam Olshansky (@adam17amo) September 27, 2018

@ccoenraets is talking about how you can build apps fast in


Developers at #DF18: The Fun Continues on Day 2

Day 2 of Dreamforce brought out some heavy hitters in the developer world. From Salesforce co-founder Parker Harris discussing the future of IdeaExchange, to our developer evangelists offering valuable insight on the various uses of Salesforce DX, it was a big day in the world of developing. Check out more #DF18 highlights here.

Flagstar Bank’s lead Salesforce developer Jay Janarthanan sparked the Trailblazer Community Campfire with valuable insights on the Salesforce Connector for Mulesoft and its various use cases like platform events, ETL, composite messages, and more.

It’s on! So many trailblazers came to hear from @JayOnSoftware… join us!

— MuleSoft Developers (@MuleDev) September 26, 2018

Salesforce MVP and TexeiFrance CTO Fabien Taillon gave a talk on how he moved his company’s developer workflow over to Salesforce DX and unlocked packages, and why they’re here to stay.

@FabienTaillon telling @SalesforceDevs about how he moved @TexeiFrance to implement #SalesforceDX and #UnlockedPackages @Dreamforce #DF18

— John M. Daniel ☁ (@ImJohnMDaniel) September 26, 2018

David Frudd, senior developer at FinancialForce, talked accessibility and building the apps everyone loves, syncing social inclusivity with building your own Lightning Components and Lightning Apps.

@frup42 talking about accessibility – salesforce for all ! @FinancialForce @SalesforceDevs #DF18

— Alba Rivas (@Alba_ARivas) September 26, 2018

We held our always-popular Meet the Developers session. The technical leadership team at Salesforce sat down for some Q&A with attendees. It was a valuable opportunity to hear directly from the product owners and engineers who build all aspects of the Salesforce Platform.

Meeting the Developers Breakout #DF18 @SalesforceDevs

— Jennifer W. Lee (@jenwlee) September 26, 2018

The Integration Keynote featured Pop Health’s Mike Berger, Unilever’s Reema Jain and Jane Morgan, and MuleSoft’s Mark Dao, Vidya Peters, and Greg Schott. Together, they covered integration, the customer touchpoint, and how MuleSoft helps them create more connected experiences for their customers.

We want to create frictionless experiences. Anypoint Platform is how we’re getting there. – Mike Berger, @MountSinaiNYC VP #DF18

— MuleSoft (@MuleSoft) September 26, 2018

Salesforce co-founder Parker Harris joined Bret Taylor, Kristen Engelhardt, Eric Jacobson, and Jennifer Sacks to discuss the future of a more transparent IdeaExchange, making way for meaningful, progressive dialogue around product direction and the Trailblazer Community’s role in that initiative.

Parker Harris is previewing our re-energized IdeaExchange with Bret Taylor. We’re re-committed to listening to our customers’ ideas about how our products can be even better. The Ohana rocks! @salesforce #DF18 @parkerharris @btaylor

— Stephanie Buscemi (@sbuscemi) September 26, 2018

Salesforce developer evangelism director Peter Chittum talked about the Salesforce CLI and how it can be used to connect with many parts of your org aside from Application Lifecycle Management. He also offered hands-on examples to boost your productivity. As Peter has said a few times, if you can write a Salesforce formula, you can use the command line. For proof, check out one of his previous sessions on writing command lines