Как настроить скрипт сайта
Перейти к содержимому

Как настроить скрипт сайта

  • автор:

Внешние скрипты, порядок исполнения

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/script-async-defer.

Если JavaScript-кода много – его выносят в отдельный файл, который подключается в HTML:

Здесь /path/to/script.js – это абсолютный путь к файлу, содержащему скрипт (из корня сайта).

Браузер сам скачает скрипт и выполнит.

Можно указать и полный URL, например:

Вы также можете использовать путь относительно текущей страницы. Например, src=»https://learn.javascript.ru/lodash.js» обозначает файл из текущей директории.

Чтобы подключить несколько скриптов, используйте несколько тегов:

На заметку:

Как правило, в HTML пишут только самые простые скрипты, а сложные выносят в отдельный файл.

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

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

Если указан атрибут src , то содержимое тега игнорируется.

В одном теге SCRIPT нельзя одновременно подключить внешний скрипт и указать код.

Вот так не сработает:

  

Нужно выбрать: либо SCRIPT идёт с src , либо содержит код. Тег выше следует разбить на два: один – с src , другой – с кодом, вот так:

   

Асинхронные скрипты: defer/async

Браузер загружает и отображает HTML постепенно. Особенно это заметно при медленном интернет-соединении: браузер не ждёт, пока страница загрузится целиком, а показывает ту часть, которую успел загрузить.

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

Например, в примере ниже – пока все кролики не будут посчитаны – нижний

не будет показан:

    

Начинаем считать:

Кролики посчитаны!

Такое поведение называют «синхронным». Как правило, оно вполне нормально, но есть важное следствие.

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

То есть, в таком документе, пока не загрузится и не выполнится big.js , содержимое будет скрыто:

  Этот текст не будет показан, пока браузер не выполнит big.js. 

И здесь вопрос – действительно ли мы этого хотим? То есть, действительно ли оставшуюся часть страницы нельзя показывать до загрузки скрипта?

Есть ситуации, когда мы не только НЕ хотим такой задержки, но она даже опасна.

Например, если мы подключаем внешний скрипт, который показывает рекламу или вставляет счётчик посещений, а затем идёт наша страница. Конечно, неправильно, что пока счётчик или реклама не подгрузятся – оставшаяся часть страницы не показывается. Счётчик посещений не должен никак задерживать отображение страницы сайта. Реклама тоже не должна тормозить сайт и нарушать его функциональность.

А что, если сервер, с которого загружается внешний скрипт, перегружен? Посетитель в этом случае может ждать очень долго!

Вот пример, с подобным скриптом (стоит искусственная задержка загрузки):

Важная информация не покажется, пока не загрузится скрипт.

. Важная информация!

Можно поставить все подобные скрипты в конец страницы – это уменьшит проблему, но не избавит от неё полностью, если скриптов несколько. Допустим, в конце страницы 3 скрипта, и первый из них тормозит – получается, другие два его будут ждать – тоже нехорошо.

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

Поэтому «расположить скрипты внизу» – не лучший выход.

Кардинально решить эту проблему помогут атрибуты async или defer :

Поддерживается всеми браузерами, кроме IE9-. Скрипт выполняется полностью асинхронно. То есть, при обнаружении браузер не останавливает обработку страницы, а спокойно работает дальше. Когда скрипт будет загружен – он выполнится.

Поддерживается всеми браузерами, включая самые старые IE. Скрипт также выполняется асинхронно, не заставляет ждать страницу, но есть два отличия от async .

Первое – браузер гарантирует, что относительный порядок скриптов с defer будет сохранён.

То есть, в таком коде (с async ) первым сработает тот скрипт, который раньше загрузится:

А в таком коде (с defer ) первым сработает всегда 1.js , а скрипт 2.js , даже если загрузился раньше, будет его ждать.

Поэтому атрибут defer используют в тех случаях, когда второй скрипт 2.js зависит от первого 1.js , к примеру – использует что-то, описанное первым скриптом.

Второе отличие – скрипт с defer сработает, когда весь HTML-документ будет обработан браузером.

Например, если документ достаточно большой…

 Много много много букв

…То скрипт async.js выполнится, как только загрузится – возможно, до того, как весь документ готов. А defer.js подождёт готовности всего документа.

Это бывает удобно, когда мы в скрипте хотим работать с документом, и должны быть уверены, что он полностью получен.

async вместе с defer

При одновременном указании async и defer в современных браузерах будет использован только async , в IE9- – только defer (не понимает async ).

Атрибуты async/defer – только для внешних скриптов

Атрибуты async/defer работают только в том случае, если назначены на внешние скрипты, т.е. имеющие src .

При попытке назначить их на обычные скрипты , они будут проигнорированы.

Тот же пример с async :

Важная информация теперь не ждёт, пока загрузится скрипт.

. Важная информация!

При запуске вы увидите, что вся страница отобразилась тут же, а alert из внешнего скрипта появится позже, когда загрузится скрипт.

Эти атрибуты давно «в ходу»

Большинство современных систем рекламы и счётчиков знают про эти атрибуты и используют их.

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

Забегая вперёд

Для продвинутого читателя, который знает, что теги можно добавлять на страницу в любой момент при помощи самого javascript, заметим, что скрипты, добавленные таким образом, ведут себя так же, как async . То есть, выполняются как только загрузятся, без сохранения относительного порядка.

Если же нужно сохранить порядок выполнения, то есть добавить несколько скриптов, которые выполнятся строго один за другим, то используется свойство script.async = false .

Выглядит это примерно так:

function addScript(src) < var script = document.createElement('script'); script.src = src; script.async = false; // чтобы гарантировать порядок document.head.appendChild(script); >addScript('1.js'); // загружаться эти скрипты начнут сразу addScript('2.js'); // выполнятся, как только загрузятся addScript('3.js'); // но, гарантированно, в порядке 1 -> 2 -> 3

Более подробно работу со страницей мы разберём во второй части учебника.

Итого

  • Скрипты вставляются на страницу как текст в теге , либо как внешний файл через
  • Специальные атрибуты async и defer используются для того, чтобы пока грузится внешний скрипт – браузер показал остальную (следующую за ним) часть страницы. Без них этого не происходит.
  • Разница между async и defer : атрибут defer сохраняет относительную последовательность скриптов, а async – нет. Кроме того, defer всегда ждёт, пока весь HTML-документ будет готов, а async – нет.

Очень важно не только читать учебник, но делать что-то самостоятельно.

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

Задачи

Какой скрипт выполнится первым?

важность: 4

В примере ниже подключены два скрипта small.js и big.js .

Если предположить, что small.js загружается гораздо быстрее, чем big.js – какой выполнится первым?

Подключение и настройка PHP

PHP — скриптовый язык программирования общего назначения, интенсивно применяемый для разработки веб-приложений. В настоящее время поддерживается подавляющим большинством хостинг-провайдеров и является одним из лидеров среди языков программирования, применяющихся для создания динамических веб-сайтов.

Начало использования

После подключения возможности использования PHP-скриптов у Вас в панели управления, на главной странице появится новый пункт: «PHP детали». Перейдя по этой ссылке, запишите данные (FTP host и FTP login) и установите пароль для подключения к FTP-аккаунту для загрузки PHP-скриптов:

Загрузка PHP-скриптов

Загрузка PHP — скриптов осуществляется по FTP соединению. Подключаться необходимо по данным предоставленным в окне «PHP детали» (на главной странице панели управления сайтом) и установленным Вами паролем.

Все скрипты необходимо загружать только в папку scripts (не в корневой каталог!). После загрузки PHP-скрипта в папку scripts, он будет доступен по адресу: http://php.ваш_сайт/example.php , либо http://ваш_сайт/php/example.php .

В последнем варианте используется так называемое проксирование. Это необходимо, например, для прямого обращения к PHP-скрипту через GET/POST запрос.

Подключение PHP-скриптов

На данный момент вывод на стороне сервера результата выполнения PHP-скрипта возможен только посредством использования функции «Импорт удалённого кода».

Минимальный период обновления информации составляет 3 часа. Результат выполнения скрипта на стороне клиента можно вывести, вставив следующий код в шаблон:

$.get('/php/SCRIPT_NAME.php',function(a));

Где phpinfo1, 1 — уникальный идентификатор в пределах одной страницы для каждого подключаемого PHP-скрипта. Первый вариант в пределах одной страницы можно использовать только один раз!

Как передать скрипту дополнительные параметры ?

Для этого необходимо использовать следующий код:

Вариант 1 (рекомендуется) — POST-запрос:

 $.post('/php/SCRIPT_NAME.php',< param1: 'value1', param2: 'value2' >,function(a)< $('#phpinfo1').html(a); >);

Принимать переданные значения в PHP-скрипте можно с помощью специального массива $_POST. Для параметров в выше написанном примере это будет: $_POST[‘param1’] и $_POST[‘param2’]

