Blog
ニトロを打つ—KenticoXperienceでのキャッシュ13リフレッシュ1
By Trevor Fayas
リフレッシュ1では、Kentico Xperienceは、既存のコア機能(キャッシュタグ)との統合、変更オプションへの追加、およびまったく新しいものであるページビルダーキャッシュを導入します。
.NetCoreのKenticoXperience 13は高速で、MVCよりもはるかに高速で、Webフォームポータルエンジンよりも非常に高速です。最近のブログ記事で、同じベースラインサイトを使用するKentico Xperience 12 MVCと比較して、.NetCoreでのKenticoXperience13の速度を強調しました。キャッシュがなくても、Kentico Xperience 13Coreはバージョン12を水から吹き飛ばしました。 10〜30ミリ秒の範囲の平均レンダリング速度を示しました(これはデータがキャッシュされた後です)。KenticoXperience12は多くの場合、最初のヒットの負荷が大きく、出力キャッシュでこれらの速度を上回っています。リフレッシュ1では、Kentico Xperienceは、既存のコア機能( キャッシュタグ)との統合、変更オプションへの追加、およびまったく新しいものであるページビルダーキャッシュを導入します。それぞれに飛び込んで、それらがどのように機能し、どれだけ速く物を作るかを見てみましょう!
タグヘルパーと
.Net CoreMVCは
これらのキャッシュ依存関係を取得する方法は別の問題です。理想的には、キャッシュ依存関係内で呼び出されるすべてのデータ項目のさまざまなキャッシュ依存関係をすべて追加する必要があります。幸いなことに(Sean G. Wrightの助けを借りて)、私たちはあなたをカバーしてくれました!
MVCキャッシング統合
私が作成したMVCCachingツールを使用している方のために、バージョン13.0.2には、 ICacheDependenciesScope.Begin()およびICacheDependenciesScope.End()を使用できる新しいICacheDependenciesScope / ICacheDependenciesStoreインターフェイスが組み込まれています。キャッシュされた領域、 ICacheDependenciesStore.Store(string [] Dependencies) -途中ですべての依存関係を取得し、ICacheDependenciesScope.End()メソッドで返します(文字列配列を返します)。 [CacheDependency(““ )]属性を使用するIRepositoryから呼び出されたメソッドはすべて、これらの依存関係をストアに自動的に追加します。もちろん、独自の依存関係を手動で追加することもできます。
以下にいくつかのコードサンプルを示します。
_ViewImports.cshtml:
@usingMVCCaching.Base.Core.Interfaces
@usingMVCCaching.Interceptor;
…
@addTagHelper*, Kentico.Web.Mvc
…
@injectICacheDependenciesScope CacheScope
@injectICacheDependenciesStore CacheStore
@injectICachingRepositoryContext CacheContext
_Layout.cshtml:
<header>
<cacheexpires-after='@TimeSpan.FromMinutes(60)'enabled='@CacheContext.CacheEnabled()'>
@{CacheScope.Begin();}
@*Example of manually adding*@
@{CacheStore.Store(new string[] { $'documentid|{PWPHelper.GetDocumentIDByNode('/Masterpage/Header')}' });}
<inlinewidgetpagedocumentid='@PWPHelper.GetDocumentIDByNode('/Masterpage/Header')'initialize-document-prior='true'>
<vc:partial-header/>
</inlinewidgetpage>
<cache-dependencycache-keys='@CacheScope.End()'/>
</cache>
@*Cache is on the component itself*@
<cacheexpires-after='@TimeSpan.FromMinutes(60)'enabled='@CacheContext.CacheEnabled()'>
@{CacheScope.Begin();}
@*This View Component uses various IRepository calls that are hooked up with MVCCaching, so all dependencies are added to the Store automatically*@
<vc:main-navigationnavigation-parent-path='/MasterPage/Navigation'css-class='MainNav'/>
<cache-dependencycache-keys='@CacheScope.End()'/>
</cache>
@*This adds javascript to highlight the current nav, this way we don't need a Vary-By on the menu and it can be cached for all pages*@
<navigation-page-selectorparent-class='MainNav'/>
</header>
ここでわかるように、2つのヘッダーアイテムがキャッシュされています。 1つは、ウィジェットゾーンのコンテンツを別のヘッダーページから取得する部分的なウィジェットページであるため、そのDocumentIDのキャッシュ依存関係があります。
2つ目は、MVCCachingシステムの一部であるIRepositoryメソッド呼び出しを使用するメインナビゲーションです。私は単にBegin()、-Render-、およびEnd()を実行し、収集された依存関係を< cache-dependencyに渡します。 cache-keys = ' @ CacheScope.End() ' /> 。
CacheDependencyStoreがどのように実装されているか、 およびMVCCachingシステムにどのように関連付けられているかを確認できます。
その他の統合
ICacheDependenciesScopeとICacheDependenciesStoreは、レポで概説しているショーンのすばらしいシステムであるMVCCachingを使用しない場合、簡単に再作成できます。 この時点で、QueryHandlerCacheDecoratorにストアを追加するだけです。彼はまた、このGISTで彼の元のパターンのアイデアの簡単な概要を提供しました。 End()に文字列配列を返さなければならないので、調整するだけなので、依存関係をキャッシュキーに渡すたびに「.ToArray()」を実行する必要はありません。
NewVary-By
Vary-Byを使用すると、キャッシュを「何か」によって変えることができます。これは、キャッシュが外部変数に依存していて、それに基づいて異なるレンダリングを行う必要がある場合に最適です。デフォルトのVary-Bysは次のとおりです。
- Vary-by-header :リクエストのヘッダーパラメータで変更できます(例:「User-Agent」または「User-Agent、content-encoding」
- クエリごとに変更:URLクエリパラメータによって変更できます(例:?category = somevalの「category」)
- ルートごとに変化:ルートマッピングによって決定されたルート値によって変化します(例:「Make」は{controller} / {action} / {Make}のルートで変化します
- Cookieごとに変化:Cookieの値によって異なります(例:「CookieLevel」)
- ユーザーごとに異なります:trueまたはfalse、User.Identity.Nameによって異なります
- 可変:渡されたパラメーターによって異なります。 ToString()、ex(@ Model.SomeVal1 + @ Model.SomeVal2)
更新1では、次の新しい可変パラメータが導入されています。
- Cookieレベルごとに変更:XperienceのCookieレベルのアクセス許可に関連付けられます。
- カルチャごとに異なります:true / false、ユーザーのカルチャに基づいてレンダリングを変更する必要がある場合
- ホストごとに異なります:true / false、コンテンツがレンダリングされるドメイン名に基づいて異なる必要がある場合(同じMVCアプリケーションを共有するマルチサイトインスタンスに役立ちます)
- カスタム変更:更新を使用すると、ICacheVeryByOptionインターフェイスおよびキャッシュされたViewComponentの[CacheVeryBy]属性を介して独自のVary-byオプションを作成できます。
Vary-Byとパフォーマンスへの影響の使用
上記のルールのいずれかに基づいてコンテンツが実際に変更される場合は常に、Vary-byパラメーターを使用する必要があります。ただし、これを行うと、メモリ内にオブジェクトの複数のコピーが作成されることに注意してください。キャッシュされた領域が大量のメモリを使用する場合、メリットを相殺するより大きなメモリインプリントが発生する可能性があります。また、Vary-byが頻繁に異なる場合、アイテムが一致するキャッシュを使用することはめったになく、キャッシュの利点が無効になる可能性があります。
たとえば、元のベースラインサイトでは、メインナビゲーションが現在のページをメニューに渡すため、ユーザーが表示しているページに「アクティブ」クラスを追加できます。つまり、これを行うには、vary-by =” {TheCurrentPage}”が必要になるため、各ページで適切な項目が選択された新しいメニューがレンダリングされます。その結果、各ページに最初にアクセスするたびに新しいメニューが生成され、ページが多いと、メリットが少なくなり、メモリのインプリントが増加します。
そこで、「アクティブ」クラスを設定するロジックがクライアント側で別のキャッシュされていないコードブロックで実行されるように、メニューを変更しました。そのおかげで、メニュー全体を変更せずにキャッシュすることができました。その後、各ページはキャッシュされたメニューを使用し、JavaScriptの簡単な部分が即座にアクティブなクラスを設定しました。すべてのページで共有される1つのキャッシュアイテム。
ウィジェットとページビルダーのキャッシュ
Refresh 1の最後の特徴は、PageBuilderウィジェットのキャッシュです。ページビルダーゾーン(<editable-area/>)では、キャッシュを許可し(allow-widget-output-cache=" true")、キャッシュ期間(widget-output-cache-expires)を設定し、その中のウィジェットでもキャッシュを有効にします(RegisterWidget アセンブリタグの AllowCache = true パラメータを使用)。
このような:
<editable-areaarea-identifier='main'widget-output-cache-expires-after='@TimeSpan.FromMinutes(60)'allow-widget-output-cache='true'/>
[assembly: RegisterWidget(ShareableContentWidgetViewComponent.IDENTITY,typeof(ShareableContentWidgetViewComponent),'Shareable Content',typeof(ShareableContentWidgetProperties), Description ='Displays the widget content of a Shareable Content Page', IconClass ='icon-recaptcha',AllowCache =true)]
次に、ビューコンポーネントに渡されるViewComponentModelプロパティに、これらの依存関係を含めるように設定できるCacheDependenciesまたはCacheKeysプロパティがあります。これらの[CacheVaryBy()]属性を使用して、外部で何かが変化した場合にキャッシュが確実に変更されるようにすることができることを忘れないでください。
結果:どれくらい速くなりますか?
前述のように、ベースラインのクローンでこれらの機能をテストしたため、これらの機能が有効になっていることを除いて同一の2つのサイトを実行していました。次に、ページをX回ヒットし、応答時間をミリ秒単位で平均化する簡単なコンソールスクリプトを作成しました(100回ヒットしました)。スクリプトは、キャッシュが設定されていることを確認するために5つの追跡されていないリクエストでページをウォームアップし、データキャッシュが両方で機能していたため、
特徴 | KX12 MVC(データキャッシングのみ) | KX12 MVC(出力キャッシュ) | 更新前1 :(データキャッシュのみ) | 更新1:データとレンダリングのキャッシュ | パフォーマンスの向上(KX 13 Preより) |
ホームページ(空) | 20.15ミリ秒 | 5.3ミリ秒 | 18.84ミリ秒 | 6.85ミリ秒 | 65%高速 |
ページについて(一部のコンテンツ) | 20.71ミリ秒 | 該当なし | 24.32ミリ秒 | 14.53ミリ秒 | 40%高速 |
サブページ(セカンダリサイドナビゲーション) | 16.96ミリ秒 | 5.16ミリ秒 | 25.71ミリ秒 | 16.39ミリ秒 | 36%高速 |
インラインウィジェットページ(3ウィジェット)–ページビルダーキャッシュが無効 | 該当なし | 該当なし | 24.66ミリ秒 | 20.20ミリ秒 | ベースより18%高速 |
インラインウィジェットページ(3ウィジェット)–ページビルダーキャッシュが有効 | 該当なし | 該当なし | 24.66ミリ秒 | 13.25ミリ秒 | キャッシュされていない更新よりも35%高速1 |
リフレッシュ1の前後でパフォーマンスが向上するのは、すでに高速なレンダリングが大幅に改善されていることは明らかです。
また、Kentico Xperience 12 MVCの出力キャッシュと比較すると、キャッシュされた出力全体を文字通り吐き出すだけなので、出力キャッシュ速度に勝るものはないことに注意してください。ただし、.NetCoreのパフォーマンスがそれほど高くないと思わせることはできません。
出力はKenticoエクスペリエンス12にキャッシュされたすべてのものにキャッシュし、そして何も変化があった場合は、すべてがその固有の出力キャッシュのために再描画されなければなりませんでした。 .Net Coreは同等のパフォーマンスを実現しますが、各要素は個別にキャッシュされます。つまり、メニューだけで何かが変更された場合、メニューのみが再実行され、それが共有されます。したがって、全体として、このキャッシュを備えた.Net Coreは、ページのパフォーマンスを向上させています。 MVCのキャッシュされていないページは、引き続き.NetCoreよりもはるかに大きなパフォーマンスヒットを示します。
結論
キャッシュの依存関係とページビルダーのキャッシュはパフォーマンスを大幅に向上させました。それだけで、ソリューションを更新するのに十分な理由です。 Kentico Xperience 13を初めて使用し、開始点が必要な場合、およびベースラインを使用してこれらのパフォーマンス向上の一部をコピーしたい場合は、更新の開始後、 HBSベースラインが更新されます。
ウィジェットとソリューションを構築するときは、これらの新機能を活用して、サイトの高速性と応答性を維持し、顧客を満足させてください。