(From Add post-processing cache, disabled by default.)
As described in T292302, when viewing a file page on Commons, first we parse the page. Then CommonsMetadata::onSkinAfterBottomScripts extracts metadata from a File, which runs LocalFile::getDescriptionText which parses the file page again.
The code in question is https://github.com/wikimedia/mediawiki/blob/b761ab61eed3b3ba0c1eb628e07da74769ac67af/includes/FileRepo/File/LocalFile.php#L2593C1-L2601
$parseStatus = $services->getParserOutputAccess()
->getParserOutput( $page, $parserOptions );
if ( !$parseStatus->isGood() ) {
// Rendering failed.
return false;
}
// TODO T371004 move runOutputPipeline out of $parserOutput
return $parseStatus->getValue()->runOutputPipeline( $parserOptions, [] )->getContentHolderText();So we're going to get postproc request for the page, which will put the main content of the page in the parser cache and also the postprocessed output. Then, at the very end of processing the output page, SkinAfterBottomScripts is invoked, which is going to get the ParserOutputAcess and ::getParserOutput on the same page with "often" the same parser options (it uses ParserOptions::newFromContext(), so it won't have useparsoid set, eg). For reasons I don't fully understand (T301310#7712257) this second invocation doesn't get the same pool counter and wouldn't be able to successfully read the parser cache (why?) but will hit the local cache successfully to prevent the double parse. (Except in the case of Parsoid read views the second parse will be with useparsoid=0 so we're still double-parsing in this case, alas.)
Anyway, I don't see any problem with excluding postprocessed output from the local cache for the time being. In order to actually make this path more efficient, we'd have to (a) tweak LocalFile::getDescriptionText() to use the ArticleParserOptions hook so the parser options were the same, and (b) set the postproc flag and make the postprocessing options match up with the ones Article uses as well. The skin is missing here, for example. It's possible instead of (b) we should be returning ParserOutput::getRawText() but that requires a bit more thought.