Вариант 2 — GET-запрос:

 $.get('/php/SCRIPT_NAME.php?param1=value1¶m2=value2',function(a)< $('#phpinfo1').html(a); >);

Принимать значения переданные GET-запросом можно с помощью специального массива $_GET. Для параметров в выше написанном примере это будет:

$_GET['param1'] и $_GET['param2']

GET — запрос, в отличии от POST-запроса, передаёт параметры непосредственно в ссылке, поэтому на параметры и их значения для GET-запроса накладываются различные ограничения.

Использовать php-скрипты на страницах сайта можно в текущем домене через проксирование:

В шаблонах для вызова php-скрипта можно использовать функцию PHPCODE следующим образом:

  • SITE_ADDRESS — адрес сайта пользователя, на котором выполняется скрипт
  • SCRIPT_NAME — путь (относительно папки scripts) и имя скрипта, который выполняется
  • ?param0=valueA&param1=valueB. &paramN=valueM — необязательные параметры для скрипта

Данная функция выполняет GET-запрос на указанный скрипт. Ответ для нее должен быть возвращен только в формате json, т.е. при использовании данной функции в шаблонах страниц, вызываемый ею скрипт не должен менять тип возвращаемых данных на какой либо другой (путем установки переменной $___notjson, использования функции header(‘Content-type: TYPE’) и т.п.). Использовать ее можно 1 раз на страницу.

Для вызова методом GET нескольких скриптов на одной странице можно использовать исходный javascript код функции $PHPCODE$, изменяя идентификатор (id) тега

Реализовать использование POST-запросов можно через формы, iframe, другие скрипты этого домена и т.д.

Например в файле шаблона:

 function updatepostdata(result) 

в скрипте SCRIPT_NAME.php:

"; foreach ($_POST as $i => $val) $ret.="$i=$val
"; echo " "; > echo " "; ?>

или в файле шаблона:

 function updatepostdata(result)  

в скрипте SCRIPT_NAME.php:

"; foreach ($_POST as $i => $val) $ret.="$i=$val
"; echo " "; > else echo "No data
"; ?>

Есть несколько параметров, которыми можно управлять в скрипте:

  • $___notjson=1 — если данная переменная установлена в единицу, то результат работы скрипта возвращается в том виде, в каком его сформировал скрипт, иначе (по умолчанию) результат возвращается в json формате
  • $___retval — результат работы скрипта (возвращенные им данные), может быть установлена в скрипте пользователя и будет использоваться, как результат работы
  • $___error — используется как описание ошибки в случае, если скрипт должен ее вернуть.

Не используйте __FILE__, т.к. скрипты выполняются через wrapper, и данная переменная определена как название wrapper-скрипта.

Как передать скрипту файл?

Передать PHP-скрипту файл на обработку можно с помощью обыкновенной формы с типом «multipart/form-data»:

Переданный скрипту файл можно получить из массива $_FILES: $_FILES[‘filename’][‘tmp_name’]

Встроенные функции

  • ucoz_getinfo(DATATYPE); Где DATATYPE — тип данных о пользователе, которые нужно вернуть. На данный момент доступен только один тип данных — SITEUSERID. Данный тип определяет ID пользователя, зашедшего на сайт. То есть, чтобы в PHP-скрипте вывести ID текущего пользователя необходимо использовать функцию: ucoz_getinfo(«SITEUSERID»);

Примечания

  • По умолчанию результат выполнения скрипта возращается в JSON формате.
  • Для вывода результата выполнения скрипта в обычном формате, в начале скрипта добавьте: $___notjson=1;
  • Для вывода ошибок используйте: $___error;

Полная инструкция по использованию PHP на uCoz находится здесь.

Внимание! Любые попытки использовать PHP-скрипты для злонамеренных действий, в частности для отправки большого числа HTTP-запросов куда-либо, наказываются удалением сайта!

Как подключить PHP

Данная услуга является платной.

Она доступна в рамках пакетов:

  • Оптимальный
  • Максимальный
  • Магазин

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

Ограничения использования PHP

