Тептар:Пределы шаблонов

Версия от 21:22, 17 февраля 2022; Adam (обсуждение | вклад) (Новая страница: «{{shortcut|ТП:ПРЕДЕЛ}} В MediaWiki есть несколько параметров, которые задают '''пределы''' сложности страниц и количества включаемой в страницу информации. Эти пределы касаются в основном той информации, которая включается в страницу через Тептар:Механизм шаб...»)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
↱

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

Справка

Что это?

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

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

Зачем нужны эти пределы?

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

Что делать, если пределы всё-таки превышены?

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

Когда проблема может возникнуть?

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

Как узнать, превышены ли пределы?

При обработке страницы движком в HTML-код после основного содержимого страницы добавляется тег комментария mw:NewPP parser report, содержащий итоговые значения счетчиков. Например, статья Кошка (на момент 19 апреля 2011 года) содержит следующий комментарий в сгенерированном HTML-коде:

<!-- 
NewPP limit report
Preprocessor node count: 68502/1000000
Post-expand include size: 431392/2048000 bytes
Template argument size: 210835/2048000 bytes
Expensive parser function count: 89/500
-->

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

<a href="/wiki/Шаблон:Foo" title="Шаблон:Foo">Шаблон:Foo</a><!-- WARNING: template omitted, post-expand include size too large -->

Включение шаблонов

