Вопрос: Как правильнее парсить результаты ajax запроса?

Лучший ответ: я делаю так. все состоит из блоков, где каждый блок это какое-то хтмл, к которому прилагается свой джаваскрипт, который на этот блок лично навешивает всякие обработчики. есть два случая: загрузка страницы целиком (то есть всех блоков со всеми своими джаваскриптами) и перезагрузка отдельных блоков в фоновом режиме (аджаксом так называемым). в первом случае собственно загружается страница и по готовности отрабатывают все скрипты, которые прилагаются к блокам из которых она состоит. во втором блок загружается на страницу (вставляется в нужное место, реплейсится, аппендится или еще как) и опять же отрабатывают его скрипты (именно его а не все). если в этих скриптах есть биндинги событий, то их сначала нужно отбиндить, потому что  блок может перезагружаться сколько угодно раз и с каждым разом события будут навешиваться повторно и нажатие на кнопку будет слать не один запрос а столько сколько раз был перезагружен блок. никогда не было доверия ко всяким .on() .live() и тд. проще и надежнее заменить кусок кода на странице и заребиндить все что его касается.
дополнительное преимущество такое, что вся логика происходит на стороне пхп, а на стороне браузера только работа с домом, никаких вычислений, ну либо только такие, которые не будут теряться после перезагрузки блока или заставлять писать одно и то же 2 раза. только простые манипуляции и отработка событий которые будут сообщать серверу об изменениях. например, какая-нибудь форма отправки заказа, сколько ужаса я повидал, когда условия доставки рассчитываются на странице джаваскриптом а потом это отправляется на сервер (то есть я могу подменить стоимость в запросе) или на сервере подобный алгоритм считает все это еще раз чтоб типа проверить, в результате имеется зеркало алгоритма на другом языке и что-то менять нужно в 2 местах ломая голову. или жмем случайно ф5 и все слетает потому что о данных в полях кроме страницы никто не знал. как правильно в данном случае (имхо конечно же), допустим форма такая, 2 поля имя и телефон и один переключатель доставка/самовывоз. делаем для нее в сессии массив которых способен хранить состояние этих полей и переключателя, задаем дефолтные значения там же. при загрузке страницы с этой формой она просто выводится со значениями которые находятся в сессии. к ней прилагается джаваскрипт который ребиндит событие кейап на полях и событие клик на переключателе. по событию кейап отправляется значение поля чтоб сохранить его в сессии (в ответ ничего не происходит, здесь не нужно). по клику на переключателе так же шлется запрос который меняет в сессии его состояние и в ответ перезагружается вся форма (на основании актуальных данных в сессии) и все на ней заново ребиндится. не знаю смог ли объяснить, короче проще всего отправлять каждый пук пользователя на сервер, обработать его там, и перезагрузить нафиг всё на что он мог повлиять.
все эти килобайты и миллисекунды полная ерунда, все споры на эту тему это отстаивание своих знаний определенных технологий. как по мне если программа на пхп то вся логика в пхп и должна происходить а джс только обслуживать интерфейс и не более того

Худший ответ: Если использовать https://github.com/bem/bh и https://github.com/bem/bh-php (шаблоны там почти 1-в-1, с точностью до $ в переменных), то можно выгружать шаблоны и на фронт, и на бекенде собирать нужное.
Еще лучше использовать прослойку на nodejs чисто для сборки html для первого захода, поисковиков, людей без JS, и не думать про это в целом, а на PHP оставить всю логику и использовать как API.
Еще, чтобы уменьшить размер передаваемых данных:
а) gzip;
б) raw-json;
в) protobuf.
Если передавать только нужное и не потеряться — нужно сделать двухпроходную шаблонизацию, т.е. в 2 шага — 1) конвертируем из сырых данных в некий промежуточный view-ориентированный json, а затем из последнего собираем html с помощью шаблонов на матчерах.
Если любите экспериметировать, можете попробовать еще вот так:// Допустим, у нас есть выгруженные шаблоны на фронт
bh.match('users-list', function ... );
bh.match('user', function ... );
// etc.
// дальше мы должны получить данные с бекенда, для простоты укажем их явно
var usersFromBackend = [{name: 'Vasya', id: 5}, {id: 42, name: 'Petya'}, ...];
// как получили — собираем каким-то образом некую view-ориентированную структуру типа:
var viewOriented = {
  // здесь можно использовать и что-то более умное
  block : 'users-list',
  content : fromBackend.map(function (el) {
    return {
      block : 'user',
      // привязываем к users-list по БЭМ
      // (мало ли понадобится что-то в стилях-скриптах подтюнить)
      mix : { block : 'users-list', elem : 'item' }, 
      // выводим контент в каждый div
      content : {
        block : 'link',
        mix : { block : 'user', elem : 'link' },
        url : el.url || '/users/' + el.id,
        text : el.name
      }
    };
  })
};
// И после получаем готовый HTML еще одной операцией, который останется куда-то вставить
console.log(bh.apply(viewOriented));
При том, что шаблоны у нас одинаковые (для php с точностью до $ в переменных) для фронта и бекенда — кол-во дублируемого кода падает. Появляется возможность вставлять одинаковые блоки в разные места на странице с разными данными, структурировать CSS (самое известное из BEM, даже гугл рекомендует), и т.д.