[Из песочницы] Кеширование всего HTML и подключение JS «на ходу»

Однажды я совершил страшное дело — посмотрел исходный код главной страницы Яндекса и задумался — что-то тут не так. Я вижу 5 заголовков последних новостей, несколько картинок, поле поиска, ссылочки и вот вопрос: Где тут 700Кб, которые требуют 1,56с моего времени? Они в коде.Все мы ходим по сайтам, получаем килобайт полезной для себя или вообще воспринимаемой человеком информации и при скорости в 3Мбит/с тратим на это секунды. В этом посте я постараюсь описать, как передавать как раз только тот килобайт, который нужен человеку, а все остальное либо кешировать, либо вообще грузить только когда понадобится.

image

Первый на очереди к оптимизации — HTML Было бы неплохо кешировать весь HTML или хотя бы его большую часть — для этого можно использовать блочное кеширование: страницу разбиваем на блоки и эти блоки выносим в отдельный JS файл, который потом остается у пользователя. Плюс такого подхода в простоте, но в нашем случае будет нетривиальное решение — надо все немного усовершенствовать.Страницу можно не просто разбивать на блоки, а все в body заменить на XML структуру, соблюдая все отношения родительства — радикально и эффективно. Никаких стилей и излишеств. Для примера возьму код Яндекса для вывода 5-ти новостей:

Получилось следующее:

Каждая новость теперь становится одним тегом. Если подобным образом представить всю страницу, то получится как раз некая помесь HTML и XML, можно назвать это [X]HTML, потому что фактически это HTML, только теперь он расширяемый — в прямом смысле этого слова. Допустим страница представлена в XML, теперь для каждого блока я добавляю в JS файл его шаблон — то, как он должен выглядеть на самом деле. По аналогии с PHP я выделил '$' в шаблонах переменные, которые надо брать из атрибутов и $HTML$ — innerHTML тега.

var novosti='

$HTML$
'; var tab='
    $HTML$
'; var newsr='
  • $num$. $pre$ $ahr
  • '; Итог — весь HTML помещается в JS файл, а на самой странице остается только то, что нужно пользователю, но это только половина дела, потому что основной трафик страницы, помимо изображений, это JS.

    Оптимизация JS Если JS файл весит 100–200Кб, то его загрузка это около 0,5с. Он загрузится и останется в кеше, а вот задержка перед его выполнением все равно останется — это связано с тем, что JS файл сначала загружается, потом весь анализируется и только после этого начитает выполняться. Такая особенность позволяет, например, вызвать функцию еще до ее объявления. Чем больше файл — тем дольше аналаз, до 300 мс, а иногда и больше. Есть очень хороший способ сократить время — сделать файл дискретным: разбить на отдельные функции или просто части и подключать их, когда они нужны. Они так же будут кешироваться, только время их анализа будет гораздо меньше — в пределах 1–2 мс.Пусть у нас есть функция, которая в реальном времени подключает JS файлы, например, вот такого вида:

    inc ({ //список подключаемых функций/файлов вида name:'id' — name-название функции (для вызова), id-постфикс для файла }, function () { //JS с использованием подключенных функций и файлов }); Для нее есть несколько требований. Во-первых, она должна запоминать уже подключенные функции и файлы, во-вторых поддерживать загрузку из разных каталогов, а так же быть асинхронной. Для указания каталога можно использовать глобальную переменную includesrc=«любойсайт.ру/каталог/» для подключения файлов и «любойсайт.ру/каталог/функция_» для функций — к этому пути будет добавляться id (постфикс). Допустим, что надо разбить файл на несколько частей или функций, тогда полученные файлы должны быть примерно такого вида:

    //если файл с одной функцией, то ludes[«id»]=function (a1, …, aN){ //код }

    //если с несколькими: //функции (просто часть исходного файла) ludes[«id»]++;//id — это имя файла, без расширения Таким образом, в файле с функцией должна быть указана часть имени файла, а при подключении файла — его название, только без расширения.

    ESS Выше я написал, как можно вынести весь HTML и кешировать, передавать только нужную информацию в XML виде, потом написано, как можно свести задержку перед выполнением JS к нескольким миллисекундам, но нет самого решения проблемы — вот оно. Его можно назвать ESS — Easy Stylesheets, по аналогии с CSS. Состоит из 2+1 функций.ess (a, b); — функция, заменяющая XML блоки на странице шаблонами из JS файла, ей надо передать a — элемент DOM и b — строчку-шаблон.inc (); — уже упомянутая функция, которая позволяет асинхронно подключить любой файл, с любого домена и затем продолжить работу.И вспомогательная функция g (a, b, c); — ищет объект по строчкам CSS вида. a — с каким tag/#id/@ name/.class искать объект, b — в каком объекте искать и с — флаг 0/1, указывающий, надо ли в любом случае возвращать массив.

    Для ESS есть документация, в которой описан синтаксис и наглядные примеры использования. Функции ess () и inc () не только позволяют экономить время пользователя и снижает нагрузку на сервер, они так же открывают новые возможности для программирования на JS, но это уже тема для отдельной статьи.

    © Habrahabr.ru