Шаблоны в нераскрытых ветвях условных функций парсера не учитываются счётчиком. Например, в коде {{#if:yes|{{bar}}|{{foo}}}}, шаблон {{bar}} раскрыт, но шаблон {{foo}} не будет раскрыт и не будет посчитан счётчиком.

Тем не менее, аргумент шаблона может влиять на счётчик, даже если он не включён в итоговый результат. Например, если страница содержит {{#if:{{foo}}|yes|no}}, парсер для выполнения этого кода должен раскрыть шаблон {{foo}}, и размер этого шаблона будет включен в post-expand counter.

Счётчик узлов препроцессора

Счётчик узлов препроцессора (англ. preprocessor node count) определяет сложность страницы (но не объем данных). Во время анализа тептар-текста парсер создает XML-подобную структуру данных, которую потом преобразует в HTML. Каждый узел этой структуры, затронутый при генерировании страницы, учитывается этим счётчиком. Если счётчик превысит предел, парсер прервет анализ страницы и выдаст ошибку «Node-count limit exceeded», видимую в итоговом HTML.

Счётчик устанавливается в единицу, когда обрабатывается первый узел, предназначенный для обычного текста. Пара тегов <nowiki> считается за 3 узла, заголовок за 2 и т. п. Ссылки не влияют на этот счётчик. Для функции #switch каждое возможное значение добавляет к счетчику 2 единицы. В случае множественного включения одного шаблона, содержимое этого шаблона без аргументов считается единожды, но шаблон с аргументами будет учитываться при каждом включении. Однако результат многократного раскрытия (шаблонов) может быть многократно использован, изменив значение счетчика лишь единожды, если этот результат присвается параметру шаблона, и шаблон позволяет многократное использование этого параметра.

Размер раскрытых включений

Счётчик размера раскрытых включений (англ. post-expand include size) учитывает размер тептар-текста, раскрытого из шаблонов, функций парсера и переменных. Каждый раз, когда парсер раскрывает на странице содержимое шаблона (включением или подстановкой), размер этого шаблона добавляется к текущему значению счётчика. Если полученная сумма превысила предел, оставшиеся шаблоны не раскрываются, и в HTML-код добавляется только имя шаблона и сообщение об ошибке <!-- WARNING: template omitted, post-expand include size too large -->. Шаблоны, включаемые в страницу многократно, добавляются к счётчику при каждом включении. Считается раскрытие шаблонов в тептар-текст (не в html), тот же что виден в Служебная:Развёртка_шаблонов.

При вызове шаблона без аргументов раскрытый текст шаблона кэшируется. Так, например, если в шаблон {{foo}} включен подшаблон {{bar}}, и на странице шаблон {{foo}} используется множество раз, счётчик будет учитывать при каждом новом включении только полностью раскрытый шаблон {{foo}}, в то время как шаблон {{bar}} будет учтен только при первом включении шаблона {{foo}}. Но если многократно включать шаблон с аргументами, например, {{foo|arg}}, то второй шаблон {{bar}} будет учитываться при каждом включении как и первый, даже если аргументы будут повторяться.

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

Комментарии, теги <noinclude> и <includeonly>

Счётчик учитывает только те данные, которые препроцессор раскрывает при обработке шаблона. Таким образом, размер HTML-комментариев в тептар-тексте не влияет на значение post-expand include size. Фрагменты кода, заключенные в теги <noinclude>, или находящиеся вне тегов <includeonly> также не раскрываются в итоговый текст и не учитываются счётчиком. То же касается и категорий — они учитываются счётчиком, только если включаются в итоговую статью (при категоризации шаблоном).

Вложенные включения

Стоит отметить, что размер всех раскрытых шаблонов и функций парсера суммируется в том числе и при многократном вложении[1]. То есть, если страница A включает страницу B, а B в свою очередь не содержит ничего, но включает страницу C, размер страницы C будет учтён счётчиком дважды. Так же это касается случаев, когда шаблоном вызываются функции парсера или функции парсера вызывают другой шаблон в качестве своего параметра. Влияние на счётчик может быть уменьшено, если в функциях парсера использовать не включения шаблона, а только его имя, например:

{{#if:{{{test|}}}|{{template1}}|{{template2}} }}

заменить на

{{ {{#if:{{{test|}}}|template1|template2}} }}.

Размер аргументов шаблона

Счётчик размера аргументов шаблона (англ. template argument size) учитывает общий размер использованных аргументов шаблона.

Например, конструкция {{3x|{{2x|abcde}}}} увеличит значение счётчика на 40 байт: аргумент {{2x|abcde}} будет вставлен 3 раза, а аргумент abcde 2 раза.

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

Если шаблон содержит «переключатель» (англ. switch), аргументы шаблона, не совпадающие со значением оператора выбора (англ. case), также не учитываются счётчиком. Аргументы шаблона в левой части «переключателя», расположенные до совпадающего со значением оператора выбора включительно, учитываются счётчиком дважды, а аналогичные аргументы в правой части учитываются лишь единожды.

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

Вызовы ресурсоёмких функций парсера

В данный момент пределом для счётчика ресурсоёмких функций парсера (англ. expensive parser function count) является значение 500. К ресурсоемким функциям парсера относят, например:

  • #ifexist — разветвление в зависимости от существования указанной в аргументе страницы. Если предел будет превышен, все функции #ifexist по умолчанию будут считать запрашиваемые страницы не существующими.
  • PAGESINCATEGORY
  • PAGESIZE

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

#time

Общая длина строк функций времени #time ограничена значением 6000 символов[2]. Сообщение об ошибке задается в MediaWiki:Pfunc time too long. Для каждой комбинации раскрытого тептар-текста из строки функции времени и раскрытого тептар-текста из выражения времени (напр. «1 Mar 2008 −1day»), повторное использование не учитывается счётчиком, так как результаты кэшируются.

К сожалению, значения этого счётчика не выводятся в служебный комментарий html-кода итоговой страницы.

Служебная:Expandtemplates

Когда страница превышает какой-либо предел, одним из вариантов решения проблемы может быть применение расширения Extension:ExpandTemplates, которое выполняется на служебной странице Expandtemplates. В отличие от подстановки шаблонов служебная страница рекурсивно раскрывает все уровни сразу без необходимости раскрывать шаблоны конструкциями вида {{{|safesubst:}}} или аналогичными[3]. Это обнуляет все счётчики, кроме счётчика узлов препроцессора (англ. preprocessor node count), но даже его значение существенно уменьшается, не позволяя превысить предел.

История

Пределы для шаблонов были впервые введены Tim Starling 14 августа 2006 года в английском разделе Тептар. Новый препроцессор, введенный в январе 2008 года, заменил предел размера раскрываемых включений (англ. pre-expand include limit) на предел узлов препроцессора (англ. preprocessor node limit).

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

Примеры

Если инициалы для авторов используются в шаблонах источников, например 500 книг/статей как примечания, использование шаблона nobr и мнемоники nbsp увеличивает размер раскрытых включений и размера параметров. При достижении предела раскрытия шаблоны и примечания перестанут показываться. В этом случае пробелы можно заменить на символ неразрывного пробела из юникода, но не копируйте его, а вставьте через alt+255. Использование инициалов вместо полного имени также отодвигает момент предела.

См. также

Примечания

Ссылки