# script
# script integrity
防止篡改远程CDN脚本,可以通过链接 (opens new window) 生成hash值。
<script src="https://unpkg.com/vue@3.0.5/dist/vue.global.js"
integrity="sha384-0k9//QJdpmfSdp5IK3oJjOYPfz42f2FE0goMLtK9Vq7aKllvc4Lnz7lHPHiFhvDP"
crossorigin="anonymous">
</script>
# script crossorigin
这个crossorigin属性是可有可无的。它的主要功用就是:影响页面里面,是否可以通过onerror捕获远程js代码的详细报错信息。所以,如果对于显示报错信息的事情无感的话,就不用纠结于是不是添加这个属性。
首先呢,如果你接受crossorigin属性的存在,就必须知晓它的使用方式:
- 使用file://协议打开的时候,该属性不生效。必须放在www容器内,使用http(s)😕/进行浏览,才有效果。也就是说,别双击html文件就进行调试了。
- 这个crossorigin是用在远程跨域js文件上面的,也就是说:如果js文件根本就和html是相同的域控制下的话,这个crossorigin属性也是无效的。
- 远程js文件,必须配置header头信息Access-Control-Allow-Origin。
window.onerror = function(...args){
console.log(args);
return true;
}
只有当网页域名和要载入的静态文件存放的站点域名不一样的时候,使用这两个属性才有意义(并且因浏览器的规定 crossorigin 属性只有这个时候才能正常使用)。
# script defer和async
- 什么时候应该使用什么?
- 如果脚本是模块化的并且不依赖任何脚本,则使用async.
- 如果脚本依赖或被另一个脚本依赖,则使用defer.
- 如果脚本很小并且被脚本所依赖,async那么使用内联script,在脚本上方没有放置属性async。
- 也就是说async是乱序的,而defer是顺序执行,这也就决定了async比较适用于谷歌分析这类不依赖其他脚本的库。
- 支持 IE9 及以下版本在其实现中存在一些非常糟糕的错误,defer因此无法保证执行顺序。如果您需要支持 <= IE9,完全不要使用defer,并且如果执行顺序很重要,则包含没有属性的脚本。
HTML的规范中指明defer属性的脚本是异步下载的,等到页面解析完成后按顺序执行,但是实际上浏览器并不保证顺序执行,所以页面中多个脚本有依赖关系的不要使用defer,平时最好只设置
一个defer脚本
# link预加载preload
<link> 元素的 rel 属性的属性值preload能够让你在你的HTML页面中 <head>元素内部书写一些声明式的资源获取请求,可以指明哪些资源是在页面加载完成后即刻需要的。对于这种即刻需要的资源,你可能希望在页面加载的生命周期的早期阶段就开始获取,在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。
利用link标签配合media等选择性加载图片,实现预加载,等需要的时候使用。
preload 还有许多其他好处。使用 as 来指定将要预加载的内容的类型,将使得浏览器能够:
- 更精确地优化资源加载优先级。
- 匹配未来的加载需求,在适当的情况下,重复利用同一资源。
- 为资源应用正确的内容安全策略。
- 为资源设置正确的Accept 请求头。
- 如果对所 preload 的资源不使用明确的 “as” 属性,将会导致二次获取
- 对跨域的文件进行preload时,必须加上 crossorigin 属性
<link rel="preload" as="font" crossorigin href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff">
哪些类型的内容可以被预加载?
许多不同类型的内容都可以被预加载,一些主要可用的as 属性值列举如下:
audio: 音频文件。
document: 一个将要被嵌入到<frame>或<iframe>内部的HTML文档。
embed: 一个将要被嵌入到<embed>元素内部的资源。
fetch:那些将要通过fetch和XHR请求来获取的资源,比如一个ArrayBuffer或JSON文件。
font: 字体文件。
image:图片文件。
object: 一个将会被嵌入到<embed>元素内的文件。
script: JavaScript文件。
style: 样式表。
track: WebVTT文件。
worker: 一个JavaScript的web worker或shared worker。
video: 视频文件。
<head>
<meta charset="utf-8">
<title>Responsive preload example</title>
<link rel="preload" href="t1.jpg" as="image" media="(max-width: 600px)">
<link rel="preload" href="t2.jpg" as="image" media="(min-width: 601px)">
<style type="text/css">
header{
width:500px;
height:500px;
}
</style>
</head>
<body>
<header>
<h1>My site</h1>
</header>
<script>
var mediaQueryList = window.matchMedia("(max-width: 600px)");
var header = document.querySelector('header');
console.log(mediaQueryList.matches)
setTimeout(()=>{
if(mediaQueryList.matches) {
header.style.backgroundImage = 'url("t1.jpg")';
} else {
header.style.backgroundImage = 'url("t2.jpg")';
}
},3000)
</script>
</body>
# 脚本化与预加载
var preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);
这意味着浏览器将预加载这个JavaScript文件,但并不实际执行它。
如果要对其加以执行,在需要的时候,可以执行:
var preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
// preloadedScript.async =false //注意浏览器的兼容性:有的不支持async属性,所以如果要统一行为的话,可以加上
document.body.appendChild(preloadedScript);
# link使用prefetch
它的作用是告诉浏览器加载下一页面可能会用到的资源,注意,是下一页面,而不是当前页面。因此该方法的加载优先级非常低,也就是说该方式的作用是加速下一个页面的加载速度
<link rel="preload" href="./manifest.js" as="script">
<link rel="preload" href="./vendor.js" as="script">
<link rel="preload" href="./app.js" as="script">
<link rel="prefetch" href="./vendor-async.js">
<link rel="prefetch" href="./user.js">
<link rel="prefetch" href="./comment.js">
<link rel="prefetch" href="./category.js">
<link rel="prefetch" href="./post.js">
<link rel="prefetch" href="./home.js">
preload 和 prefetch 混用的话,并不会复用资源,而是会 重复加载
<link rel="preload" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font">
<link rel="prefetch" href="https://at.alicdn.com/t/font_zck90zmlh7hf47vi.woff" as="font">