【ASP.NET MVC】 Azureで公開してるサイトのレスポンスがだいぶ良くなったのでやったことのメモ
ASP.NET MVCをAzure環境で使ってます
こんなサイトを作成しています。
しかし機能拡張をしていく中でどんどんサイトが重くなってしまいました。
このままでは遅いからだれにも必要とされないサイトになってしまいそうだったので低レイテンシをめざして改修しました。
目標はgoogleの推奨する200ms以下のディレイ。
(2018/05/02追記)PageSpeed Insightsで99/97達成したので追記します。adsense/analytics付きなのでここらが限界かなと思います。
(2018/05/18)Azure http2対応したのでサイトに反映。
TestMySiteで2秒がでるようになりました。
しかしPageSpeed Insightsで99/97達成出来なくなりましたorz
参考サイトを見ながら少しずつ進めました。
1. Linq to SQLでIncludeを使う
基本的なことですができてませんでした。。。
HogeのIndexページでHugaクラスの属性も表示する場合
以下のようにIncludeするとDBから一度にHogeとHugaを読み込むため
レスポンスが良くなります。
public List<Hoge> ToList() {
var q = from s in db.Hoges
select s;
return q.Include(m => m.Huga).ToList();
}
2.string/intに対してHtml.DisplayForの使用をやめる
一覧画面で合計4000回ぐらいHtml.DisplayForを読んでいたところ
HTML出力が遅くなっていました。VS2015のプロファイラーで
CPU時間を確認するとHtml.DisplayForが原因の一部と判明。
モデルからはstringとintの出力しかしていなかったため
直接出力することにしました。
これは大量にHtml.DisplayForを実行している場合にだけ有効ですね。
転送量を削減すればディレイも短くなります。
3. 出力されるHTMLからスペースと改行を削除する
参考サイトよりWhitespaceFilterAttribute
を拝借してプロジェクトに追加します。
WhitespaceFilterAttributeをControllerにつけると出力されるHTMLのスペースと改行が削除されます。
同じサイトにCompressFilterAttributeも載ってましたが
1つのcontrollerに両方使用するとうまく動かなかったため
私は効果の高かったWhitespaceFilterだけ使用することにしました。
ある一覧画面では500kb出力していたページが200kbまで落とせました。
[WhitespaceFilter]
public class HogesController : Controller {
// Index 等の実装・・・
}
4. JS/CSSを圧縮する
これも基本ですができてませんでした。
Web.Release.configに以下を追記
<compilation debug="false" targetFramework="4.5.2" />
5. CSSスプライトを利用する
私は↓のサイトを利用して各ページのリンク画像をCSSスプライトにしました。
参考サイト2
6. レポジトリレベルでのキャッシュを実装する
これはアクセスが集中した場合に有効でした。
HogeクラスにToListという全レコードをリスト形式で取り出すメソッドがあったとして以下のような継承クラスを作成しControllerは
CachedHogeRepository を利用するように変えました。
public class CachedHogeRepository : HogeRepository
{
private static readonly object CacheLockObject = new object();
private const string cacheKey = "CachedHogeRepository:ToList";
public override IList<Hoge> ToList()
{
IList<Hoge> result = HttpRuntime.Cache[cacheKey] as List<Hoge>;
// キャッシュにないの場合
if (result == null)
{
lock (CacheLockObject)
{
result = HttpRuntime.Cache[cacheKey] as List<Hoge>;
if (result == null)
{
result = base.ToList();
HttpRuntime.Cache.Insert(cacheKey, result,
null, DateTime.Now.AddHours(12), TimeSpan.Zero);
}
}
}
return result;
}
// 作成更新削除があったらこのメソッドでキャッシュをクリアします。
public override int SaveChanges()
{
var ret = base.SaveChanges();
HttpRuntime.Cache.Remove(cacheKey);
return ret;
}
}
(ここから追記)
7 link rel preloadを利用する
<link rel="preload" as="script" href='@Scripts.Url("~/bundles/jquery")' />
cssのダウンロード/読み込み中にscriptをダウンロードさせることで時間を節約します。
8 CSSや小さなJavaScriptをインラインにする
public ActionResult InlineCss(string Path)
{
BundleContext context = new BundleContext(
new HttpContextWrapper(System.Web.HttpContext.Current),
BundleTable.Bundles,
Path);
Bundle cssBundle = BundleTable.Bundles.GetBundleFor(Path);
BundleResponse response = cssBundle.GenerateBundleResponse(context);
return Content(response.Content);
}
私はHomeControllerに上のメソッドを追加し_Layout.cshtml内で下のように読み込むことで
CSSをインラインにしました。
<style type="text/css">
@Html.Action("InlineCss", "Home", new { Path = "~/Content/css" })
</style>
(ここまで追記)
Author And Source
この問題について(【ASP.NET MVC】 Azureで公開してるサイトのレスポンスがだいぶ良くなったのでやったことのメモ), 我々は、より多くの情報をここで見つけました https://qiita.com/mako-tos/items/90bbc05303ba627dc3c5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .