Проблема производительности JsRender/JsViews в Edge и IE

const N_COLS = 20; // use it to modify the number of columns
const N_ROWS = 20; // use it to modify the number of rows

const data = {
  name: "Sample",
  columns: generateColumns(N_COLS),
  rows: generateRows(N_ROWS),
}

function generateColumns(n){
  let columns = [];
  for(let i = 0; i < n; i ++){
    columns.push({ index: i, name : "Column " + i})
  }
  return columns;
}

function generateRows(n){
  let rows = [];
  for(let i = 0; i < n; i ++){
    rows.push({ index: i, fields: generateFields(N_COLS)});
  }
  return rows;
}

function generateFields(n){
    let fields = [];
    for(let i = 0; i < n; i ++){
        fields.push({index: i, text: "Field " + i});
    }
    return fields;
}

$(document).ready(function(){
    console.time('Compile');
    var tmpl = $.templates("#mainTemplate");
    console.timeEnd('Compile');

    console.time('Render');
    tmpl.link("#container", data);
    console.timeEnd('Render');
});
<!DOCTYPE html>
<html>
    <head>
        <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.min.js"></script>
    </head>
    <body>
        <script id="mainTemplate" type="text/x-jsrender">
            <h1>{{:name}}</h1>
            {{include tmpl="#contentTemplate"/}}
        </script>

        <script id="contentTemplate" type="text/x-jsrender">
            <table>
                <thead>
                    {{for columns}}
                        {{include tmpl="#columnTemplate"/}}
                    {{/for}}
                </thead>

                <tbody>
                    {{for rows}}
                        {{include tmpl="#rowTemplate"/}}
                    {{/for}}
                </tbody>
            </table>
                
        </script>
        
        <!-- In this example, using those templates with an include tag doesn't make sense, but that's because it's a simplified version of what I'm working with -->
        <!-- In my scenario having those templates separated is a must have :( -->
        <script id="columnTemplate" type="text/x-jsrender">
            <th>{{:name}}</th>
        </script>
        
        <script id="rowTemplate" type="text/x-jsrender">
            <tr>
                {{for fields}}
                    {{include tmpl="#fieldTemplate"/}}
                {{/for}}
            </tr>
        </script>

        <script id="fieldTemplate" type="text/x-jsrender">
            <td>
                {{:text}}
            </td>
        </script>

        <div id="container"></div>
    </body>
</html>

Я столкнулся с проблемой производительности с JsViews в Edge и IE. У меня есть действительно большой шаблон, который содержит так много тегов, а также множество ссылок на данные. В Chrome и Firefox с производительностью все в порядке, рендеринг занимает менее 1 секунды, что хорошо для моих нужд, но в Edge и IE это занимает почти 5 секунд:(

Этот шаблон может использоваться столько раз, сколько мы хотим на данной странице, поэтому здесь проблема с производительностью возрастает.

Я попытался использовать JsRender вместо JsView, адаптируя свои шаблоны и объекты без связей данных, потому что заметил, что в моем сценарии их использование так сильно влияет на производительность, что в Chrome и Firefox я достиг 500 мс при рендеринге, а также в IE и Край.. 2 секунды, что все еще так много для моих нужд.

Я уже пытался упростить шаблоны, которые я использую, но я достиг нижней черты..

У меня есть много идей, чтобы попытаться решить эту проблему, и вот откуда мои вопросы:

  • Есть ли (или это будет в новых версиях JsViews/JsRender) способ компилирования шаблонов в веб-приложении? Я знаю, что в веб-работнике мы не можем использовать JQuery, получать доступ к DOM или использовать объекты с пользовательскими прототипами, но кто знает... Даже если время компиляции будет таким же, по крайней мере, я смогу компилировать шаблоны в paralel.

  • Есть ли несколько волшебных советов по улучшению производительности JsViews/JsRender в IE и Edge? (выбрасывать IE и Edge было бы неплохо, но, к сожалению, это не вариант:(xD)

PS: боюсь, я не могу опубликовать какой-либо код, потому что я говорю о проекте для предприятия, на которое я работаю.

1 ответ

IE и Edge намного медленнее, чем Chrome - хотя, насколько это будет зависеть от деталей кода и сценария. Например, IE намного медленнее, чем Chrome, в некоторых сценариях рендеринга таблиц HTML. Вы можете обнаружить, что, избегая разметки таблиц и вместо использования CSS для эквивалентных разметок сетки, вы получаете значительное улучшение - и это может быть более заметным в IE и Edge....

Если вы посмотрите на этот http://borismoore.github.io/jsrender/test/perf-compare.html в разных браузерах, вы увидите, что IE может работать намного медленнее, причем не только для JsRender, но и для других компонентов или шаблонные движки.

Помимо отказа от таблиц HTML (если это возможно), вы можете рассмотреть возможность замены:

{{for columns}}
  {{include tmpl="#columnTemplate"/}}
{{/for}}

от

{{for columns tmpl="#columnTemplate"/}}

если это возможно для вас.

Кроме того, небольшое улучшение может быть связано с:

{{... tmpl=~columnTemplate/}}

и предоставление скомпилированных шаблонов в качестве помощников, как в

var tmpls = {
    columnTemplate: $.templates("#columnTemplate"),
    ...
};

tmpl.link("#container", data, tmpls);

Кроме того, если вы вообще не используете связывание данных JsViews (я заметил, что все ваши теги {{...}}не {^{...}}) тогда вы можете сделать tmpl.render (...) и затем вставить HTML в DOM за один раз...

Другие вопросы по тегам