RazorEngine работает медленно

У меня есть приложение MVC5, которое использует RazorEngine для создания электронных писем. Каждое электронное письмо находится в шаблоне cshtml. В шаблоны передаются данные, поэтому их кэширование не очень помогает, хотя я это делаю. Есть ли что-нибудь еще, что я могу сделать, чтобы уменьшить время, необходимое для рендеринга? Для рендеринга на сервере Azure требуется несколько секунд.

@{
    ViewBag.Title = "_EmailResetPassword";
}

@{ var PasswordToken = Model.token; }
@{ var URLpath = Model.URLpath; }
@{ string link = string.Format("http://{0}/Account/ResetPassword/?tokenid={1}", URLpath, PasswordToken); }

<html>

<head>
<title></title>
<style type="text/css">
.auto-style1 {
    text-align: center;
}
.auto-style2 {
    background: white;
    text-align: left;
    font-size: 11.0pt;
    font-family: Helvetica, sans-serif;
    color: #4D4D4D;
}
</style>
</head>

    <body>
        <div class="auto-style1">

        <h3 class="auto-style2">Dear @Model.FirstName,</h3>

        <h3 class="auto-style2">We have reset your password at Eph Apparel for the username: @Model.UserName</h3>

        <h3 class="auto-style2">Please click on the following link to create a new password:</h3>

        <h3 style='text-align:center;background:white'><span lang=EN-CA
        style='font-size:11.0pt;font-family:"Helvetica","sans-serif"'>
        <a href="@link">Reset Password</a></span></h3>

        <h3 style='text-align:center;background:white'><span lang=EN-CA
        style='font-size:11.0pt;font-family:"Segoe UI","sans-serif";color:#4D4D4D'>LIKE US ON </span>
        <span> <a href="https://www.facebook.com/ephapparel" target="_blank"><img alt="" width=25 height=22
        src="http://ephoms-prod.azurewebsites.net/images/eph_graphics/fb_icon.png" ></a></span>
        &nbsp;<span lang=EN-CA style='font-size:11.0pt;font-family:"Segoe UI","sans-serif";
        color:#4D4D4D'>&nbsp;FOLLOW US ON </span><span lang=EN-CA></span>
        <span><a href="https://www.twitter.com/ephApparel" target="_blank"><img alt="" width=25 height=23
        src="http://ephoms-prod.azurewebsites.net/images/eph_graphics/twitter_icon.png"></a></span></h3>
        <br>
        <img alt="" src="http://ephoms-prod.azurewebsites.net/images/eph_graphics/eph_logo.png">
        </div>

    </body>

</html>

Код позади:

private string ResetPassword(Customer oCustomer, string oToken)
{
    string oURLpath = GetConfigSettingById(3);

    string template = System.IO.File.ReadAllText(HostingEnvironment.MapPath("/bin/EmailTemplates/_EmailResetPassword.cshtml"));
    string message = Razor.Parse(template, new { FirstName = oCustomer.FirstName, UserName = oCustomer.Email, token = oToken, URLpath = oURLpath }, "Reset");
    return message;
}

person Craig    schedule 26.06.2014    source источник
comment
RazorEngine может работать медленно, в зависимости от того, что вы делаете... Можем ли мы увидеть какой-нибудь код, который поможет оценить?   -  person Dylan Corriveau    schedule 26.06.2014
comment
В дополнение к двум другим очень уместным вопросам, вы запускаете это локально, используя отладку в Visual Studio? Если да, то насколько медленно что-то происходит во время локальной разработки, ни на что не влияет. Время тестирования производительности на готовом к работе сервере.   -  person Chris Pratt    schedule 26.06.2014
comment
Это выполняется на рабочем сервере в Azure. Для рендеринга представления требуется несколько секунд.   -  person Craig    schedule 26.06.2014


Ответы (1)


private string ResetPassword(Customer oCustomer, string oToken)
{
    string oURLpath = GetConfigSettingById(3);    
    string template = System.IO.File.ReadAllText(HostingEnvironment.MapPath("/bin/EmailTemplates/_EmailResetPassword.cshtml"));
    string message = Razor.Parse(template, new { FirstName = oCustomer.FirstName, UserName = oCustomer.Email, token = oToken, URLpath = oURLpath });
    return message;
}

