Make page loading faster by deferred script loading:
* Create generalized function for emmitting <script defer src=""> tags to templates * Remove type attribute from inline_js * Add defer attribute to external <script> tags Signed-off-by: Michael Letzgus <michaelletzgus@users.noreply.github.com>
This commit is contained in:
parent
6e3a914f4a
commit
fb9f13d4c1
5 changed files with 44 additions and 24 deletions
|
@ -12,20 +12,13 @@
|
|||
<link rel="icon" href="<?php print_unescaped(image_path('', 'favicon.ico')); /* IE11+ supports png */ ?>">
|
||||
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>">
|
||||
<link rel="mask-icon" sizes="any" href="<?php print_unescaped(image_path('', 'favicon-mask.svg')); ?>" color="<?php p($theme->getColorPrimary()); ?>">
|
||||
<?php if (isset($_['inline_ocjs'])): ?>
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" type="text/javascript">
|
||||
<?php print_unescaped($_['inline_ocjs']); ?>
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php foreach ($_['cssfiles'] as $cssfile): ?>
|
||||
<link rel="stylesheet" href="<?php print_unescaped($cssfile); ?>">
|
||||
<?php endforeach; ?>
|
||||
<?php foreach($_['printcssfiles'] as $cssfile): ?>
|
||||
<link rel="stylesheet" href="<?php print_unescaped($cssfile); ?>" media="print">
|
||||
<?php endforeach; ?>
|
||||
<?php foreach ($_['jsfiles'] as $jsfile): ?>
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="<?php print_unescaped($jsfile); ?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<?php emit_script_loading_tags($_); ?>
|
||||
<?php print_unescaped($_['headers']); ?>
|
||||
</head>
|
||||
<body id="body-public">
|
||||
|
|
|
@ -13,20 +13,13 @@
|
|||
<link rel="icon" href="<?php print_unescaped(image_path('', 'favicon.ico')); /* IE11+ supports png */ ?>">
|
||||
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path('', 'favicon-touch.png')); ?>">
|
||||
<link rel="mask-icon" sizes="any" href="<?php print_unescaped(image_path('', 'favicon-mask.svg')); ?>" color="<?php p($theme->getColorPrimary()); ?>">
|
||||
<?php if (isset($_['inline_ocjs'])): ?>
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" type="text/javascript">
|
||||
<?php print_unescaped($_['inline_ocjs']); ?>
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php foreach($_['cssfiles'] as $cssfile): ?>
|
||||
<link rel="stylesheet" href="<?php print_unescaped($cssfile); ?>">
|
||||
<?php endforeach; ?>
|
||||
<?php foreach($_['printcssfiles'] as $cssfile): ?>
|
||||
<link rel="stylesheet" href="<?php print_unescaped($cssfile); ?>" media="print">
|
||||
<?php endforeach; ?>
|
||||
<?php foreach($_['jsfiles'] as $jsfile): ?>
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="<?php print_unescaped($jsfile); ?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<?php emit_script_loading_tags($_); ?>
|
||||
<?php print_unescaped($_['headers']); ?>
|
||||
</head>
|
||||
<body id="<?php p($_['bodyid']);?>">
|
||||
|
|
|
@ -21,20 +21,13 @@
|
|||
<link rel="apple-touch-icon-precomposed" href="<?php print_unescaped(image_path($_['appid'], 'favicon-touch.png')); ?>">
|
||||
<link rel="mask-icon" sizes="any" href="<?php print_unescaped(image_path($_['appid'], 'favicon-mask.svg')); ?>" color="<?php p($theme->getColorPrimary()); ?>">
|
||||
<link rel="manifest" href="<?php print_unescaped(image_path($_['appid'], 'manifest.json')); ?>">
|
||||
<?php if (isset($_['inline_ocjs'])): ?>
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" type="text/javascript">
|
||||
<?php print_unescaped($_['inline_ocjs']); ?>
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
<?php foreach($_['cssfiles'] as $cssfile): ?>
|
||||
<link rel="stylesheet" href="<?php print_unescaped($cssfile); ?>">
|
||||
<?php endforeach; ?>
|
||||
<?php foreach($_['printcssfiles'] as $cssfile): ?>
|
||||
<link rel="stylesheet" href="<?php print_unescaped($cssfile); ?>" media="print">
|
||||
<?php endforeach; ?>
|
||||
<?php foreach($_['jsfiles'] as $jsfile): ?>
|
||||
<script nonce="<?php p(\OC::$server->getContentSecurityPolicyNonceManager()->getNonce()) ?>" src="<?php print_unescaped($jsfile); ?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<?php emit_script_loading_tags($_); ?>
|
||||
<?php print_unescaped($_['headers']); ?>
|
||||
</head>
|
||||
<body id="<?php p($_['bodyid']);?>">
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@statuscode.ch>
|
||||
* @author Michael Letzgus <develope@michael-letzgus.de>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Raghu Nayyar <hey@raghunayyar.com>
|
||||
* @author Robin Appelman <robin@icewind.nl>
|
||||
|
@ -208,6 +209,9 @@ class OC_Template extends \OC\Template\Base {
|
|||
$headers = '';
|
||||
foreach(OC_Util::$headers as $header) {
|
||||
$headers .= '<'.\OCP\Util::sanitizeHTML($header['tag']);
|
||||
if ( strcasecmp($header['tag'], 'script') === 0 && in_array('src', array_map('strtolower', array_keys($header['attributes']))) ) {
|
||||
$headers .= ' defer';
|
||||
}
|
||||
foreach($header['attributes'] as $name=>$value) {
|
||||
$headers .= ' '.\OCP\Util::sanitizeHTML($name).'="'.\OCP\Util::sanitizeHTML($value).'"';
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Lukas Reschke <lukas@statuscode.ch>
|
||||
* @author Michael Letzgus <develope@michael-letzgus.de>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
|
@ -37,6 +38,42 @@ function p($string) {
|
|||
print(\OCP\Util::sanitizeHTML($string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a <script> tag with nonce and defer depending on config
|
||||
* @param string $src the source URL, ignored when empty
|
||||
* @param string $script_content the inline script content, ignored when empty
|
||||
* @param bool $defer_flag deferred loading or not
|
||||
*/
|
||||
function emit_script_tag($src, $script_content) {
|
||||
$defer_str=' defer';
|
||||
$s='<script nonce="' . \OC::$server->getContentSecurityPolicyNonceManager()->getNonce() . '"';
|
||||
if (!empty($src)) {
|
||||
// emit script tag for deferred loading from $src
|
||||
$s.=$defer_str.' src="' . $src .'">';
|
||||
} else if (!empty($script_content)) {
|
||||
// emit script tag for inline script from $script_content without defer (see MDN)
|
||||
$s.=">\n".$script_content."\n";
|
||||
} else {
|
||||
// no $src nor $src_content, really useless empty tag
|
||||
$s.='>';
|
||||
}
|
||||
$s.='</script>';
|
||||
print_unescaped($s."\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Print all <script> tags for loading JS
|
||||
* @param hash $obj all the script information from template
|
||||
*/
|
||||
function emit_script_loading_tags($obj) {
|
||||
if (!empty($obj['inline_ocjs'])) {
|
||||
emit_script_tag('', $obj['inline_ocjs']);
|
||||
}
|
||||
foreach($obj['jsfiles'] as $jsfile) {
|
||||
emit_script_tag($jsfile, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an unsanitized string - usage of this function may result into XSS.
|
||||
* Consider using p() instead.
|
||||
|
|
Loading…
Reference in a new issue