Запрещено использование следующих функций:

  • Системные вызовы (proc_open, proc_terminate, shell_exec, system и т.д.)
  • Низкоуровневые функции по работе с файловой системой (dio_fcntl, dio_open, dio_read, dio_seek и т.д.);
  • Posix функции;
  • Shared memory функции;
  • MySQL функции (mysql_stat, mysql_pconnect);
  • Функции для отправки почты ( mail() );
  • Функции для работы с FTP (ftp_connect() и прочие; для работы с FTP используйте cURL);
  • Максимальный размер файла, обрабатываемого PHP-скриптом, либо загружаемого на PHP-сервер, равен 10 Mb;
  • Максимальное количество файлов и директорий в одной директории на PHP-сервере равно 500;
  • Максимальное общее количество всех файлов и дирректорий на PHP-сервере равно 10’000;
  • Максимальное время выполнения скрипта равно 25 секунд;
  • Доступное дисковое пространство на PHP-сервере для каждого пользователя равно 200 Mb;
  • По прямым ссылкам можно получить только файлы с расширением PHP. То есть, если вы загрузите на PHP-сервер, например, файл example.html, то по ссылке http://ваш_сайт/php/example.html он не откроется. Такие файлы могут быть открыты только посредством PHP-скриптов.

Актуальный список функций, которые запрещено использовать

popen,pclose,stream_copy_to_stream,dio_close,dio_fcntl,dio_open,dio_read,dio_seek,dio_stat,dio_tcsetattr,dio_truncate,dio_write,exec,passthru,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,system,expect_expectl,expect_popen,pcntl_alarm,pcntl_exec,pcntl_fork,pcntl_getpriority,pcntl_setpriority,pcntl_signal_dispatch,pcntl_signal,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_wait,pcntl_waitpid,pcntl_wexitstatus,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,posix_access,posix_ctermid,posix_errno,posix_get_last_error,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_initgroups,posix_isatty,posix_kill,posix_mkfifo,posix_mknod,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_strerror,posix_times,posix_ttyname,posix_uname,ftok,msg_get_queue,msg_queue_exists,msg_receive,msg_remove_queue,msg_send,msg_set_queue,msg_stat_queue,sem_acquire,sem_get,sem_release,sem_remove,shm_attach,shm_detach,shm_get_var,shm_has_var,shm_put_var,shm_remove_var,shm_remove,shmop_close,shmop_delete,shmop_open,shmop_read,shmop_size,shmop_write,apache_child_terminate,apache_get_modules,apache_get_version,apache_getenv,apache_lookup_uri,apache_note,apache_request_headers,apache_reset_timeout,apache_response_headers,apache_setenv,getallheaders,virtual,nsapi_request_headers,nsapi_response_headers,nsapi_virtual,mail,mysql_stat,mysql_pconnect

Какую версию PHP использует uCoz ?

На сентябрь 02.09.2021 актуальна PHP Version 5.2.12.

Что такое скрипт сайта и как его установить

Что такое скрипт сайта и как его установить

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

Что такое скрипт сайта

  • Клиентские на пользовательском ПК (команды в коде web-ресурса).
  • Серверные для выполнения функций в структуре ресурса.

Чем отличаются плагины и скрипты

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

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

Что такое скрипт

Языки скриптов

Сценарии пишут с помощью специальных языков, которые называют скриптовыми. У них разный синтаксис, возможности и области применения.

Языки бывают трех видов:

  • Общего назначения. Их используют для скриптового программирования в консоли операционной системы (Bash, PowerShell, язык командной оболочки в Windows).
  • Для решения узкоспециальных задач. Такие языки – составная часть программной системы (язык для работы в системе проектирования Autocad).
  • Языки универсального назначения. К этой категории относят языки для программирования сайтов (JavaScript, PHP, Python).

Маркетинг

Читайте также:

Как создать магазин в Инстаграм* с нуля: руководство и полезные советы

Как создать магазин в Инстаграм* с нуля: руководство и полезные советы

Принцип работы скриптов

  1. Пользователь выполняет необходимое условие на сайте.
  2. Информация поступает на сервер.
  3. На сервере запускается файл скрипта.
  4. Происходит обработка данных, по сценарию выбирается нужный ответ.
  5. После того как информация с сервера поступает на компьютер пользователя, совершается ответное действие.

Автоматические сценарии устроены так, что пользователю не нужно совершать действие. Это всплывающая поп-ап реклама или автоматическая прокрутка баннеров при открытии страницы сайта.

Также некоторые скрипты выполняются не на сервере, а в браузере. Для этого в браузерах встроен интерпретатор скриптового языка. Почти все браузеры умеют распознавать один из языков – JavaScript.

Скрипт для сайта

Для чего применяют скрипты на сайтах

Скрипты обеспечивают функциональность сайта. Они устанавливают алгоритмы поведения в каждой предусмотренной ситуации.

