jQuery автозаполнение-вопрос оптимизации


Хотелось бы, чтобы вы подумали об этом.

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

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

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

На задней стороне, я использую Linq к сущностям в методе для получения результатов от база данных:

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 символа, но это не изменит скорость, и я не хочу, чтобы требовалось так много символов.

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

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

Обновление: Хорошо, очевидно, проблема была в том, как я строил свой вызов EF. Вызов EF 'records' в конечном счете не строил предложение WHERE в SQL-запросе; он получал всю таблицу каждый раз, а затем методы linq запускали эту уже перечисленную массу данных - это происходило каждый раз, когда печаталась буква, - вызывая замедление. Дох! Я отодвинул ее .Метод Where для слоя хранилища данных, где он перечисляет после фильтра where результаты и возвращает словарь-кажется, теперь работает отлично. Спасибо за вашу помощь! Я отметил наиболее полезный ответ, который помог мне разобраться в этом вопросе.

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

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

4 5

4 ответа:

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

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

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

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

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

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 автозаполнение

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

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

Это означает, что автозаполнение не будет работать до тех пор, пока не будут возвращены результаты, но каковы шансы, что пользователь перейдет в текстовое поле и наберет текст за

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