HTML-таблица занимает слишком много времени, чтобы динамически создавать, когда строки больше 4k-8k [duplicate]

Что вы можете сделать по этому поводу?

Здесь есть много хороших ответов, объясняющих, что такое пустая ссылка и как ее отладить. Но очень мало о том, как предотвратить проблему или, по крайней мере, сделать ее легче поймать.

Проверить аргументы

Например, методы могут проверять разные аргументы, чтобы увидеть, null и выбросить ArgumentNullException, исключение, явно созданное для этой конкретной цели.

Конструктор для ArgumentNullException даже принимает имя параметра и сообщение как аргументы, чтобы вы могли точно сказать разработчику, что проблема.

public void DoSomething(MyObject obj) {
    if(obj == null) 
    {
        throw new ArgumentNullException("obj", "Need a reference to obj.");
    }
}

Использовать инструменты

Есть также несколько библиотек, которые могут помочь. Например, «Resharper» может предоставить вам предупреждения во время написания кода, особенно если вы используете их атрибут: NotNullAttribute

В разделе «Контракты кода Microsoft» вы используете синтаксис, например Contract.Requires(obj != null), который дает вам проверку выполнения и компиляцию: Представление кодовых контрактов .

Существует также «PostSharp», который позволит вам просто использовать такие атрибуты:

public void DoSometing([NotNull] obj)

Сделав это и сделав PostSharp частью вашего процесса сборки, obj будет проверяться на нуль во время выполнения. См. Ошибка проверки PostSharp

Решение для простого кода

Или вы всегда можете использовать свой собственный подход, используя простой старый код. Например, вот структура, которую вы можете использовать, чтобы поймать нулевые ссылки. Он моделируется после той же концепции, что и Nullable:

[System.Diagnostics.DebuggerNonUserCode]
public struct NotNull where T: class
{
    private T _value;

    public T Value
    {
        get
        {
            if (_value == null)
            {
                throw new Exception("null value not allowed");
            }

            return _value;
        }
        set
        {
            if (value == null)
            {
                throw new Exception("null value not allowed.");
            }

            _value = value;
        }
    }

    public static implicit operator T(NotNull notNullValue)
    {
        return notNullValue.Value;
    }

    public static implicit operator NotNull(T value)
    {
        return new NotNull { Value = value };
    }
}

. Вы использовали бы очень похоже на то, как вы бы использовали Nullable, за исключением того, что цель заключалась в том, чтобы сделать абсолютно противоположное - не разрешать null. Вот несколько примеров:

NotNull person = null; // throws exception
NotNull person = new Person(); // OK
NotNull person = GetPerson(); // throws exception if GetPerson() returns null

NotNull неявно отбрасывается в и из T, поэтому вы можете использовать его в любом месте, где это необходимо. Например, вы можете передать объект Person методу, который принимает значение NotNull:

Person person = new Person { Name = "John" };
WriteName(person);

public static void WriteName(NotNull person)
{
    Console.WriteLine(person.Value.Name);
}

Как вы можете видеть выше, как с помощью nullable, вы получите доступ к базовому значению через Value имущество. Кроме того, вы можете использовать явный или неявный листинг, вы можете увидеть пример с возвращаемым значением ниже:

Person person = GetPerson();

public static NotNull GetPerson()
{
    return new Person { Name = "John" };
}

Или вы даже можете использовать его, когда метод просто возвращает T (в этом случае Person), выполнив бросок. Например, следующий код будет похож на код выше:

Person person = (NotNull)GetPerson();

public static Person GetPerson()
{
    return new Person { Name = "John" };
}

Объединить с Extension

Объединить NotNull с методом расширения, и вы можете охватить еще больше ситуаций. Вот пример того, как может выглядеть метод расширения:

[System.Diagnostics.DebuggerNonUserCode]
public static class NotNullExtension
{
    public static T NotNull(this T @this) where T: class
    {
        if (@this == null)
        {
            throw new Exception("null value not allowed");
        }

        return @this;
    }
}

И вот пример того, как он может быть использован:

var person = GetPerson().NotNull();

GitHub

Для вашей справки я сделал код выше, доступный на GitHub, вы можете найти его по адресу:

https://github.com/luisperezphd/NotNull

Функция родственного языка