С помощью скриптов:

  • Собирают статистику. Это количество посещений или поведение пользователей на сайте.
  • Происходит сообщение между базой данных и интерфейсом сайта.
  • Подгружают информацию на страницы без обновления. Так работает кнопка «Показать еще» на сайтах интернет-магазинов.
  • Можно расширить функционал ресурса, добавить новые инструменты.
  • Автоматизируют большинство операций, необходимых для SEO-продвижения сайта. Это освобождает время вебмастера на решение других задач.
  • Добавляют динамические элементы дизайна. Например, в период новогодних праздников пишут скрипт с анимацией снегопада.

Роль скриптов в SEO

От скриптов зависит, каким будет результат SEO-работы, а также качество общей производительности сайта и скорости загрузки страниц.

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

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

Роль скриптов в продвижении

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

Сценарии автоматизируют большой объем рутинных задач контент-менеджера. Так, можно автоматизировать публикацию записей, генерацию метатегов. Скрипты также используют для имитации действий реальных пользователей. Это сервисы по накрутке активности в соцсетях, способные массово проставлять лайки или регистрироваться на почте и в соцсетях.

Сквозная аналитика Calltouch

  • Анализируйте воронку продаж от показов до денег в кассе
  • Автоматический сбор данных, удобные отчеты и бесплатные интеграции

JavaScript в контекстной рекламе

В системе Google Ads есть возможность управлять рекламной кампанией с помощью скриптов, написанных на JavaScript. Скрипт – это более простой и быстрый способ по сравнению с использованием API.

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

Преимущества скриптов

Безопасность работы. Скриптовые программы не требуют модификации основной части кода. Наличие ошибки не повлияет на работу остальных модулей сайта.

Скорость решения задач. Небольшой скрипт может заменить объемный код, где сложно найти проблему и решить ее.

Универсальность. Интерпретаторы скриптовых языков встроены в большинство современных браузеров, поэтому сценарии легко переносить между разными площадками.

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

Как установить скрипт на сайт

  1. Загрузить файл скрипта на сайт. Это делают с помощью ftp.
  2. Определить права доступа к скрипту.
  3. Установить программу с помощью инсталлятора.
  4. Заполнить все необходимые данные (может потребоваться доступ к базе MySQL).
  5. Настройка через панель администрирования.

Маркетинг

Читайте также:

Как рекламировать доставку еды

Как рекламировать доставку еды

Примеры использования скриптов

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

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

Виджет обратного звонка для сайта

  • Повысьте конверсию сайта на 30%
  • Новым клиентам 50 минут в подарок

Скрипты используют для автоматического формирования страниц или меню на них. Специализированные калькуляторы тоже делают с помощью скриптов.

Главное

  • Скрипты упрощают работу вебмастера, улучшают функционал сайта и помогают в продвижении. Их безопасно использовать, так как ошибка в одном модуле не представляет угрозы для работы всей системы.
  • Несмотря на то, что прописанные сценарии делают сайт удобным для пользователя, большое количество анимации и всплывающих окон может плохо повлиять на посещаемость и позиции сайта в поиске.

Как подключить скрипт на сторонний сайт

Привет, Хабр! Это первый пост в нашем блоге. Многие знают нас как чат для сайта, именно с него мы начинали, а сейчас занимаем лидирующие позиции в сфере бизнес-мессенджеров. Мы постепенно эволюционировали в комплексное бизнес-решение, которое предоставляет множество возможностей для клиентов: callback, общение с клиентами через мессенджеры, соцсети, мобильные приложения, виртуальная АТС, CRM-функции и многое другое.

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

image

Jivosite сегодня это:

  • 250К клиентов по всему миру;
  • 150М показов виджета в сутки;
  • 3.5М сообщений в сутки;
  • 10М чатов в месяц;
  • 1М одновременных коннектов;
  • 250+ серверов в production.

Входная точка

Театр начинается с вешалки, а подключаемый сервис с кода-вставки. Он является входной точкой для любого сервиса или модуля на сайт. Как правило, его можно найти в инструкции установки, после чего необходимо добавить его в HTML-код сайта, а дальше происходит «магия», которая определенным образом загружает и инициализирует скрипт.

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

Идентификация

Просто так подключать скрипт мало кому интересно, наверняка скрипт выполняет какую-либо логику, а эта логика привязана к пользователю. Например, ID счетчика, APP_ID от соцсети, в нашем случае это ID созданного канала связи. То есть скрипт должен идентифицировать пользователя в запросах на сервер. Для идентификации клиента через код-вставки есть три варианта реализации.

Передавать ID прямо в ссылке на файл и на стороне сервера каким-либо способом прокидывать его в скрипт. В этом случае серверу на лету придется прописывать ID в файл или формировать JS-строку c ID, которая будет загружать file.js. Эта логика похожа на реализацию JSONP-запросов.

Долгое время мы работали по такому принципу, но минусы этого подхода в том, что добавляется «холостая» нагрузка на сервер и необходимость реализации серверного кэширования.

   

Атрибут async — говорит браузеру о том, что не нужно дожидаться загрузки скрипта для построения DOM, скрипт надо выполнить сразу после загрузки. Это уменьшает время загрузки страницы, но есть и обратная сторона медали: скрипт может выполняться до того, как DOM будет готов к работе.

Одна из самых популярных реализаций, так делают в том числе и крупные сервисы, отличается только синтаксис, но суть у всех одна.

У такого подхода есть два основных минуса, первый — усложняется код-вставки, а второй — очень важен порядок выполнения данного кода, в противном случае ничего работать не будет. К тому же необходимо делать выбор между скоростью (async) и стабильностью (без async), большинство выбирают 2-й вариант.

Аналогично первому варианту передавать ID в ссылке на файл, но извлекать его в браузере, а не на сервере. Это не так просто, как кажется, но возможно. В API браузера есть свойство document.currentScript, оно возвращает ссылку на скрипт, который загружен и в данный момент выполняется в браузере. Зная это, можно вычислить ID, для этого надо получить свойство document.currentScript.src и регуляркой вытащить из него ID.

Есть одно но: document.currentScript поддерживается не всеми браузерами. Для браузеров, не поддерживающих это свойство, мы придумали интересный хак. В коде file.js можно выбросить специальное «фейковое» исключение, обернутое в try/catch, после чего в стеке ошибки будет URL скрипта, в котором произошла ошибка. URL будет содержать ID, который мы получаем той же регуляркой.

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

Настройки

В большинстве случаев у подключаемых скриптов есть какие-либо настройки, отвечающие за внешний вид или логику работы. Эти настройки необходимо «прокидывать» в подключаемый скрипт, для этого существуют два принципиально разных подхода.

  

К этому подходу также относится передача настроек в GET параметрах url скрипта, аналогично варианту #1 из раздела «Идентификация». Подход заключается в том, что если клиент хочет поменять настройки, то ему необходимо отредактировать код-вставки и обновить его на сайте.

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

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

Не надо разбираться в коде и делать ради этого деплой, этим может заниматься человек, далекий от JavaScript, например менеджер. Конечно для пользователей такой вариант гораздо удобнее и проще, поэтому именно его мы используем. Но за удобство надо платить, такой подход требует разработки и поддержки логики на сервере и подразумевает дополнительную нагрузку на него. В следующих статьях мы обязательно расскажем, как мы ежедневно обрабатываем 150М таких запросов.

Обратная совместимость

Очень важно максимально быстро прийти к зрелой версии кода-вставки. Потому что обновлять уже установленные коды-вставки будет крайне сложно. Пример из нашей практики: в первых версиях мы использовали числовые ID, но по соображениям безопасности заменили их на число-буквенные. Оказалось, что очень сложно добиться изменения уже установленного кода-вставки. Многие даже не знают, что такое HTML и как устроены сайты. Например, сайт делали фрилансеры, студия или сайт создавался через CMS/конструктор и т. д. В большинстве случаев наши клиенты работают только с панелью настроек виджета. С тех времен у нас до сих пор в nginx работает мапа реврайта старых ID на новые, в которой около 40К записей.

 . /script/widget/config/15**90 /script/widget/config/bqZB**rjW5; /script/widget/config/15**94 /script/widget/config/qtfx**xnTi; /script/widget/config/15**95 /script/widget/config/fqmpa**4YX; /script/widget/config/15**97 /script/widget/config/Vr21g**nuT; /script/widget/config/15**98 /script/widget/config/8NXL5**F8E; /script/widget/config/15**00 /script/widget/config/Th2HN**6RJ; . 

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

Изоляция кода

Так как скрипт подключается на сторонний сайт, на котором уже есть JavaScript и CSS код сайта и других сервисов, первостепенной целью является не навредить сайту, чтобы наш код не изменил логику, а тем более не сломал ее. Это может быть JavaScript-ошибка, которая останавливает поток выполнения, или стили, которые переопределяют стили сайта. Но и код сайта может саффектить подключаемый скрипт, например используется библиотека которая модифицирует браузерное API, после чего код перестает работать или работает не так, как мы ожидаем.

  
 // код библиотеки или разработчика сайта body * < padding: 20px; >form input 

