Comments 9
А как данная защита спасет от использования chromium в headless mode?
С интересом прочитал заметку, занёс в закладки, при необходимости парсинга буду учитывать подобный вариант защиты.
Надеюсь, web-специалисты нам здесь расскажут о регулярной динамической обфускации данных и структур, отдаваемых сервером.
На каждую хитрую гайку найдется свой болт с резьбой, поэтому не очень понял, какие такие данные надо защищать от парсинга? В моём понимании, если сайт настолько популярен и полезен, люди его не только регулярно смотрят, но и парсят, то надо помочь-углУбить-расширить, создав сервисы и api для скачивания. А уж после созревания поляны, начать её доить.
Тут под "блокировкой парсинга" подразумевается блокировка браузером парсинга HTML во время загрузки/выполнения JS/CSS. И статья — про повышение скорости загрузки страниц.
Плюсанул за "регулярную… динамическую… обфускацию… данных и структур"
Вы путаете скрапинг и парсинг
Скрапинг - это то, что вы называете парсингом
Парсинг - это то, что делает браузер чтобы отобразить страницу
В силу того, что переводчик совершенно не ориентируется в теме материала, а оригинал написан безобразно получилась жуткая химера от которой вреда больше чем пользы.
Судите сами:
Если в теге
<script>
не используются атрибутыasync
илиdefer
— процесс загрузки и обработки материалов страницы происходит так, как показано на следующей схеме. Загрузка JS-файлов и выполнение содержащегося в них кода блокирует парсинг HTML-кода.
Таким образом как показано на схеме, парсинг происходил 10 лет назад. С тех пор разработчики браузеров догадались, что ждать не обязательно и, как минимум, это время можно использовать для параллельной загрузки других внешних ресурсов, которые когда придет их время пройдут типичные для них шаги активации.
Правильно было бы писать, что показанное на схеме, это очень упрощенное отображение процесса, активации скрипта, которое в настоящее время хоть и имеет прямое отношение к реальности, но уже не оказывает драматического влияния на производительность (как это было раньше) в силу того, что все современные браузеры научились смотреть в будущее и готовить внешние ресурсы заранее.
Далее:
Когда браузер обрабатывает тег
<script>
с атрибутомasync
, загрузка JavaScript-кода осуществляется в асинхронном режиме. Код скрипта выполняется сразу после загрузки. При этом выполнение JS-кода блокирует парсинг HTML.
и
Если в теге
<script>
имеется атрибутdefer
— код скрипта загружается асинхронно. При этом код, после завершения его загрузки, выполняется только тогда, когда будет завершён парсинг HTML-кода.
Автор материала пытается пересказать спецификацию, но делает это способом который сбивает с толку переводчика, и получается неоднозначная формулировка когда можно подумать, что в случае async блокировка рендера происходит, а в случае defer нет. На самом деле это не так, на самом деле блокируют оба, только в силу особенностей поведения defer происходит это всегда в момент когда вероятность этого минимальна.
async и defer - как же все на самом деле
Радикальная разница async и defer заключается в том, что defer гарантирует активацию скриптов ровно в том порядке в котором они были обнаружены на странице, при этом момент активации в настоящий момент определен как точка ровно перед событием domcontentloaded. При этом async может выполниться в любой момент времени когда браузер решит что он готов это сделать, но при этом обязательно до события load.
Когда я говорю в настоящий момент, я хочу обратить внимание что все время спорадически возникают обсуждения новой спецификации, которая, предполагает активацию подобных скриптов без обязательной привязке к domcontentloaded, так как строго говоря, в современных реалиях такое поведение это почти тоже самое что лечить геморрой подорожником. Вроде как бы и лечит, только эффективность сомнительная.
Иными словами, тот факт что цепочка defer скриптов гарантированно выполняется перед domcontetnloaded дает гарантию только того, о чем говорит событие - html распасрили и dom готов, но не говорит о том, что если сейчас что то иницирует reflow он не будет заблокирован работающим defer скриптом. Он будет заблокирован ровно так же как и async и любым другим скриптом, за исключением workero ов. В результате мы вроде бы как поток основного построение DOM и не блокировали и должны радоваться, только все мы знаем что современный проект почти всегда это не просто DOM но и JS логика. Как итог, вспоминаем про подорожник.
Именно по этой причине, при построении приложений где производительность играет ключевое значение, никто не использует ни async ни defer в силу их текущей практической бесполезности (за исключением одного особого случая, о котором я напишу ниже) и именно поэтому возникают идеи изменить спецификацию и дать возможность выполнения скприта без привязки к событиям domcontentloaded и load
Если не async и defer то что и как?
Организация современного приложения в условиях строго детерминированного бюджета выделяемых ресурсов на его работу, должна выстраиваться на основе Service Worker ов с cache API и строгим контролем fetch запросов с учетом текущего IDLE браузера. Что реализовать 10 лет было невозможно, а сейчас стало не просто реальностью - но стандартом дефакто
Что за особый случай для async и defer о котором говорилось выше
Не смотря на почти полную бесполезность этих атрибутов в реалиях современной разработки, разработчики V8 (насчет других неуверен, кажется в Spider Monkey так же) все таки нашли еще одну возможность реанимировать эти два зомби. Сейчас указав скрипту этот атрибут Вы не просто измените поведение его загрузки и точку его активации, но дадите возможность браузеру провести парсинг и компиляцию части скрипта за пределами основного треда, в отличии от классической схемы, где парсинг с компиляцией пройдет в основном треде со всеми вытекающими.
В результате этой микро фичи, некоторые проекты, в основе которых не закладывались какие либо претензии к производительности могут получить существенное ощутимое изменение в фазе холодного старта. Касается это тех приложений которые до сих пор весь свой код собирают в единый большой жирный красивый толстый бандл, вешая поверх него рюкзак с полифилами и давая в руки плакат - я сделяль. То есть в ситуации когда компиляция занимает ощутимое время указанием defer или async мы помогаем браузеру разрешая ему собрать это безобразие в отдельном потоке.
Отдельного внимания заслуживает процесс кеширования байткода да и сам процесс компиляции. с 2015 года браузеры использующие v8 получили возможность кешировать не просто файл скрипта, но и байткод получаемый при его выполнения. Google Chrome например с 2015 года это делает. При этом, логика работы этого хозяйства, то есть по какой причине были выбраны именно такие алгоритмы, а не другие, для меня, человека знающего до последней ассемблерной команды эту часть работы, до сих пор не понята.
Итого
Построение отзывчивого интерфейса в условиях больших обьемов JS логики, давно ушло за рамки борьбы с блокированием построения DOM дерева и началом его рендера. И требует сейчас достаточно неплохого знания современных технологий, от Wotker ов, WorkLet ов, до принципов компиляции современными платформами JS кода.
Google не так давно стал заявлять, что в 2022 году начнет активно внедрять метрики, которые будут опираться уже не просто на скорость рендера, но и на обьемы потребляемой памяти и обьемы затрачиваемого процессорного времени.
CSS, JavaScript и блокировка парсинга веб-страниц