script、link标签详解

关键词:异步加载脚本、MIME、Preload、内容安全策略

<script>标签

    <script type="application/javascript" src="" defer></script>
    <script type="application/javascript" src="" sync></script>
复制代码
  1. async="async" 异步执行脚本
  2. defer="defer" 脚本在页面完成解析时执行。 如果不使用async、defer,在浏览器继续解析之前会立即读取并执行脚本
  3. type="MIME-type" 规定脚本的MIME类型

MIME

MIME 描述消息内容类型的因特网标准。MIME类型就是设定某种扩展名的文件用哪种应用程序来打开的方式类型。浏览器通常使用MIME类型而不是文件扩展名来确定如何处理文档。

MIME类型由两部分组成:媒介类型和子类型。

媒介类型描述
text表示文件是普通文本, text/plain, text/javascript, text/css, text/html
image图像,包括动图, image/gif, image/png, image/x-icon
audio音频文件, audio/midi, audio/ogg, audio/wav
video视频文件, video/webm, video/ogg
application表明是某种二进制文件, application/octet-stream, application/xml, application/javascript
multipart复合文件类型, multipart/form-data, multipart/byteranges

所有的text javascript类型已经被废弃,推荐使用application/JavaScript

<link>标签

在HTML中,<link>标签没有结束标签。rel属性用于定义当前文档与被链接文档之间的关系。

参考链接:

关于Preload, 你应该知道些什么?
Link Preload 标签
深入研究Chrome:Preload与Prefetch原理,及其优先级

dns-prefetch

DNS Prefetch 是一种 DNS 预解析技术。当你浏览网页时,浏览器会在加载网页时对网页中的域名进行解析缓存,这样在你单击当前网页中的连接时就无需进行 DNS 的解析,减少用户等待时间,提高用户体验。

<!-- off为关闭,ON为开启 -->
<meta http-equiv="X-dns-prefetch-control" content="on" />
<link rel="dns-prefetch">
复制代码

Prefetch

<link rel="prefetch" as="script" href="example.js">
复制代码

当确定网页在未来(下一页)一定会使用某资源时,可以通过prefetch提前请求资源并且缓存以供后续使用。但具体什么时候请求这个资源由浏览器决定。 页面跳转时prefetch发起的请求不会中断。该方法的加载优先级很低,一般用来提高下一个页面的加载速度。

Preload

Preload是一项新的web标准,旨在提高性能和为开发人员提供更细粒度的加载控制。Preload可以让开发者自定义资源的加载逻辑,且无需忍受基于脚本的资源加载器带来的性能损失。 preload是声明式的fetch,可以强制浏览器请求资源,同时不阻塞文档onload事件

对于当前页面有必要的资源使用preload,对于可能在将来的页面中使用的资源使用prefetchpreloadprefetch请求的资源都缓存在HTTP缓存中。

link标签不需要关闭

声明式获取指令 declarative fetch directive

<link rel="preload" as="script" href="example.js">
复制代码

onload

Preload支持onload事件,可以自定义资源加载完后的回调函数。

<link rel="proload" href="test.js" as="script" onload="console.log('finish');">
复制代码

as

preload的as属性,告诉浏览器加载的是什么资源。常用的as属性值有:

script, style, image, media, document, font

通过设置as属性可以实现:

  • 浏览器可以设置正确的资源加载优先级
  • 浏览器可以确保请求是符合内容安全策略
  • 浏览器根据as的值发送正确的accept头部信息
  • 浏览器根据as的值得知资源类型。因此当获取的资源相同时,浏览器能够判断前面获取的资源能否重用。

忽略as或者设置错误的值会使preload等同于XHR异步请求。但浏览器不知道加载的是什么,会赋予此类资源非常低的加载优先级。

预加载器 Preloader

令牌化阶段tokenization : 输出对HTML对早期解析结果

预加载器Preloader : 找到包含资源的标签,将这些资源的URL收集起来

读取器fetcher:根据这些资源对页面加载速度的影响进行有序的加载

preload的常用用法:

peoload的主要用途是提前加载资源,在需要的时候直接执行,将加载和执行分开。

  1. 使用preload动态加载js脚本,但是不立即执行,之后再通过<script>执行脚本
// 预先加载脚本
var link = document.createElement('link');
link.rel = 'preload';
link.as = 'script';
link.href = 'myscript.js';
document.head.appendChild(link);

// 执行脚本
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'myscript.js';
document.body.appendChild(script);

复制代码
  1. 提前加载字体,解决字体图标闪的问题
<link rel="preload" as="font" type="font/woff" href="myfont.woff" crossorigin>
复制代码

一定要加crossorigin,即使同源

  1. 基于标记语言的异步加载

<script async></script>可以实现异步加载,但是会阻塞window的onload事件。可以通过preload的onload事件实现资源的异步加载。先用link preload加载资源到本地,资源加载完后通过onload事件设置回调,使用资源或执行脚本。

异步记载样式文件

<link rel="preload" as="style" href="async_style.css" onload="this.rel='stylesheet';">
复制代码

异步加载js脚本

<link rel="preload" as="script" href="async_script.js" onload="
    var script = document.createElement('script');
    script.src = this.href;
    document.body.appendChild(script);
">
复制代码

兼容性

判断浏览器是否支持preload

var DOMTokenListSupports = function(tokenList, token) {
  if (!tokenList || !tokenList.supports) {
    return;
  }
  try {
    return tokenList.supports(token);
  } catch (e) {
    if (e instanceof TypeError) {
      console.log("The DOMTokenList doesn't have a supported tokens list");
    } else {
      console.error("That shouldn't have happened");
    }
  }
};

var linkSupportsPreload = DOMTokenListSupports(document.createElement("link").relList, "preload");
if (!linkSupportsPreload) {
  // Dynamically load the things that relied on preload.
}
复制代码

内容安全策略 Content-Security-Policy

网站通过发送csp头部,告诉浏览器什么是被授权执行的,什么是被禁止的。CSP被称为解决XSS攻击的神器,可以解决潜在的跨站脚本安全问题。 Content-Security-Policy 配置并启用后,不符合csp的外部资源会被阻止加载。

CSP的使用方式:

  1. 在HTTP Header上使用
"Content-Security-Policy": 策略
复制代码
  1. HTML 标签上使用
<meta http-equiv="Content-Security-Policy" content="策略">
复制代码

两个同时存在的话,优先采用HTTP头部设置的策略。

策略由一个或多个CSP指令组成,多个指令之间用英文分号分隔,多个指令值之间用空格分隔。

常用的CSP指令、值:

CSP指令描述
default-src默认加载策略
script-src对于JavaScript脚本的加载策略
style-src对于样式的加载策略
img-src图片的加载策略
object-src显示插件来源,如flash
frame-src
media-src
report-uri请求资源不被允许时,向该地址提交日志
CSP指令值描述
*允许任何内容
'none'不允许加载任何内容
'self'允许来自相同源的资源
data:允许data:协议,如base64编码的图片
www.host.com允许加载指定域名的资源
unsafe-inline允许加载inline资源,如style属性,inline css, inline js
unsafe-eval允许加载动态js代码
Content-Security-Policy: default-src 'self'

Content-Security-Policy: default-src http://host.com https://aaa.com; frame-src 'none'; object-src 'none'

复制代码

转载于:https://juejin.im/post/5c2059eef265da61672053f6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>