使用内容安全策略(CSP)的页面特定JavaScript

时间:2017-04-26 07:29:16

标签: javascript html performance bundling-and-minification content-security-policy

我想在整个网站上使用Content Security Policy (CSP)。这要求所有JavaScript都在单独的文件中。我共享了所有页面使用的JavaScript,但还有一些特定于页面的JavaScript,我只想为特定页面运行。处理特定于页面的JavaScript以获得最佳性能的最佳方法是什么?

我可以想到解决此问题的两种方法是使用特定于页面的JavaScript包或带有switch语句的单个JavaScript包来执行特定于页面的内容。

2 个答案:

答案 0 :(得分:2)

很抱歉,我知道这最终会被长时间阅读,但这样做是值得的,因为您可以做出适合您网站的选择。对于tl; dr,请阅读每个段落的第一句话。

首先,无论您选择哪种路由,都应该将每个页面的所有JS公共文件放在同一个文件中,以便最大限度地利用缓存。这只是常识。此外,在所有情况下,我认为你使用的是一个称职的minifier,因为这将产生比其他任何东西更大的差异。如果您需要其中一个,也可以使用打包商 - 如果您需要其中任何一个,Google就是您的朋友。

对于特定于页面的JS,您应该确定将第一个页面加载(用户与您网站的第一次联系)加载是否最重要,或者是否最重要的是加载以下页面(用户与任何给定页面的第一次联系)为“快速”。现在,现代浏览器缓存非常好,因此您可以随时依赖缓存中的浏览器加载。一般来说,如果第一页加载最快是最重要的,那么创建单独的JS文件(这样,用户在访问你的站点之前就不会停止下载10 MB的数据)。如果没有,那么将所有JS放在同一个文件中,请记住,如果一个页面的JS比其他页面明显多,那么会对您网站上每个页面的加载时间产生负面影响。请注意,使用asyncdefer标记可以减少此额外加载时间,稍后会详细介绍。

考虑这样的情况:页面A有5 KB的JS,而页面B有5 MB的JS。如果将两个脚本放在同一个文件中,页面A的加载速度会更慢(因为它需要加载~5 MB的JS),但由于JS文件已被缓存,因此页面B的加载速度会快得多。如果将它们分开,页面A的加载速度将比页面B快得多,但与第一种情况相比,平均速度会降低。 如果一个页面的JS没有明显多于另一个页面,请使用单独的文件。您将遇到更好的平均加载时间,因为提前加载大文件的“节省”将大大减少(您还将避免下面提到的问题)。

另一个考虑因素是其中一个JS文件是否会经常更改,因为这会使缓存版本无效并需要浏览器重新下载它。如果您将所有JS放在一起并且只有一个文件是易失性的(尤其是,如果它不是经常访问的页面,例如注册页面),则最终用户将面临比平均加载时间更长的时间。如果你把它们分开Stack Overflow本身采用了一种有趣的方法。看起来它们有一个函数来使与页面无关的JS的缓存无效并在页面上的JS加载时加载它(如果需要),以便以后节省加载时间。

还有一件事!除此之外,您还应决定是否应在脚本标记中使用asyncdefer,因为您要完全迁移到“外部”JS。

async允许页面在JS下载完成之前加载并显示给用户。如果您决定使用“一个文件来统治所有”路由,这是隐藏大型JS文件下载的好方法。但是,您可能还会发现需要下载并执行JS才能使页面正常显示(不使用asyncdefer时)。

因此,最好使用这两个建议的混合,并将您的j分成需要每页加载的单个文件,以便页面正确显示(每页一个),然后全部放入没有加载到asyncdefer标记(这是“一个大文件”)的脚本的js。在向用户显示页面后,defer允许浏览器在后台中加载它。

最终,只有您才能做出适合您应用的决策。在所有情况下都没有一个神奇的选择,但这是软件设计/工程的现实。我希望我已经让这个过程更加清晰,所以你可以更容易地找到正确的选择。

答案 1 :(得分:2)

有很多方法可以执行特定于页面的javascript

选项1(通过课程检查)

将类设置为正文标记

<body class="PageClass">

然后通过jQuery检查

$(function(){
  if($('body').hasClass('PageClass')){
    //your code
  }
});

选项2(通过开关案例检查)

var windowLoc = $(location).attr('pathname'); //jquery format to get window.location.pathname

switch (windowLoc) {
    case "/info.php":
        //code here
        break;
    case "/alert.php":
        //code here
        break;
}

选项3通过功能检查

在函数

中创建所有特定于页面的脚本
function homepage() {
    alert('homepage code executed');
}

然后在特定页面上运行功能

homepage();