instantsoft / icms2

Self-hosted Site Management System
https://instantcms.ru
GNU General Public License v2.0
294 stars 120 forks source link

Подключение js. Пожалуйста, верните, как было! #1389

Closed asnenne closed 2 years ago

asnenne commented 2 years ago

Используемая версия InstantCMS: 2

Предлагаю вернуть подключение js-файлов в head. От того, что это перенесли в подвал пользы никакой, один сплошной вред. Ну выиграем мы 0.00003с в скорости загрузки, это ни о чем. Но при медленном интернете половина сайта работает некорректно. Возьмем, например, уведомления. Страница вроде уже загрузилась, кнопка с уведомлениями показывает, что есть уведомление. Нажимаем и получаем ошибку 404, потому что уведомления загружаются только в модальном окне, но скрипты в подвале еще не загрузились до конца.

Или второй пример. В одном виджете использую библиотеку для уменьшения шрифта, чтобы текст полностью вписывался в блок. Так вот эта доля секунды, на которую дольше загружаются скрипты в подвале, делают сайт дерганым.

Я видел, как на форуме кто-то сильно требовал перенести скрипты в подвал. Ок, мы выполнили требование гуглпейдспида в ущерб себе. Теперь можно делать только деревянные сайты, где javascript работает потом, когда уже не надо.

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

Спасибо.

Panda58dev commented 2 years ago

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

$(document).ready(function() {
    //code...
}

так пишут многие, но не все. А во-вторых на сколько мне известно, добавление скриптов в head силами CMS всё таки доступно

$template->addTplJSName("fileName");
fuzegit commented 2 years ago

Но при медленном интернете половина сайта работает некорректно.

А при чём тут медленный интернет? Все биндинги срабатывают при document ready. Что вверху js, что внизу, роли не играет.

В одном виджете использую библиотеку для уменьшения шрифта, чтобы текст полностью вписывался в блок. Так вот эта доля секунды, на которую дольше загружаются скрипты в подвале, делают сайт дерганым.

Вероятно, вы делаете что-то не так при работе с этой библиотекой. Чтобы отработала ваша библиотека нужно

  1. Дождаться, пока страница загрузится в браузер полностью ($(document).ready(function() {})), мы ведь весь текст хотим обойти ею;
  2. Запустить ваш скрипт.

В общем чувствую порыв души у вас был как раз связанный с этой либой)

где javascript работает потом, когда уже не надо.

Мне кажется вы не понимаете механизм работы javascript.

asnenne commented 2 years ago

Я понимаю, как это работает.

Первый пример. Уведомления. Внизу страница библиотека jquery, после нее ajax.modal. Кнопка с уведомлениями уже есть, а скрипты не загрузились. Я недавно видео записывал по одному компоненту. И там как раз и вылезла ошибка 404 из-за этого.

asnenne commented 2 years ago

Что вверху js, что внизу, роли не играет

Я у себя в шаблоне перенес всё вверх и дергания прекратились. И модальные окна стали загружаться, как надо. Вы наверное думаете, что это современно так? Боюсь вас огорчить, но подключением js библиотек внизу страницы лучше не стало, а только хуже.

fuzegit commented 2 years ago

Внизу страница библиотека jquery, после нее ajax.modal. Кнопка с уведомлениями уже есть, а скрипты не загрузились.

Еще раз: биндинг кнопок происходит при document ready. Что вверху будут скрипты, что внизу, пока ВСЯ страница не отрендерится, биндинга не будет.

asnenne commented 2 years ago

Это вам так кажется. На самом деле всё не так.

И да, про "современные решения")) 0 Гугл впарил вам идею, а сам свои библиотеки подключает там, где ему надо.

asnenne commented 2 years ago

Начиная с 14:33 несколько секунд в этом видео: https://youtu.be/cZ5HO4RakBg

Здесь, правда, не уведомления, но тоже модальное окно. Именно из-за того, что аякс-модал внизу, я получил 404 ошибку. Сегодня я перенес все скрипты вверх и все ошибки пропали.

fuzegit commented 2 years ago

И модальные окна стали загружаться, как надо

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

Это вам так кажется. На самом деле всё не так.

