В своём менеджере я использую очень невыгодную загрузку списка сообщений.
Сначала я получаю список сообщений на серверной части, а приёмник на стороне клиента через ajax запрос перехватывает и из этих данных делает переменную типа string, которую потом я использую как innerHtml и вставляю его в лист сообщений.
PHP:
public function get_messages($id){
$chat = $this->db->find_one('users_chats', ['id' => $id]);
$messages = $this->db->find('users_messages', ['cid' => $id]);
if($chat != null){
$user_ids = json_decode($chat['users_ids'], false);
if(array_search($this->AM->user['id'], $user_ids) !== false) {
if ($chat['type'] == 'private') {
$chat['title'] = json_decode($chat['title'], true)[$this->AM->user['id']];
}
for ($i = 0; $i < count($messages); $i++) {
$viewed = json_decode($messages[$i]['viewed'], false);
if (array_search($this->AM->user['id'], $viewed) === false) {
$viewed[] = $this->AM->user['id'];
$views = json_encode($viewed);
$this->db->update('users_messages', ['viewed' => $views], ['id' => $messages[$i]['id']]);
}
$messages[$i]['user'] = $this->db->find_one('users_accounts', ['id' => $messages[$i]['uid']], ['id', 'first_name', 'last_name', 'photo']);
}
echo json_encode(['type' => 'success', 'messages' => $messages, 'chat' => $chat]);
}else{
echo json_encode(['type' => 'error']);
}
}else{
echo json_encode(['type' => 'error']);
}
}
JS:
function open_chat(id) {
if($.cid != id || $.cid == null) {
$.cid = id;
$.ajax({
url: '/get-messages/',
method: 'POST',
data: {cid: id},
success: function (result) {
result = JSON.parse(result);
if (result['type'] == 'success') {
$('#content').children('.title').children('span').text(result['chat']['title']);
$('#content').show();
$('#no-content').hide();
var messages_list = result['messages'];
var messages_html_list = '';
[].forEach.call(messages_list, function (message) {
messages_html_list = messages_html_list +
'<div class="message"><div class="autor link_page" url="/u' + message['user']['id'] + '/records/"><div class="author-photo"><img src="' + message['user']['photo'] + '" alt=""></div>' +
'<div class="fullname">' + message['user']['first_name'] + ' ' + message['user']['last_name'] + '</div><div class="time" time="' + message['time'] + '"></div></div>' +
'<div class="text">' + message['message'] + '</div></div>';
});
$('#messages_list').html(messages_html_list);
$('#messages_list').scrollTop($('#messages_list').prop('scrollHeight'));
if (messages_list.length != 0) {
$.last_message_id = messages_list[messages_list.length - 1]['id'];
}
start_page();
set_checking();
}
}
});
}
}
Функцию openchat вызываю при клике на элемент "чата".
<div class="chat element" onclick="open_chat(<?=$chat['id']?>)">
<div class="photo">
<img src="<?=$chat['photo']?>" alt="">
</div>
<div class="main">
<div class="name"><?=$chat['title']?></div>
<div class="last-message">
</div>
</div>
</div>
Но, по производительности это ужасно стучит. И, мне бы хотелось узнать, может вы сможете дать совет?
Немного переформатировал код для более быстрой работы js. но все же есть вопросы. о них ниже.
function open_chat(id) {
if ($.cid != id || $.cid == null) {
$.cid = id;
let $content = $('#content');
let $no_content = $('#no-content');
let $messages_list = $('#messages_list');
let content_title = $content$content.children('.title').children('span');
$.ajax({
url: '/get-messages/',
method: 'POST',
data: { cid: id },
success: function(result) {
result = JSON.parse(result);
if (result['type'] == 'success') {
$content_title.text(result['chat']['title']);
$content.show();
$no_content.hide();
var messages_list = result['messages'];
var messages_html_list = '';
[].forEach.call(messages_list, function(message) {
messages_html_list = `${messages_html_list}
<div class="message"><div class="autor link_page" url="/u${message['user']['id']}/records/"><div class="author-photo"><img src="${$message['user']['photo']}" alt=""></div>
<div class="fullname">${message['user']['first_name']} ${message['user']['last_name']}</div><div class="time" time="${message['time']}"></div></div> '<div class="text">${message['message'] }</div></div>`;
});
$messages_list.html(messages_html_list);
$messages_list.scrollTop($messages_list.prop('scrollHeight'));
if (messages_list.length != 0) {
$.last_message_id = messages_list[messages_list.length - 1]['id'];
}
start_page();
set_checking();
}
}
});
}
}
Для поиска просадки я бы посоветовал использовать инструменты разработчика и посмотреть как быстро после вызова функции приходит ответ..если долго -смотрим сервер, если быстро (~100 мс или меньше) . то смотрим дальше js. по js быстро найти можно используя console.time('test');
-- ставим в начале измерения, console.timeEnd('test');
-- соответственно в конце.и таким путем находим где конкретно просадка в js. Да, и формирование кода из строки намного медленнее чем если бы использовал создание элементов на чистом js. например
let div = document.createElement('div');
let innerDiv = document.createElement('div');
innerDiv.textContent = 'text example';
div.append(innerDiv);
document.boady.append(div);
чем меньше перерисовок и изменений после вставки в dom, тем быстрее
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть форма (тест), содержащая несколько вопросов, на которые надо давать ответы путем выбора от 0 до 5 балловСделано радиокнопками:
После всех элементов в html файле располагаю скриптВ объекте page есть объект obj со значением $("