Асинхронная загрузка виджетов ВКонтакте

Как известно, ВКонтакте есть несколько полезных виджетов, которые можно разместить на своем сайте, например, виджет группы или комментариев. Но есть у них недостаток: они вставляются обычным тегом script и подгружаются с сервера ВКонтакте, что ощутимо тормозит загрузку сайта целиком. А если вдруг у пользователя по каким-то причинам заблокирован домен vk.com, то он может и вообще не дождаться загрузки сайта. В результате я решил сделать загрузку асинхронной. Первое, что пришло в голову — это использовать свойства defer или async у тега script, но оказалось, что в этом случае ничего не работает вообще из-за того, что код инициализации пытается выполниться раньше, чем будет загружен скрипт и создан объект VK. Но это достаточно легко обойти:
нужно вынести код инициализации в анонимную функцию на событии onload:


<script  async="async" src="https://userapi.com/js/api/openapi.js?20" onload='VK.init({apiId: ID_сайта_ВКонтакте, onlyWidgets: true}); VK.Widgets.Group("vk_groups", {mode: 0, width: 200, height: 250}, номер_группы); VK.Widgets.Comments("vk_comments", {limit: 10, width: 400, attach: "*"});'> </script>

Для того, чтобы код сработал корректно, нужно расположить его после блока для виджетов <div id="vk_groups"></div>

Теперь подгрузка виджетов начинается параллельно отображению основной части сайта и не тормозит его! Посмотреть в действии можно на сайте SOCIOMODEL.RU (но там несколько более сложный код).

Добавлено 19 мая 2018 года. А с помощью библиотеки CondiLoader подгрузку можно сделать так:


<script> function CondiLoaderInit() {  new CondiLoader([ {   js: "http://userapi.com/js/api/openapi.js?20",    init: function () {         VK.init({apiId: ID_сайта_ВКонтакте, onlyWidgets: true});         VK.Widgets.Group("vk_groups", {mode: 0, width: 200, height: 250}, номер_группы); // вывод группы         VK.Widgets.Comments("vk_comments", {limit: 10, width: 400, attach: "*"}); // вывод комментариев    } }  ],{ /* options */ }); } </script> <script src="condi_loader.js" onload="CondiLoaderInit()" defer="defer"></script>