Что мне кажется?) Я понимаю механизм работы javascript в браузере.

Гугл впарил вам идею

Мне?) Мне вообще всё равно где подключаются скрипты.

Чем вы отличаетесь от тех, кто что-то там "впарил"? Ваш тикет сплошной поток нервного текста и "впаривания". Чем вы получаете лучше?)

Написали бы просто, "добавить опцию где подключать javascript в подвале или футере", а не вот это вот всё. Опцию сделать не проблема.

Здесь, правда, не уведомления, но тоже модальное окно.

Блеск) Что вы хотите мне доказать, я только не пойму.

Именно из-за того, что аякс-модал внизу, я получил 404 ошибку. Сегодня я перенес все скрипты вверх и все ошибки пропали.

Еще раз. Остановитесь. Прочитайте как работает javascript в браузере. Вы перенесли вверх и теперь просто не успеваете поймать ошибку, потому что скрипты грузятся ДО того, как вы визуально увидели страницу. Сейчас же вы сначала видите страницу, поэтому да, некое время проходит, пока всё догрузится и забиндятся эелементы.

asnenne commented 2 years ago

Ваш тикет сплошной поток нервного текста и "впаривания"

Не правда, я вообще не нервный. Я предложил в самом нечале добавить опцию. Отклонено, потому что "я не понимаю". Ну ок. 0

asnenne commented 2 years ago

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

Это по Вашему не требует решения?)) Если мы видим кнопку, по которой открывается модальное окно, раньше, чем загрузился скрипт, который это делает, то, очевидно, мы не сможем открыть модальное окно, а вместо этого получим ошибку.

Простите, я не программист, может быть некоторые вещи не теми словами называю. Хорошо, что Вы поняли, в чем проблема))

asnenne commented 2 years ago

Вероятно, вы делаете что-то не так при работе с этой библиотекой. Чтобы отработала ваша библиотека нужно В общем чувствую порыв души у вас был как раз связанный с этой либой)

Библиотека отрабатывает нормально. Но с задержкой. Визуально уже всё есть, а библиотека еще не загрузилась. Этой доли секунды хватает, чтобы увидеть дергание. А "порыв души" больше из-за всех нюансов, особенно из-за модалок. Оно знаете как, там мелочь, там нюанс, а общая картина в итоге так себе.

Panda58dev commented 2 years ago

"особенно из-за модалок"

https://user-images.githubusercontent.com/71038326/148652437-216386ac-4ea0-4fb5-b61a-59562833f5fd.MP4

В принципе - да, задержка небольшая есть (на видео это открытие элемента списка). Но (имхо) она на столько ничтожна что обращать на неё внимание не стоит :)

Но раскрытие того блока - это писал я сам, и знаю как оно работает, и перенос скрипта в <head> может помочь, но вот на счёт модалок - это вряд ли. Все модалки в modern делаются через bootstrap, а он в свою очередь написан на JQ, и как уже писал Fuze - скорее всего такие скрипты начинают свою работу только после загрузки страницы.

fuzegit commented 2 years ago

Это по Вашему не требует решения?))

Нет, не требует. И вы упорно продолжаете спорить на тему

Если мы видим кнопку, по которой открывается модальное окно, раньше, чем загрузился скрипт, который это делает

https://github.com/instantsoft/icms2/blob/master/templates/modern/js/core.js#L3 https://github.com/instantsoft/icms2/blob/master/templates/modern/js/modal.js#L9

Вы ВСЕГДА будете видеть кнопку раньше чем загрузится скрипт. Вопрос лишь в том, сколько времени она будет незабинденной. Те же модалки начинают биндится ТОЛЬКО при document ready, откройте уже исходный код этого файла. Я уже столько раз это написал, что устал.

А все эти предложения "я знаю как правильно и лучше" в настойчивой форме конечно хороши и своё дело делают, однако как показывает практика, постоянно потом переделываю. Так было, например, со 100% готового кода, который предлагал человек, который вас научил.

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

Не правда, я вообще не нервный. Я предложил в самом нечале добавить опцию. Отклонено, потому что "я не понимаю". Ну ок.

Ну да, ни разу :) Прочитайте ваш заголовок, текст и в конце "ну или опцию". Только опция и никак иначе.

asnenne commented 2 years ago

Все модалки в modern делаются через bootstrap, а он в свою очередь написан на JQ, и как уже писал Fuze - скорее всего такие скрипты начинают свою работу только после загрузки страницы.

Все модалки делаются с помощью библиотеки modal.js, бутстрап тут вообще ни при чем. html-элемент уже загрузился, в нем класс ajax-modal, который вызывает модальное окно. А скрипт еще на загрузился. Вы нажмете на кнопку и получите ошибку 404, а вместо модального окна откроется обычная страница с адресом из ссылки.

Panda58dev commented 2 years ago

с помощью библиотеки modal.js

Ну может быть, особо не вникал.

Вы нажмете на кнопку и получите ошибку 404

Сайт (или устройство пользователя) должен сильно тупить, что бы у юзера хватило ловкости "успеть" тыкнуть в эту кнопку.

asnenne commented 2 years ago

что бы у юзера хватило ловкости "успеть" тыкнуть в эту кнопку

Я успеваю, особо не спеша. У нас когда-то года полтора назад начали глушить интернет, так до сих пор через раз работает. Если он стабильный, так конечно разницы не увидите. Но он бывает медленным. Ну или хотя бы чуть медленнее, ем хотелось бы.

А все эти предложения "я знаю как правильно и лучше" в настойчивой форме

Есть с чем сравнить)) Раньше ведь всё работало нормально в дефолтном шаблоне)) Смотрите, у нас загружается страница сверху вниз. Загрузилась шапка, потом загрузилось тело, только потом скрипты. Чем больше скриптов, тем дольше они загружаются. Они же все внизу. Опять же повторю, при быстром интернете это не видно, но при небольших тормозах заметно. Если же мы сначала загрузим скрипты, а потом уже контент, то сократим время от начала показа кнопки до полной загрузки на время загрузки скриптов. И тогда уже даже при тормознутом интернете или медленном хостинге не будет проблем.

fuzegit commented 2 years ago

Если же мы сначала загрузим скрипты, а потом уже контент, то сократим время от начала показа кнопки до полной загрузки на время загрузки скриптов.

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

Короче, опцию подкину, это 2 минуты. По умолчанию она будет выключена.

asnenne commented 2 years ago

Спасибо!

asnenne commented 2 years ago

Нет, это не всё))

Переноса библиотек вверх опционально мало. Есть много разных полей, в том числе системных, виджетов и т.д., где скрипт вставляется в тело страницы. Но после переноса jquery вниз, их стали оборачивать в ob_start ... ob_get_clean, чтобы перенести туда же, после подключения jquery.

Так вот, если библиотеки будут подключаться вверху, а эти скрипты все равно переноситься вниз, то тормоза останутся, хоть их станет и меньше. А если вдруг эти скрипты тоже вверх попадут (это вряд ли), то вообще ничего работать не будет.

Тут двумя минутами не обойтись)) Надо писать какой-то механизм буферизации, только чтобы работало всё так, что если библиотеки вверху, то выводим скрипт на странице в том месте, где он написан, а если внизу, то отправляем скрипт тоже вниз. Для совместимости))

asnenne commented 2 years ago

Если бы я знал, как это сделать, то предложил бы, конечно, готовый код)) Но я не знаю.

Panda58dev commented 2 years ago

Если бы я знал, как это сделать...

Хоть бы алгоритм маленький накидали :) То, что Вы предлагаете тоже будет сайт грузить жёстко, особенно если на сайте куча данных. В итоге загрузка скриптов будет ещё чуть дольше. По идеи, если брать формирование страниц - в этом может сильно помочь (теоретически) php jit, но он есть только в восьмёрке, а php 8 использовать как-то стрёмновато :)

всё имхо

asnenne commented 2 years ago

Ну, какой алгоритм. Сейчас так

<?php ob_start(); ?>
<script>...</script>
<?php $this->addBottom(ob_get_clean()); ?>

Вместо ob_start какой-то метод из какого-нибудь хелпера, типа icms_script - icms_script_end.

Оборачиваем этим. А в самом методе проверяем. Если в настройках включено подключение библиотек вверху, то игнорируем и возвращаем на место, где написано, а если внизу, то переносим вниз (addBottom).

Ну вот, что в голову пришло)) Может еще как-то.

asnenne commented 2 years ago

Или даже не так.

<?php ob_start(); ?>
<script>...</script>
<?php $this->addBottom(ob_get_clean()); ?>

Вместо addBottom какой-нибудь addScript. И в зависимости от того, где библиотеки, скрипт остается либо на месте, либо отправляется вниз.

asnenne commented 2 years ago

И будет нагрузка не больше, чем сейчас.

Panda58dev commented 2 years ago

Скорее тогда просто addHead :)

asnenne commented 2 years ago

addHead перенесет в шапку. Но не все скрипты будут так работать. Надо новый метод писать специально для таких вот скриптов.

asnenne commented 2 years ago

Например, вот файл шаблона поля listmultiple

<?php if ($field->title) { ?><label for="<?php echo $field->id; ?>"><?php echo $field->title; ?></label><?php } ?>

<div class="input_checkbox_list" id="<?php echo $field->id; ?>">
    <?php foreach ($field->data['items'] as $v => $title){ ?>
        <?php $checked = in_array($v, $value, true); $ch_id = $field->id.$v; ?>
        <div class="custom-control custom-checkbox<?php if($field->is_vertical){ ?> mb-1<?php } else { ?> custom-control-inline<?php } ?>">
            <input name="<?php echo $field->element_name; ?>[]" value="<?php html($v); ?>" type="checkbox" class="custom-control-input" id="<?php echo $ch_id; ?>"<?php if($checked) { ?>checked<?php } ?>>
            <label class="custom-control-label" for="<?php echo $ch_id; ?>">
                <?php html($title); ?>
            </label>
        </div>
    <?php } ?>
</div>

<?php if($field->getProperty('show_all')){ ob_start(); ?>
<script>
    $(function() {
        $('#<?php echo $field->id; ?> input').on('click', function (){
            var v = $(this).val();
            var p = $(this).closest('.input_checkbox_list');
            if(v==0){
                $('input', p).not('input[value="0"]').prop('checked', false);
            } else {
                $('input[value="0"]', p).prop('checked', false);
            }
        });
    });
</script>
<?php $this->addBottom(ob_get_clean()); } ?>

Да много где.

Panda58dev commented 2 years ago

Ну, можно переделать - например, вместо использования вывода буфером, юзать (как я писал выше) такой код: $template->addTplJSName("fileName");, для этого нужно просто в templates/папку шаблона/js/ кинуть нужный скрипт и такой скрипт будет загружаться в head

fuzegit commented 2 years ago

Только скрипты вверх. Механизм буферизации естественно переделывать никто не будет.

то выводим скрипт на странице в том месте, где он написан

Так не оборачивайте в ob_*

Panda58dev commented 2 years ago

Механизм буферизации

Так они же в пыхе дефолтные, разве нет?

fuzegit commented 2 years ago

Так они же в пыхе дефолтные, разве нет?

имелось в виду

<?php ob_start(); ?>
<script>...</script>
<?php $this->addBottom(ob_get_clean()); ?>
asnenne commented 2 years ago

Так не оборачивайте в ob_*

Предложение было для совместимости)) Если, например, я в дополнении не оберну в этот ob_* какой-нибудь скрипт, то на том сайте, где библиотеки внизу, дополнение работать не будет.

Механизм буферизации естественно переделывать никто не будет.

Я там дальше другой вариант предложил)) А может и нет, еще не разобрался)) 0

И те компоненты-виджеты-поля, которые не обновились, например, вовремя, все равно продолжат работать.

fuzegit commented 2 years ago

Всё, что могу предложить, это опция с тем, где скрипты. Если одного этого мало, то увы, ничем больше не могу помочь.

asnenne commented 2 years ago

Ну, на безрыбье и рак - рыба)) Пусть будет хотя бы опция. И то полегче станет. А там может через версий 8 уговорю Вас и второе добавить))

fuzegit commented 2 years ago

https://github.com/instantsoft/icms2/commit/df3d690dd14d3e599f4b05644f1a83bcb1b81c8d