【ASP.NET MVC】 Azure에서 공개하고 있는 사이트의 응답이 상당히 좋아졌기 때문에 했던 메모

ASP.NET MVC를 Azure 환경에서 사용



이런 사이트 을 작성 중입니다.
그러나 기능 확장을 해가는 가운데 점점 사이트가 무거워져 버렸습니다.
이대로는 느리기 때문에 누구에게도 필요하지 않은 사이트가 되어 버릴 것 같았기 때문에 저 레이턴시를 목표로 개수했습니다.
목표는 구글 추천 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를로드하기 위해
응답이 좋아집니다.

HogeRepository.cs
    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가 원인의 일부로 판명.
모델에서 문자열과 int 출력 만 있었기 때문에
직접 출력하기로 결정했습니다.
이것은 대량으로 Html.DisplayFor를 실행하는 경우에만 유효합니다.

전송량을 줄이면 지연도 짧아집니다.

3. 출력되는 HTML에서 공백과 줄 바꿈을 삭제합니다.



참고 사이트 부터 WhitespaceFilterAttribute
빌려 프로젝트에 추가합니다.
WhitespaceFilterAttribute 를 Controller 에 붙이면 출력되는 HTML 의 스페이스와 개행이 삭제됩니다.
같은 사이트에 CompressFilterAttribute도 실려 있었지만
하나의 컨트롤러에 둘 다 사용하면 제대로 작동하지 않았기 때문에
나는 효과가 높았던 WhitespaceFilter만 사용하기로 결정했다.
어느 일람 화면에서는 500kb 출력하고 있던 페이지가 200kb까지 떨어뜨릴 수 있었습니다.

HogesController.cs
    [WhitespaceFilter]
    public class HogesController : Controller {
        // Index 等の実装・・・
    }

4. JS/CSS 압축



이것도 기본이지만 할 수 없었습니다.
Web.Release.config에 다음 추가

Web.Release.config
<compilation debug="false" targetFramework="4.5.2" />

5. CSS 스프라이트 사용



나는 ↓ 사이트를 이용하여 각 페이지의 링크 이미지를 CSS 스프라이트로 만들었습니다.
참고 사이트 2

6. 리포지토리 수준에서 캐시 구현



이것은 액세스가 집중된 경우에 유효했습니다.
Hoge 클래스에 ToList라는 모든 레코드를 목록 형식으로 꺼내는 메서드가 있었기 때문에 다음과 같은 상속 클래스를 만들고 Controller는
CachedHogeRepository를 사용하도록 변경했습니다.

CachedHogeRepository.cs
    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를 다운로드/로드하는 동안 스크립트를 다운로드하여 시간을 절약합니다.

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>

(여기까지 추가)

현재는 Azure에서 다음과 같은 응답을 달성할 수 있었습니다.

좋은 웹페이지 즐겨찾기