Есть разные варианты изоляции кода. Например можно использовать префиксы в JS переменных, замыкания, чтобы не засорять глобальный контекст, использовать что-то наподобие БЭМ для стилей. Но самый простой способ — это выполнения кода в iframe, он решает большинство проблем изоляции, но накладывает определенные ограничения. Мы используем гибридный вариант, про изоляцию кода расскажем подробнее в следующих статьях.

Блокировка загрузки сайта

Событие onload — наступает после того, как веб-страница полностью загружена, включая изображения, стили и внешние скрипты. Важная особенность в том, что на большинстве сайтов JS-логика, сторонние скрипты и реклама начинают работать по наступлению этого события. Очень важным пунктом для всех подключаемых скриптов является не допустить негативного влияния на это событие.

Это происходит в тех случаях, когда сервер, с которого грузится скрипт, отвечает долго или вовсе не отвечает: тогда событие onload откладывается и дальнейшая загрузка страницы по сути блокируется. В случае, когда сервер недоступен, событие onload наступит только по истечении таймаута запроса, который больше 60 с. Таким образом, проблемы на сервере отдачи скрипта по сути «ломают» сайты, что является недопустимым.

Личный опыт
В прошлом я работал в компании, у которой был сайт с одновременным онлайном 100К, онлайн-знакомства. В те времена были попопулярны кнопки «Поделится в соцсетях». Чтобы они появились на сайте, надо было подключить скрипт (sdk) от нужных соцсетей. В один прекрасный день к нам прибежали коллеги и сказали, что наш сайт не работает! Мы посмотрели в мониторинги, в которых все было нормально, и сначала не поняли, в чем проблема. Когда начали разбираться глубже, поняли, что cdn-сервера Twitter прилегли, и их SDK не мог загрузиться, это блокировало нам загрузку сайта на ~1.5 минуты. То есть после открытия сайта загружался небольшой HTML(остальное SPA) и только через 1.5 минуты все прогружалось, срабатывал тот самый таймаут запроса. Нам пришлось экстренно организовывать хотфикс и убирать их скрипт с сайта. После повтора этой ситуации мы решили убрать блок «Поделиться» совсем.

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

  

Решение простое, надо подписаться на событие полной загрузки сайта и только потом загружать скрипт, для этого надо использовать код-вставки, а не тег script.

Google Pagespeed

Результаты анализа мобильной версии habr.com

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

Это означает, что надо использовать современные техники оптимизации загрузки страниц. Например использовать Gzip, кешировать статические файлы и запросы, использовать асинхронную загрузки скриптов, сжатие статики современными алгоритмами такими как WebP/Brotli/etc и использовать другие оптимизации. Мы регулярно проводим аудит и реагируем на предупреждения и рекомендации, чтобы соответствовать современным требованиям.

CDN

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

С целью экономии бюджета, стабильности и уменьшения сетевой задержки оптимально загружать статику со специально предназначенных для этого серверов. Можно использовать готовые CDN-провайдеры, но на больших масштабах это недешево и приходится ограничиваться возможностями, которое предоставляет тот или иной провайдер.

Мы реализовали это просто, заказали недорогие сервера в России, Европе и Америке с безлимитным трафиком и широким каналом. Это дешево, не накладывает на нас никаких ограничений, мы можем настроить все под себя, а отказоустойчивость обеспечивается за счет механизма, работающего в браузере. В данный момент с наших CDN-серверов загружается 1ТБ статики ежедневно.

Отказоустойчивость

К сожалению, мир не идеален, случаются пожары, аплинки падают, ДЦ целиком уходят под воду, РКН блочит подсети, а люди совершают ошибки. Тем не менее, необходимо уметь обрабатывать такие ситуации и продолжать работать.

Мониторинг
Сначала надо понять, что что-то пошло не так. Можно, конечно, подождать, пока пользователи придут и пожалуются, но лучше настроить мониторинг и алерты, а после релизов, проверять все ли в порядке. Мы мониторим много различных параметров, как серверных, так и клиентских, и если что-то пошло не так, мы сразу это видим. Например, уменьшилось количество загрузок виджета или аномальный всплеск трафика на CDN-серверах.

Суммарное кол-во загрузок виджета по каждой версии