В C # 6.0 был введен «оператор с нулевым условием», который немного помогает в этом. С помощью этой функции вы можете ссылаться на вложенные объекты, и если какой-либо из них null, все выражение возвращает null.

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

var address = country?.State?.County?.City;

Представьте, что country является объектом типа Country, который имеет свойство, называемое State и т. Д. Если country, State, County или City - null, то address will be null . Therefore you only have to check whether адрес is null`.

Это отличная функция, но она дает вам меньше информации. Это не делает очевидным, какой из 4 является нулевым.

Встроенный как Nullable?

C # имеет красивую стенографию для Nullable, вы можете сделать что-то нулевое помещая знак вопроса после такого типа int?.

Было бы неплохо, если бы у C # было что-то вроде структуры NotNull выше и имела аналогичную стенографию, может быть, восклицательный знак (!), чтобы вы могли написать что-то вроде: public void WriteName(Person! person).

19
задан fuel37 1 February 2011 в 16:16
поделиться

7 ответов

joinHi,

Реализация - проблема, но есть также проблема с конкатенацией так много строк внутри цикла, особенно когда строка становится очень большой. Вероятно, лучше всего поместить строки в отдельные элементы массива, а затем использовать «join» для создания огромной строки одним махом. например,

var r = new Array();
var j = -1, recordId;
r[++j] =  '<table><thead><tr><th>ID</th><th>Status</th><th>Name</th><th>Actions</th><th>Origin</th></tr></thead><tbody>'; 
for (var i in data){
    var d = data[i];
    recordId = d.id;
    r[++j] = '<tr id="';
    r[++j] = recordId;
    r[++j] = '" class="';
    r[++j] = d.status;
    r[++j] = '"><td width="1%" align="center">';
    r[++j] = recordId;
    r[++j] = '</td><td width="1%" align="center"><span class="status" rel="';
    r[++j] = recordId;
    r[++j] = '"><strong>';
    r[++j] = d.status;
    r[++j] = '</strong></span></td><td width="70%"><span class="name">';
    r[++j] = d.name;
    r[++j] = '</span></td><td width="2%"><input type="button" class="failOne" rev="';
    r[++j] = recordId;
    r[++j] = '" value="F"><input type="button" class="promoteOne" rev="';
    r[++j] = recordId;
    r[++j] = '" value="P"></td><td width="1%">';
    r[++j] = d.origin;
    r[++j] = '</td></tr>';
}
r[++j] = '</tbody></table>';
$('#documentRows').html(r.join(''));

Кроме того, я бы использовал приведенный здесь метод индексирования массива, вместо того, чтобы использовать «push», поскольку для всех браузеров, кроме Google Chrome, это происходит быстрее, согласно этой статье .

18
ответ дан mean 28 August 2018 в 10:36
поделиться

Отображение того, что многие строки заставляют движок рендеринга браузера замедляться, а не движок JavaScript. К сожалению, вы ничего не можете с этим сделать.

Лучшее решение - просто не отображать столько строк одновременно, либо путем разбивки на страницы, либо виртуальной прокрутки.

4
ответ дан David Tang 28 August 2018 в 10:36
поделиться

Можно попробовать ...

Улучшить циклы

Улучшить String Concat

var tmpLst = [];

for (var i=0, il=data.length; i<il; i++) {
    var record = data[i];
    var recordId = record.id;

    tmpLst.push('<tr id="');
    tmpLst.push(recordId); 
    tmpLst.push('" class="'); 
    tmpLst.push(record.status);
    tmpLst.push('">');
    tmpLst.push('<td width="1%" align="center">');

...ect...


}
rows += tmpLst.join('');

Это может сжать дополнительный бит производительности ...

var lstReset = i * lstReset.length;
tmpLst[lstReset + 1]='<tr id="';
tmpLst[lstReset + 2]=recordId; 
tmpLst[lstReset + 3]='" class="'; 
0
ответ дан digiguru 28 August 2018 в 10:36
поделиться

Вы можете сделать несколько вещей для повышения производительности:

  1. ваша переменная строк становится все больше и больше, поэтому не храните html в одной переменной. решением может быть функция $.each() и каждая функция, которую вы добавляете в DOM. Но это незначительная корректировка.
  2. Генерация Html хороша, но вы можете попробовать создать и добавить DOM. Как $('<tr></tr>').
  3. И, наконец, это решит вашу проблему наверняка: используйте несколько вызовов ajax в первом вызове ajax, чтобы собрать, сколько данных доступно, и получить около 1000 или может быть больше данных. И используйте другие вызовы для сбора оставшихся данных. Если вы хотите, вы можете использовать синхронный вызов или асинхронные вызовы с умом.

Но старайтесь избегать сохранения значения. Размер DOM будет огромным, но он должен работать на модерирующих браузерах и забыть об IE6.

@ fuel37: Пример

function outputDocumentNew(data, doc_id) {
    //Variable DOM's
    var rowSample = $('<tr></tr>').addClass('row-class');
    var colSample = $('<td></td>').addClass('col-class');
    var spanSample = $('<span></span>').addClass('span-class');
    var inputButtonSample = $('<input type="button"/>').addClass('input-class');

    //DOM Container 
    var container = $('#documentRows');
    container.empty().append('<table></table>');

    //Static part
    var head = '<thead>\
                <tr>\
                    <th width="1%" align="center">ID</th>\
                    <th width="1%" align="center">Status</th>\
                    <th width="70%">Name</th>\
                    <th width="2%">Actions</th>\
                    <th width="1%">Origin</th>\
                </tr>\
                </thead>';
    container.append(head);

    var body = $('<tbody></tbody>');
    container.append(body);

    //Dynamic part
    $.each(data, function (index, value) {
        var _this = this;

        //DOM Manupulation
        var row = rowSample.clone();

        //Actions
        var inpFailOne = inputButtonSample.clone().val('F').attr('rev', _this.id).addClass('failOne').click(function (e) {
            //do something when click the button.
        });
        var inpPromoteOne = inputButtonSample.clone().val('P').attr('rev', _this.id).addClass('promoteOne').click(function (e) {
            //do something when click the button.
        });

        row
        .append(colSample.clone().append(_this.id))
        .append(colSample.clone().append(spanSample.colne().addClass('status').append(_this.status)))
        .append(colSample.clone().append(spanSample.colne().addClass('name').append(_this.name)))
        .append(colSample.clone().append(inpFailOne).append(inpPromoteOne))
        .append(colSample.clone().append(_this.origin));

        body.append(row);
    });
}

в этом процессе вам необходимо создать & amp; поддерживать id или классы для манипуляций. У вас есть элемент управления для привязки событий и управления ими.

1
ответ дан Imrul 28 August 2018 в 10:36
поделиться

Ответ на получение форматирования

Что произойдет, если вы сделаете

for(var i in data){
    var record = data[i];
    var recordId = record.id;
    rows += '<tr id="' + recordId + '" class="' + record.status + '">';
    rows += '<td width="1%" align="center">' + recordId + '</td>';
    rows += '<td width="1%" align="center"><span class="status" rel="' + recordId + '"><strong>' + data[i].status + '</strong></span></td>';
    rows += '<td width="70%"><span class="name">' + record.name + '</span></td>';
    rows += '<td width="2%">';
    rows += '<input type="button" class="failOne" rev="' + recordId + '" value="F">';
    rows += '<input type="button" class="promoteOne" rev="' + recordId + '" value="P">';
    rows += '</td>';
    rows += '<td width="1%">' + record.origin + '</td>';
    rows += '</tr>';
}//end for
0
ответ дан mplungjan 28 August 2018 в 10:36
поделиться

Способ построения вашей строки приведет к огромному объему сбора мусора.

Поскольку строка становится длиннее и длиннее, движок javascript должен продолжать выделять большие буферы и отбрасывать старые. В конце концов, он не сможет выделить достаточную память, не перерабатывая остатки всех старых строк.

Эта проблема ухудшается по мере увеличения длины строки.

Вместо этого попробуйте добавить новые элементы в DOM по одному с использованием jQuery-манипуляционного API

Также рассмотрите только визуализацию того, что видно, и выполните собственную прокрутку.

2
ответ дан Noel Walters 28 August 2018 в 10:36
поделиться

В других предложениях (я недостаточно авторитет, чтобы комментировать, извините!), вы можете попробовать плагин TableSorter для обработки только отображения полезного количества данных за раз.

Я не знаю, как это работает при очень большом количестве строк, но их пример данных составляет 1000 строк или около того.

Это не помогло бы с JS-производительностью, но сохранит нагрузку с браузера.

0
ответ дан peteorpeter 28 August 2018 в 10:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: