Optimize your Website Pages performance – Part One

Optimizing your website’s page performance is crucial for several reasons:

  1. User Experience (UX): Fast-loading pages provide a better user experience. Users tend to abandon websites that take too long to load, leading to higher bounce rates and lower engagement. By optimizing performance, you ensure that visitors can access your content quickly and smoothly, improving satisfaction and retention.
  2. Search Engine Ranking: Search engines like Google consider page speed as a ranking factor. Faster-loading pages are more likely to rank higher in search results, leading to increased visibility and organic traffic. Therefore, optimizing performance can positively impact your website’s search engine optimization (SEO) efforts.
  3. Mobile Compatibility: With the growing number of mobile users, optimizing performance becomes even more critical. Mobile devices often have slower internet connections and less powerful hardware than desktop computers. By optimizing for performance, you ensure that your website is accessible and usable across different devices and network conditions.
  4. Conversion Rates: Page speed directly impacts conversion rates. Studies have shown that even small improvements in load time can lead to significant increases in conversion rates. Whether your goal is to sell products, generate leads, or encourage engagement, optimizing performance can help you achieve higher conversion rates and ultimately improve your bottom line.
  5. Cost Efficiency: Faster-loading pages require fewer server resources, leading to lower hosting costs. Additionally, improved performance reduces the need for additional development and optimization efforts in the long run. By investing in performance optimization upfront, you can save money on hosting and development expenses over time.
  6. Competitive Advantage: In today’s competitive online landscape, every advantage counts. Websites that load quickly and provide a seamless user experience are more likely to stand out from the competition. By prioritizing performance optimization, you can gain a competitive edge and attract more visitors to your website.

Overall, optimizing your website’s page performance is essential for enhancing user experience, improving search engine visibility, increasing conversions, reducing costs, and staying ahead of the competition in the digital marketplace.

How we can improve performance in Sitecore website

There are many ways to improve website performance that we can analyze through Lighthouse score and it will provide some suggestions as well but here I will describe only those which i implemented in my project.

  1. Optimize Images – Image optimization is one of the important and easiest way to improve page performance, for improving this I used Dianoga. Dianoga is an automatic image optimizer for the Sitecore media library. Reduce the size of your images served from Sitecore by 8-70%, completely automatically. When media images are requested, Dianoga automatically runs mozjpeg, PNGOptimizer, SVGO or WebP on the image data immediately after it is placed in the Sitecore media cache.
  2. Removed unused CSS and JS files – To address this issue, we’ve adopted a more granular approach. We now serve only the CSS and JS files required for each specific page based on the components and features utilized within Sitecore. By doing so, we ensure that only essential resources are loaded, minimizing unnecessary overhead and improving page load times. This strategy not only enhances performance but also aligns more closely with best practices for web optimization. It allows us to deliver a faster and more efficient user experience while addressing the recommendations provided by performance analysis tools like Lighthouse.
  3. Update Web Config setting – In web.config, set <compilation optimizeCompilations="true" />, we can get full info about this from following link https://blogs.msdn.microsoft.com/davidebb/2009/04/15/a-new-flag-to-optimize-asp-net-compilation-behavior/
  4. Avoids an excessive DOM size –
    • To address the issue typically encountered with the Navigation component, particularly when the navigation tree size is substantial, we’ve implemented a solution that leverages AJAX calls to load navigation child elements dynamically.
    • With this approach, the children of navigation items are not loaded from the server until a user clicks on a specific navigation item. In practical terms, when a user interacts with the navigation menu by clicking on a parent item, an AJAX request is sent to the server to retrieve the corresponding child elements. These child elements are then dynamically injected into the navigation menu, providing a seamless and efficient user experience.

In the first part, I outlined various strategies for enhancing page performance. In the next blog post, I’ll delve into how I refined our solutions to deliver only the necessary JS and CSS to each page, effectively addressing the issue of unused resources impacting performance.

Thanks, hope this helps

AddMoveToTopAndBottomButtons in Sitecore Device Editor

It is frequently necessary to position a new rendering in the device editor at the top, but if there are already a significant number of renderings present and if content authors add a new rendering to a content item, it is by default positioned at the bottom. If the control needs to be positioned at the top, the Move Up button must be clicked each time. So it can be a little annoying to repeatedly hit the Move Up button.

We’ve implemented the “Move To Top” and “Move To Bottom” buttons to make this possible.