Сбор ошибок
JavaScript очень специфичный язык, и допустить в нем ошибку несложно. К тому же зоопарк браузеров в современном вебе очень большой; то, что работает в последнем Chrome, не факт, что будет работать в Safari или Firefox. Поэтому очень важно настроить сбор ошибок из браузера и вовремя реагировать на всплески. Если ваш код работает в iframe, то сделать это можно отслеживая глобальный обработчик window.onerror и в случае ошибки отправлять данные на сервер. Если код работает вне iframe, то реализовать сбор ошибок очень сложно.

Суммарное кол-ва ошибок со всех сайтов и браузеров

Информация по конкретной ошибке

CDN Failover
Выше я уже писал, что все имеет свойство падать, поэтому важно обрабатывать эти ситуации и лучше — автоматически. Мы прошли несколько этапов фаллбека CDN-серверов, начинали с ручного, а в итоге нашли способ делать это автоматически и оптимально для браузера.

В ручном режиме это работало просто: админам приходило СМС о том что CDN прилег, они совершали определенные манипуляции, после чего виджет начинал загружаться с серверов приложения. Это могло занять от 5 минут до 2 часов времени.

Для реализации автоматического фаллбека необходимо как-то детектить, что загрузка скрипта началась, но сделать это не так просто, как кажется. Браузер не дает возможности отслеживать промежуточные состояния загрузки тега script, как например событие onprogress в XMLHttpRequest, а сообщает только событие по окончанию загрузки и выполнения скрипта. Также нельзя за приемлемое время узнать, что сервер в данный момент недоступен, единственное событие onerror срабатывает по истечении таймаута запроса, больше 1 минуты. За минуту посетитель может уже покинуть страницу, а скрипт так и не загрузится.

Мы пробовали разные варианты, простые и сложные, но в итоге пришли к решению с ping-запросом CDN-сервера. Работает это так: мы сначала пингуем CDN-сервер, если ответил, то тогда мы загружаем виджет с него. Чтобы реализовать эту схему оптимально для браузера и наших серверов, мы используем легкий HEAD-запрос (без тела), а при последующих загрузках мы его не делаем, пока не обновится версия виджета, т. к. виджет уже в кеше браузера.

Таким образом мы получили очень быстрый и автоматически детект доступности сервера статики и в случае падения практически без задержек переходим на резервный сервер.

Loader

Чтобы загрузить свой скрипт на сторонний сайт, надо учесть множество моментов, но реализовать эту логику в коде-вставки сложно, так как он просто превратится в «мясо». Но делать это все равно надо, для этого мы создали небольшой модуль, который управляет всей этой логикой «под капотом» и загружает основной код виджета. Он загружается в первую очередь и реализует CDN Failover, кеширование, обратную совместимость со старыми кодами-вставки, А/Б тестирование, постепенную выкладку новой версии виджета и множество других функций.

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

Сторонние сервисы

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

GoogleBot
В нашем приложении оператора есть функция «Посетители», в которой можно посмотреть посетителей, в данный момент просматривающих сайт, и различную информацию по ним: время на сайте, страницу, число просмотренных страниц и так далее. В определенный момент клиенты начали жаловаться, что у них «висят» посетители с других сайтов, то есть на сайте по продаже айфонов, клиент, у которого якобы открыта страница «Купить крем для лица». Когда начали разбираться, выяснили, что это GoogleBot, который при переходе от сайта к сайту кешировал LocalStorage первого и впоследствии передавал неправильные данные на сервер.

Решение простое, на сервере начали игнорировать данные от GoogleBot.

Яндекс.Метрика
В метрике есть замечательная функция — вебвизор, которая позволяет посмотреть, что видел и делал пользователь, в виде скринкаста. Для этого метрика записывает все действия пользователя, а после специальный бот метрики ходит по сайтам, совершает те же действия и записывает это. Проблема была в том, что для эмуляции мобильного браузера пользователя, по нашим данным, включался Firefox в режиме мобильной эмуляции, но при этом userAgent у бота был десктопный.

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

Примеров намного больше, но, думаю, этого будет достаточно для понимания сути.

Заключение

Надо очень внимательно относиться к коду, который вы отдаете клиентам для вставки на сайт. Мы кратко рассказали, с какими проблемами мы столкнулись и как их решали. В следующих статьях мы более подробно расскажем про некоторые упомянутые темы и другие участки нашей системы, например, как мы используем NodeJS в качестве бэкенда, как держим нагрузку всех 270К сайтов за счет продуманного кеширования и не боимся хабра-эффекта подключенных к нам сайтов, как работаем в полностью распределенной команде и многое другое.

Спасибо за внимание, будем рады ответить на ваши вопросы и комментарии!

  • Блог компании Jivosite
  • Веб-разработка
  • JavaScript

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *