Автозаполнение jQuery - вопрос оптимизации - PullRequest
5 голосов
/ 12 мая 2011

хотелось бы, чтобы ваши мысли об этом.

Я использую автозаполнение jQuery в приложении ASP.NET MVC для получения списка записей из базы данных - я хотел бы знать, если есть лучший способчем то, как я сейчас это делаю - следующим образом:

Вот jQuery (я вызываю метод действия 'GetRecordByName' с автозаполнением)

    $('#tb_name').autocomplete({
        source: 'Home/GetRecordByName',
        minLength: 1, delay: 0,
        select: function (event, ui) {
            // do stuff
        }
    });

В конце,Я использую Linq to Entities в методе для получения результатов из базы данных:

public JsonResult GetRecordByName(string term)
{
        var data = records
            .Where(dr => dr.Key.StartsWith(term))
            .Select(dr => new { dr, value = dr.Key })
            .Take(5);

        return Json(data, JsonRequestBehavior.AllowGet);
}

В настоящее время он работает немного медленно (~ 1-2 секунды).По сути, в БД содержатся десятки тысяч записей, и каждый раз, когда вы вводите символ в текстовое поле, приложение обращается к базе данных.Я могу установить его на 2 или 3 символа, но он не меняет скорость, и при этом я не хочу требовать такого количества символов.

У меня есть идея, как его оптимизировать: при загрузке страницы получите всевозможные результаты из БД и отправка их клиенту (через скрытый ввод или структуру данных javascript), а также автозаполнение использует эти данные на стороне клиента в качестве источника.Я уверен, что это будет молниеносно, но мне кажется странным - есть ли какие-либо недостатки в этом?

Есть ли другие способы добиться более быстрого автозаполнения?

ОБНОВЛЕНИЕ: Хорошо, очевидно, проблема заключалась в том, как я создавал свой вызов EF.Вызов EF для «записей» в конечном итоге не создавал предложение WHERE в запросе sql;он получал всю таблицу каждый раз, а затем методы linq отключали эту уже перечисленную массу данных - это происходило каждый раз, когда печаталось письмо, - вызывая замедление.Doh!Я переместил метод .Where на уровень хранилища данных, где он перечисляет после того, как где фильтрует результаты, и возвращает словарь - похоже, теперь отлично работает.Спасибо за вашу помощь!Я отметил самый полезный ответ, который помог мне разобраться в проблеме.

Что касается решения Flickr / передачи всего набора данных клиенту, я все еще чувствую, что это странно / излишне, но я уверен,это гарантировано определенными большими наборами данных.Также буду больше изучать OutputCache для других вещей.

Еще раз спасибо!

Ответы [ 4 ]

6 голосов
/ 12 мая 2011

Как и при любой оптимизации, сначала вы должны проверить, чтобы определить узкое место.В противном случае ваши усилия будут направлены не в те области.Например, используйте Firebug, чтобы увидеть, сколько времени занимает фактический запрос.Используйте секундомер в вашем MVC-действии, чтобы увидеть, сколько времени занимает фактический поиск данных (бросьте вызов ToList в конце вашего запроса, чтобы убедиться, что он оценивает in-method).

Пока мы не узнаемтам, где замедление, невозможно дать вам действительно хорошее предложение для оптимизации, но вот несколько идей, которые приходят на ум:

  • Использование SQL Server Management Studio для анализа пути выполнениязапроса, произведенного LINQ to Entities.Возможно, добавление какого-либо индекса к текстовому столбцу приведет к более быстрому возврату результатов из базы данных?
  • В Windows существует проблема с DNS, которая часто приводит к тому, что браузеры без IE очень медленно работают против сред разработки.Если это работает быстро в IE, но не в Firefox, возможно, вам просто нужно настроить файл Hosts.

При загрузке страницы получите все возможные результаты из БД и отправьте их клиенту.(через скрытый ввод или структуру данных javascript), и автозаполнение использует эти данные на стороне клиента в качестве источника.Я уверен, что это будет молниеносно, но мне это кажется странным - есть ли какие-либо недостатки в этом?

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

2 голосов
/ 12 мая 2011

1) Это действительно зависит от вашего использования и ваших данных, но я рекомендую использовать [OutputCache]. Вы можете избежать выполнения запроса к базе данных каждый раз, когда любой пользователь вызывает одно и то же действие контроллера. Для получения более подробной информации см. . Это будет только для каждого пользователя, если вы используете кеширование на уровне действий контроллера, оно будет кешировать одно для всех пользователей.

2) посмотрите на ответ на этот вопрос: Как улучшить производительность автозаполнения Jquery

"This widget downloads a list of all of your contacts, in JavaScript, in under 200ms
(this is true even for members with 10,000+ contacts). In order to get this level of 
performance, we had to completely rethink how we send data from the server to the client."

3) Я видел людей, использующих Redis . Это требует некоторой настройки, но это эффективно.

Redis autocomplete

эффективное автозаполнение на стороне сервера

1 голос
/ 12 мая 2011

То, как вы упоминаете, не является плохой идеей - но, как упомянул StriplingWarrior, это может повлиять на загрузку вашей страницы.Обходной путь - сделать асинхронный ajax-вызов при загрузке страницы и в случае успешного обратного вызова связать данные, возвращаемые автозаполнением.

Это означает, что автозаполнение не будет работать до тех пор, пока результаты не будут возвращены, но чтошансы, что использование перейдет в текстовое поле и наберет <2/3 секунды? </p>

0 голосов
/ 12 мая 2011

Я не совсем уверен в вашей настройке, но вы могли бы воспользоваться одним из способов оптимизации: использовать redis для хранения всех ваших параметров поиска в виде пары ключ / значение.Просто настройте задачу так, чтобы она постоянно обновлялась.

...