Client-side solutions have been de rigueur for a few years now: they’re cloud friendly, and are generally much easier to deploy than server-side code. SharePoint is an enterprise class content management tool, so it’s only natural to store the client code in SharePoint. That was all well and good until Office 365’s large farm sizes rendered SharePoint’s BLOB cache useless, which makes loading static files much slower online than on premises.
So lately Microsoft has been encouraging – and helping – us all to use a proper Content Delivery Network (CDN) for static content. CDN’s are designed for speed and volume; they even address the speed of light problem by fetching files from a data center that’s near the client. This will help your client-side solutions to load noticeably faster, as seen in this chart.
The chart shows the time to download one file, an SPFx bundle from my Quotes web part. For all tests, I warmed up my local DNS cache and forced a refresh in Chrome; I also measured the timing with Chrome’s developer tools. TTFB is the Time to First Byte – that is the amount of time between the browser requesting a page and receiving the first byte of a response. This can include things like DNS lookups and router caches, but I warmed up each scenario, so it’s mainly time spent in the server. You can see that with SharePoint only it’s about half a second slower, since without a BLOB cache, SharePoint needs to go all the way back to SQL for the file. It also may be due to SharePoint only supporting HTTP 1.1 (still?) – so it needs to establish the SSL connection each time. TTLB is, of course, Time to Last Byte; there the transfer time doesn’t vary as much, but still SharePoint manages to be slower.
Using a CDN can be the difference between seeing your web part spin while loading vs. a tiny flicker on the screen.
There are many CDN options out there; I tested two of them for this article. SharePoint Online comes with a free CDN; this is the obvious choice. Azure also offers a CDN, however; I picked the Verizon free plan but there were other options. (Wow that TTFB was fast!)
No CDN
I started by testing with no CDN. Since I was using the SharePoint Framework, I set the “cdnBasePath” in write-manifests.json to the location of a document library in SharePoint.
{
"cdnBasePath": "https://mytenant.sharepoint.com/sites/scripts/public/quotes"
}
Whether I’m using the SharePoint Framework or just a Content Editor Web Part, I like to put shared files in a special site collection that’s secured appropriately. (NOTE: The content editor web part can’t reference files outside of its site collection, but it’s useful to put very simple files in each site collection that pull in the application logic from a shared location; see this article for details.) As you can see in the example, my site collection is called /sites/scripts; within that I have a document library called public (the name will be clear later in this article). Within public, I have a folder for each solution. Nice and tidy.
To deploy to the CDN, I ran a couple gulp commands
gulp bundle --ship gulp package-solution --ship
Then I copied the files from the /temp/deploy folder into the quotes folder in the document library, and I deployed the SharePoint Package (.sppkg) file in the app catalog.
All that directs SharePoint to fetch the web part bundle from the folder in SharePoint. The result works fine, and if the powers that be won’t let you set up a CDN, it’s good enough.
But look – it took over a second to load including the 171.5 ms it spent waiting for the browser to free up a thread to make the request on. A second is an eternity on a web page!
SharePoint CDN
First of all, let me clarify that I used a SharePoint public CDN. That means that anyone with the URL can read the file; it’s not very secure! But the thinking is that’s OK for JavaScript and CSS files… you’re not hard-coding passwords are you? Are you!
SharePoint also supports a private CDN, but it’s not especially useful for web part code and the like. It provides a token-based authorization scheme, where the token is encoded on the URL. SharePoint checks the file’s permissions, and if the user has access, it generates the token and sticks it on the URL. This URL rewriting is cool, but it only applies to image files and the like which are referenced by page content. SharePoint won’t rewrite the URL’s of, say, an SPFx web part’s code bundle, so it’s useless in this context.
To set up the public CDN, you need a few PowerShell commands. First, ensure you have the latest SPO PowerShell commands. Then you can add one or more origins for the CDN. An origin is just a SharePoint document library; put files in the library, and they are automatically deployed to the CDN. How easy is that? Just be sure you don’t put any confidential documents in there!
For example, here’s how I published the origin for my example:
Set-SPOTenantCdnEnabled -CdnType Public -Enable $true Add-SPOTenantCdnOrigin -CdnType Public -OriginUrl sites/scripts/public
Now you know the reason I called the document library “public” – because I planned all along to associate it with the public CDN.
When referencing files, simply prepend the SharePoint library URL with “publiccdn.sharepointonline.com”.
<div> <div>{</div> <div> "cdnBasePath": "https://publiccdn.sharepointonline.com/bgtest17.sharepoint.com/sites/scripts/public/quotes"</div> <div>}</div> <div>
Very informative! Thanx…..I am getting cached image (old) from picture library despite the image was updated.
LikeLike
Hey Bob!
I didn’t know about this post until the series of Twitter messages I saw when I woke up this morning. Seeing those, I had to come out here and check it out. Nice work – truly! Although I came at CDNs from a slightly different (more admin-focused) angle, I like the fact that I called attention to some of the same concerns you did (e.g., public vs private content caching) – lends a bit of confidence 🙂
In any case, I added an update to my post (near the bottom) to call attention to this article and give it some of the love and attention it deserves (https://sharepointinterface.com/2020/08/22/what-cdn-usage-does-for-sharepoint-online-spo-performance/) I’m sure the 3.5 readers my blog has (and their moms) will appreciate the annotation and additional reading you provide here.
Have a great day, and again – really awesome work! Thanks for sharing 🙂
– Sean
LikeLiked by 1 person
Thanks Sean – your article is great too and definitely readers here should check it out! I love your explanation of how many files a browser can fetch at a time and how that affects the whole page; this actually shows up in my data (the 171.5 ms delay for SharePoint) – we didn’t even plan it that way :).
LikeLiked by 1 person