Process of implementation:

  1. To accomplish this, we must copy deviceeditor.xml to the root directory at the following location: \sitecore\shell\Override\DeviceEditor.xml.
  2. Copy the AddMoveToTopAndBottomButtons.dll file from the bin folder to the main directory’s bin folder.

If you want to see code, you can get from my GitHub repository.

Replace String in Sitecore Content Tree Using PowerShell

Below is the script that helps you to find and replace all instances in all fields below the Sitecore root item using Sitecore Power shall.

$rootItem = gi master:// -id "{000000-0000-0000-0000-00000000}"
$items = $rootItem | Get-ChildItem -r | ForEach-Object{$item = $_; $_.Fields  | ?{$_.TypeKey -eq "Multi-Line Text"} }
foreach($i in $items){
   
  
   if ($i.Value -Like '*OldText1*' -or $i.Value -Like '*OldText1*') 
   {
         $replaced = $i.Value -replace 'OldText1', 'NewText1'
          $replaced = $replaced -replace 'OldText1', 'NewText2'
        $i.Item.Editing.BeginEdit()
  
    $i.Item.Fields[$i.Name].Value = $replaced
    $i.Item.Editing.EndEdit()
    Write-Host $i.Item.Name  "-Test"  $i.Name
    
   }
}
Write-Host "Updated " $count " Found Data"

Thank

Rishi

Could not find a part of the path in TDS Exception

In my current project I face this problem, we were trying to sync items in bulk from using TDS as shown in below screenshot

Could not find a part of the path 
'D:\Projects\WebsiteProject\TDS\Intranet\TDS.Master.Templates\sitecore\templates\User Defined\Folder1\Folder2\Folder3\Example Template\Example Template Section\title.item'.
Please see the output window for more details. (SitecoreSyncException):
   at HedgehogDevelopment.SitecoreProject.VSIP.Controls.SyncWithSitecore.RunSyncForProject(SitecoreProjectNode project)
   at HedgehogDevelopment.SitecoreProject.VSIP.Controls.SyncWithSitecore.RunSync()


Inner Exception Details:
Exception Could not find a part of the path 'D:\Projects\WebsiteProject\TDS\Intranet\TDS.Master.Templates\sitecore\templates\User Defined\Folder1\Folder2\Folder3\Example Template\Example Template Section\title.item'. (DirectoryNotFoundException):
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
   at System.IO.File.InternalWriteAllBytes(String path, Byte[] bytes, Boolean checkHost)
   at System.IO.File.WriteAllBytes(String path, Byte[] bytes)
   at HedgehogDevelopment.SitecoreProject.VSIP.SitecoreItemNode.RefreshSitecoreInfo(String sitecoreItemPath)
   at HedgehogDevelopment.SitecoreProject.VSIP.SitecoreProjectNode.CreateSitecoreItemNode(String localItemPath, String sitecoreIcon, HierarchyNode parent)
   at HedgehogDevelopment.SitecoreProject.VSIP.Controls.SitecoreSyncTreeNode.DoSyncAction(Boolean& applyToAll)
   at HedgehogDevelopment.SitecoreProject.VSIP.Controls.SyncWithSitecore.RunSyncForProject(SitecoreProjectNode project)
Exception An exception occured while updating the sitecore item \sitecore\templates\User Defined\Folder1\Folder2\Folder3\Example Template\Example Template Section\title.item

Previously, I assumed it was not a File Name Length problem because it was displaying an error related to File Name Error Length in Sitecore logs and TDS output. Then I tried adding aliases to folder names, which solved my problem.

My goal in writing this blog is to help anyone who is experiencing “File Name Length Error in TDS.”

Because by default Microsoft has a character limitation for file paths. The folder and file name must remain under 260 characters. If you’re familiar with Twitter, 260 characters seems like a breeze. However, most projects easily hit that limit. For this we created a work around in TDS.

The File Alias function in TDS allows you to shorten the file path to fit in the requirements that Microsoft set. You’ll probably see the following error if trying to sync items into a TDS project tree that already exceeds the path length:

“The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters”.

Thanks

Rishi

Copy content from one database to another using Sitecore RAZL

In our last project we need to upgrade the solution from Sitecore 8.2 to Sitecore 9.3. To migrate data items from the Sitecore 8.2 project to Sitecore 9.3, we decided to use the Sitecore TDS. But we have some problems with this, the first is the transfer speed, the 8.2 project has a very large database, so it takes a long time to transfer data. Second, there is a problem with the long file path of the core TDS site element. The TDS cannot be synchronized with the Sitecore if the physical element path of the TDS exceeds 260 characters.

To solve this problem, we need to set the folder alias property to fix it. In my case, even with the aliases, the names were too long, even with the aliases of all the above folders. Also, TDS crashed after configuring the filesystem alias. and you move the files which resulted in some but not all aliases being created, creating a corrupted TDS project. After that, we decided to use Sitecore Razl tool for data transfer. Also, the point of using Sitecore Razl transfer speed is much better than TDS and we can do full comparison between two Sitecore databases side by side.

Establishing a Connection

In order to establish a connection, you need to know the URL of the Sitecore instance and the name of the Sitecore database. The developer also needs access to the file system where the Sitecore CMS instance or desktop resides.

  1. Click the Connection Manager button and then click the Sitecore Connection Manager pop-up. In it we can see the connection already created, we can add a new connection and we can also import another connection. To create a new connection, click the Add button at the bottom left of the window.
  • Enter the name of the connection and click the Next button. (If the Read Only Connection checkbox is checked, it means we cannot update, add or delete items from this connection, we can only get the item from this connection.)
  • Now we have to choose the connection type between direct connection and packet connection. In my case, I choose Direct Connection and click Next button.
  • Now click on Test connection button, it took approx. 4-5 min to test the connection. After the test connection is successful, click the Next button.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
  • Then provide the server URL and Webroot path. The Access Guide is automatically generated.
  • On the next screen, select the database and click Next.

Your connection will then appear in the Sitecore Connection Manager window. Follow the same steps with another connection and add it in the connection.

Select the left and right section connection from the top bar drop-down menu and launch the update item. We can update the elements from left to right and from right to left.

Thanks

Rishi

Solr index field indexed with ItemFieldName_txm instead of ItemFieldName_sm

In one of our Sitecore projects we are getting results of news articles using Solr search, and everything was working as expected but suddenly someone noticed that new items which were created in last week not displaying in search results.

We did re-index particular node folder item of last week, rebuilt entire master and web index, clear sitecore cache, Reset IIS and followed all other possible approaches to resolve this issue but we didn’t get success.

After that we started analysing Solr queries then we found that index field name from which we were getting results has incorrect suffix(primary_collection_txm), index field name suffix was _txm instead of _sm(primary_collection_sm).

Then we did analysis of config file and found that computed index field name configuration doesn’t have return type:

<field fieldName="primary_collection" >Sitecore.Demo.PrimaryCollection, Sitecore.Demo</field>

Suffix _txm is used for text collection and that was causing issue, so we just add return type for this computed index field and then reindex items and it’s started working.

<field fieldName="primary_collection" returnType="stringCollection">Sitecore.Demo.PrimaryCollection, Sitecore.Demo</field>

Thanks

Rishi

Copy and replace datasource from Shared Layout to Final Layout in Sitecore using Powershall

Hi All,

In my current project I created a page template and set datasource on shared and final layout but my mistake wrong datasource path copied on final layout and from this template content editors created more than 100 pages, during testing I found that wrong data was showing for header because on final layout datasource was wrong.

For correct this datasource I wrote a powershall script because if I am going to manually update these pages it takes lots of time.

$items = Get-ChildItem -Path “master:/sitecore/content/Site Home” -Recurse | Where-Object { $_.TemplateName -eq ‘Page Template’ }

foreach ($item in $items) {
$sharedRendering = $item.Fields[“__Renderings”].Value
$finalRendering = $item.Fields[“__Final Renderings”].Value
if($sharedRendering -Like ‘*{shared-rendering-datasource-id}*’) {
$replaced = $finalRendering -replace ‘{final-rendering-datasource-id}’, ‘{shared-rendering-datasource-id}’
$item.Editing.BeginEdit()
$item.Fields[“__Final Renderings”].Value = $replaced
$item.Editing.EndEdit()

}
}

Deploy JSS app to Sitecore

In my last blog post we know how to install JSS and run in disconnected mode. In this blog we will run deploy JSS app into Sitecore instance. JSS CLI is used to deploy our app to deploy, which imports all our disconnected content and components into sitecore items that can be edited. Once the app is deployed  to Sitecore we can use connected mode and content author’s can edit app’s content.

Step1 – Configure app’s site and host name

Standard example sites includes a Sitecore Site definition patch file on the following path “my-first-jss-app/sitecore/config/my-first-jss-app.config” here my-first-jss-app is my JSS app name open configuration patch file confirm the hostName attribute matches a host header that the Sitecore server should respond with the JSS app as shown in below screenshot.

If you are running local Sitecore instance, make sure host name is mapped to your localhost via a hosts file entry, i an running on windows so hosts file can be found at “C:\Windows\System32\drivers\etc\hosts” .

Note: Open your hosts file in administrator mode to be able to edit in with default security settings.

 

After adding host entry add binding as shown in below screenshot

Step2 – API Key

Services used by JSS utilize the API Key mechanism provided by Sitecore Service Client. You’ll need to create an API key and note its item ID for use in setting up the sample apps. Login into Sitecore and open the desktop application.

Note: In Sitecore 9.1 and later, the API Key is stored in master database, in previous versions it stored in core database.

 

  • From start menu open Content Editor application.
  • Navigate to /sitecore/system/Settings/Services/API Keys in the content tree, then right click on API Keys item as shown in below screenshot
  • I created a new API key item, and named it as JSSDemo as shown in below  screenshot.

  • We have setup the fields mentioned in above screenshot
      1.  CORS Origins: If you will be using connected mode, the APIs will need to support CORS  so that your dev server (default: http://localhost:3000) is allowed to make HTTP calls to the JSS services. For purely local development setup, use * to allow all origins.
      2.  Allowed Controllers:  It is also possible to use *, but explicitly whitelisting controllers is a best practice.  If you use additional custom SSC API controllers, they would need to be added to this list.
      3. Impersonation User: always specify an explicit user. The impersonation user is a Sitecore user whose security context is used to determine the security rights of the JSS app to Sitecore content. Most apps should use extranet\anonymous, giving them the same security context as any anonymous web user. Note that authenticated users (with valid Sitecore auth cookies) will receive their own security context regardless of this setting; it applies only to anonymous requests.
  • Save API key item and publish and make note of API Key item as shown in below screenshot

Connecting JSS APP to Sitecore

To configure the Sitecore connection, run   jss setup at a command line within your JSS app, and follow the prompts. You will be asked for several pieces of information:

  • website folder – Root physical path of the Sitecore folder used to deploy config files and JSS artifacts.
  • Sitecore host name – Host name of your JSS app for example i configured  http://my-first-jss-app.dev.local
  • Sitecore import service URL – This is the import service URL of your JSS app, by default it consists of host name of your JSS app plus /sitecore/api/JSS/import.
  • API Key ID – API Key item id created previously.
  • Deployment secret. This is a shared secret that enables authentication to deploy your app’s items to Sitecore.

Config deployment

The JSS app is registered with Sitecore using config patches that are deployed to the Sitecore server. Config deployment are of two types

  • Automatic config deployment – It is recommended, it deploy the config patches directly from the JSS App using the JSS CLI. jss setup completed from this technique. for automatic config deployment open CMD within your JSS app and run jss deploy config.
  • Manual  config deployment

App Deployment

 

 

 

 

 

Install Sitecore JSS in quick steps

Hi All,

I am writing a blog series on Sitecore JSS for beginners, this is my first blog for JSS installation.

The Sitecore JavaScript Services (JSS) is a complete SDK for JavaScript developers allowing to build full-fledged modern solutions using Sitecore and JavaScript and being completely disconnected during development and deploy to any platform in a headless configuration with full experience platform capability preserved.

JSS Prerequisites

  • Sitecore 9.0 +
  • Node JS
  • Sitecore JSS license

Installation steps

Install the JSS CLI

JSS includes a command line tool to make it easy to get started and maintain your application. If you’re familiar with angular-cli or create-react-app, this is the same idea but for managing your JS app’s connectivity and deployment to Sitecore. The CLI is installed globally, but it uses commands stored in the app’s node_modules so multiple apps with different JSS versions will just work.

npm install -g @sitecore-jss/sitecore-jss-cli

 

To verify that your CLI installation was successful, run jss –help at any command line.

Choose a JSS application template

The JSS CLI is used to create applications, which can be created from a several application templates. To get started, choose an application template based on your needs and desired frontend framework.

“Which framework you use for JSS is a matter of opinion. JSS provides equal support to React, Vue, and Angular. If you’re a newcomer to modern frontend development and don’t have your own opinion yet, React or Vue are the easiest to get started with.”

Styleguide Templates

Styleguide templates are mirror images of each other, supporting basic Sitecore features (routing, multilingual, GraphQL) and using popular supporting libraries for their frameworks. Each Styleguide template comes with a sample styleguide showing how to use and define various Sitecore field types and patterns in that framework.

  • react The React Styleguide template, based on create-react-app.
  • vue The Vue Styleguide template, based on vue-cli.
  • angular The Angular Styleguide template.

Experimental Templates

Experimental templates are experimental specialized JSS examples. They are examples of how to do advanced tasks, but may not be stable or thoroughly documented.

  • sitecore-embedded-jss-app This app shows how to embed a JSS application inside an existing Sitecore site as a rendering. Read more here.
  • sitecore-javascript-renderings This app shows how to render a JavaScript app as a rendering embedded within a traditional Sitecore MVC site. See JavaScript Renderings for details.

Create application using selected template

Once you have selected a template, it’s time to create your application.

  • Open a command line where you wish to create your application
  • Run jss create <your-app-name> <app-template-name>
  • Sit back and relax while JSS does its work

For example, jss create myapp react would create a React sample in a myapp folder under the current directory.

Once it will completed, you should see message shown in below screen.

Run your application

  • At a command line in your app’s folder, run jss –help to see your options and what they do. This is optional, but recommended.
  • To start the app in disconnected mode which uses locally defined content, run jss start

The app will be built and a local development server will be started. Your default browser should open with http://localhost:3000 and your JSS app is rendered:

Once it will completed you will see the below message on cmd.

And it should open http://localhost:3000 in browser automatically, if installed successfully and jss application will run in disconnected mode as shown in below screenshot.

Installing Horizon in Sitecore 9.3

Hi All,

Today I installed Sitecore 9.3 with Horizon on my machine, so i want to share installation steps with everyone.

Prerequisites

  1. Install Sitecore 9.3
  2. Sitecore Content Management site should be running on https protocol.
  3. Sitecore Installation Framework (SIF) 2.2.0.

Installation Steps

  1. Download  Horizon Installation zip file.
  2. Unzip the zip file, after unpack zip file you will see files shown in below screenshot

3. Open parameter.ps1 file, and specify the following parameters:

For example my instance’s parameter.ps1 is is as follows:

# Parameters
$ContentManagementInstanceName = “sitecore93sc.dev.local”
$ContentManagementWebProtocol = “https”
$SitecoreIdentityServerPhysicalPath = “C:\inetpub\wwwroot\sitecore93identityserver.dev.local”
$SitecoreIdentityServerPoolName = “sitecore93identityserver.dev.local”
$SitecoreIdentityServerSiteName = “sitecore93identityserver.dev.local”
$LicensePath = “C:\inetpub\wwwroot\sitecore93sc.dev.local\App_Data\license.xml”
# General Args
$configsRoot = Join-Path $PSScriptRoot Configs
$authoringHostName = $ContentManagementInstanceName + ‘AuthoringHostClient’
# Configure Sitecore
$sitecoreCM = @{
    Path                      = Join-Path $configsRoot sitecore-cm.json
    SiteName                  = $ContentManagementInstanceName
    AuthoringHostSiteName     = $authoringHostName
    WebProtocol               = $ContentManagementWebProtocol
    HorizonFeatureIntegrationPackageFolder = Join-Path $PSScriptRoot “resources”
    HorizonFeatureIntegrationPackageName = ‘Horizon.FeatureIntegration 3.0.0.zip’
}
# Configure AuthoringHost
$sitecoreAH = @{
    Path                      = Join-Path $configsRoot sitecore-ah.json
    SiteName                  = $authoringHostName
    ContentManagementUrl      = “https://$ContentManagementInstanceName&#8221;
    LicensePath               = $LicensePath
    AuthoringHostPackageFolder = Join-Path $PSScriptRoot “resources”
    AuthoringHostPackageName  = “AuthoringHost.zip”
}
# Configure Sitecore Identity Server
$sitecoreIS = @{
    Path                       = Join-Path $configsRoot sitecore-is.json
    AuthoringHostSiteName      = $authoringHostName
    AuthoringHostPhysicalPath  = “c:\inetpub\wwwroot\$authoringHostName”
    # Please fill in physical path to Sitecore IdentityServer. Example: c:\inetpub\wwwroot\horizon-IdentityServer
    SitecoreIdentityServerPhysicalPath = $SitecoreIdentityServerPhysicalPath
    SitecoreIdentityServerPoolName = $SitecoreIdentityServerPoolName
    SitecoreIdentityServerSiteName = $SitecoreIdentityServerSiteName
}
4. In windows, launch Powershell as an administrator, and run the install.ps1 file.
Once it runs successfully horizon will be installed in with that particular instance set into parameter.ps1 file.
Once Horizon installed, horizon tiles will appears on the launchpad as shown in below screenshot
Thanks
Rishi