前端加载技术

参考 

前端性能优化之加载技术 

  关于Preload, 你应该知道些什么?

  Preload,Prefetch 和它们在 Chrome 之中的优先级

对以下文章的补充

  简单汇总了一下web的优化方案

  关于页面加载

图片处理

  预加载,在onload之后动态插入img标签,使浏览器提前缓存该图片

  懒加载,使用onload之后手动设置src,src的值存放在标签的某个属性上即可(如data-x-src),实现策略:滚动监听、节流函数、手动设置src值

模块处理:

  webpack code split

dns预解析

当浏览器真正请求该域中的某个资源时,DNS 的解析就已经完成了

<link rel="dns-prefetch" href="//example.com">

tcp预连接

预先建立 socket 连接,从而消除昂贵的 DNS 查找、TCP 握手和 TLS 往返开销

<link rel="preconnect" href="http://example.com">

资源预获取

优先级低,那就意味着浏览器空闲的时候才会对资源进行获取(但也可能不获取,即被浏览器忽略),可轻松绕过性能瓶颈。下载的资源一般用于将来的页面,而不是当前页面

<link rel="prefetch" href="image.png">

预渲染

会预处理这个页面中所有的资源,慎重使用;确保用户会访问这个链接,才去预渲染,否则可能浪费较多资源(高流量、高cpu)。

<link rel="prerender" href="http://example.com">

应用场景:用户精确搜索出一个结果,那可以预渲染这个页面链接;阅读中,预渲染下一个页面的内容。

prefetch

<link rel=“prefetch”>

  告诉浏览器加载下一页面可能会用到的资源,因为资源是作用于下一个页面,所以优先级很低

preload

<link rel="preload">

  加载的资源作用于当前页面。浏览器可以正确指定优先级,即preload不会影响当前页面重要资源的下载;和prefetch不同的是,prefetch可能会被浏览器忽略,但浏览器必定会响应preload

  有as属性,常用的值有:script、style、image、media、document。忽略as属性的话,preload等同于xhr请求,优先级较低

  资源都是异步下载,不会阻碍window.onload的触发,拥有自己的onload事件(至少对于chrome,prefetch没有onload事件)。注意:script async会阻塞onload

应用场景

  加载字体。因为字体对界面很重要,而且埋在css中,不知道对应的选择器什么时候才会作用到dom节点上,这时候预先加载字体可以提升速度和用户体验(crossorigin 是必须的即使资源没有跨域)

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

  加载资源但不执行。

<link rel="preload" href="late_discovered_thing.js" as="script">
脚本化操作
var preload = document.createElement("link");
link.href = "myscript.js";
link.rel = "preload";
link.as = "script";
document.head.appendChild(link);
  加载后马上执行
<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);">
prefetch用于加载其他页面可能要用到的资源,而preload用于加载这个页面将要用到的资源
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Faster</title>
  <link rel="dns-prefetch" href="//cdn.com/">
  <link rel="preload" href="//js.cdn.com/currentPage-part1.js" as="script">
  <link rel="preload" href="//js.cdn.com/currentPage-part2.js" as="script">
  <link rel="preload" href="//js.cdn.com/currentPage-part3.js" as="script">

  <link rel="prefetch" href="//js.cdn.com/prefetch.js">
</head>
<body>
  <script type="text/javascript" src="//js.cdn.com/currentPage-part1.js" defer></script>
  <script type="text/javascript" src="//js.cdn.com/currentPage-part2.js" defer></script>
  <script type="text/javascript" src="//js.cdn.com/currentPage-part3.js" defer></script>
</body>
</html>

   响应式的加载

<link rel="preload" as="image" href="map.png" media="(max-width: 600px)">
<link rel="preload" as="script" href="map.js" media="(min-width: 601px)">

检查浏览器是否支持preload

参考:https://github.com/w3c/preload/issues/7

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.
}

终极完美的结构

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Faster</title>
  <link rel="dns-prefetch" href="//cdn.cn/">

  <!--预加载当前页面的资源-->
  <link rel="preload" href="//cdn.cn/webfont.woff2" as="font">
  <link rel="preload" href="//cdn.cn/Page1-A.js" as="script">
  <link rel="preload" href="//cdn.cn/Page1-B.js" as="script">
 
  <!--预加载其他页面的js-->
  <link rel="prefetch" href="//cdn.cn/Page2.js">
  <link rel="prefetch" href="//cdn.cn/Page3.js">
  <link rel="prefetch" href="//cdn.cn/Page4.js">

  <style type="text/css">
    /* 首页用到的CSS内联 ,这里用到字体*/
  </style>
</head>
<body>
<script type="text/javascript" src="//cdn.cn/Page1-A.js" defer></script>
<script type="text/javascript" src="//cdn.cn/Page1-B.js" defer></script>
</body>
</html>

posted @ 2017-10-07 16:22  HelloHello233  阅读(1018)  评论(0编辑  收藏  举报