Я собираюсь пойти на риск и сказать, что именно здесь происходит ваше замедление... Такие операции довольно затратны на сайте, особенно если он выполняется в другом месте (например, в Azure). Эта операция буквально загружает весь файл, а затем заполняет его каждый раз, когда вы сбрасываете пароль.

Обычно есть 3 варианта, которые вы можете сделать с электронной почтой.

  1. Оставьте все как есть (работает, но медленно)
  2. Воспользуйтесь подходом с шаблонами/кешированием (который я добавлю через несколько секунд и вызовет значительное замедление при запуске, но во время работы он становится намного лучше).
  3. Попробуйте сторонний API (я обнаружил, что Postal довольно хорош с точки зрения скорости, когда я сделал что-то подобное на своем последний сайт)

Чтобы создать шаблон, выполните следующие действия:

  1. Во-первых, превратите Razor Elements в новый класс. IE:

    public class ResetPassword
    {
        public string FirstName { get; set; }
        public string Email { get; set; }
        public string Token { get; set; }
        public string UrlPath { get; set; }
    }
    
  2. Затем измените свой html, чтобы использовать новый класс в качестве модели:

    @model Your.Namespace.ResetPassword
    @{
        ViewBag.Title = "_EmailResetPassword";
        string link = string.Format("http://{0}/Account/ResetPassword/?tokenid={1}", Model.URLpath, Model.token); 
    }
    <html>   
     <head>
          <title></title>
          <style type="text/css">
          .auto-style1 {
             text-align: center;
          }
          .auto-style2 {
             background: white;
             text-align: left;
             font-size: 11.0pt;
             font-family: Helvetica, sans-serif;
             color: #4D4D4D;
          }
          </style>
    </head>
    <body>
        <div class="auto-style1">
    
        <h3 class="auto-style2">Dear @Model.FirstName,</h3>
    
        <h3 class="auto-style2">We have reset your password at Eph Apparel for the username: @Model.UserName</h3>
    
        <h3 class="auto-style2">Please click on the following link to create a new password:</h3>
    
        <h3 style='text-align:center;background:white'><span lang=EN-CA
        style='font-size:11.0pt;font-family:"Helvetica","sans-serif"'>
        <a href="@link">Reset Password</a></span></h3>
    
        <h3 style='text-align:center;background:white'><span lang=EN-CA
        style='font-size:11.0pt;font-family:"Segoe UI","sans-serif";color:#4D4D4D'>LIKE US ON </span>
        <span> <a href="https://www.facebook.com/ephapparel" target="_blank"><img alt="" width=25 height=22
        src="http://ephoms-prod.azurewebsites.net/images/eph_graphics/fb_icon.png" ></a></span>
        &nbsp;<span lang=EN-CA style='font-size:11.0pt;font-family:"Segoe UI","sans-serif";
        color:#4D4D4D'>&nbsp;FOLLOW US ON </span><span lang=EN-CA></span>
        <span><a href="https://www.twitter.com/ephApparel" target="_blank"><img alt="" width=25 height=23
        src="http://ephoms-prod.azurewebsites.net/images/eph_graphics/twitter_icon.png"></a></span></h3>
        <br>
        <img alt="" src="http://ephoms-prod.azurewebsites.net/images/eph_graphics/eph_logo.png">
        </div>
    
    </body>
    

  3. Finally, back to your code, try the following:

      private string ResetPassword(Customer oCustomer, string oToken)
      {    
          string template = HostingEnvironment.MapPath("/bin/EmailTemplates/_EmailResetPassword.cshtml");
          ResetPassword password = new ResetPassword
          {
              FirstName = oCustomer.FirstName, 
              UserName = oCustomer.Email, 
              token = oToken, 
              URLpath = GetConfigSettingById(3)
          };
          var templateService = new TemplateService(); 
          return templateService.Parse(File.ReadAllText(template), password, null, "Reset");
      }
    

Попробуйте этот или сторонний API и сообщите нам о результатах! (Если вам нужна помощь с Postal, задайте новый вопрос, и я буду рад внести свой вклад)

person Dylan Corriveau    schedule 27.06.2014