zoukankan      html  css  js  c++  java
  • 异步加载CSS

    说到加载 CSS 这种事儿不是很简单吗?像这样咯:

    <link rel="stylesheet" href="cssfile.css">

    这不就完事儿了嘛!

    这样是没错!但是这样有问题啊——会阻塞渲染!浏览器看到这个标签就会停下手里的活儿,去加载 CSS 并解析了。

    当然了,如果这个 CSS 文件是接下来要渲染的内容所需的,那无可厚非,必须先要有了这个 CSS 才能接着渲染,阻塞也是情理之中。

    但实际的情况却是,我们很多 CSS 内容其实在首屏的时候是不需要,起码等到后续才会使用,那么这个时候这些 CSS 这样加载去阻塞内容渲染就不对了。

    也就是说,针对优先级不那么高的(暂时用不到)CSS,就应该要想办法让它异步加载,不要阻塞浏览器渲染。

    那么怎么弄呢?

    老方子

    现在介绍第一种老办法:通过 JS 动态插入 link 标签来异步载入 CSS 代码,就像这样:

    var myCSS = document.createElement( "link" );
    myCSS.rel = "stylesheet";
    myCSS.href = "mystyles.css";
    document.head.insertBefore( myCSS, document.head.childNodes[ document.head.childNodes.length - 1 ].nextSibling );

    这个很好理解吧,就是后续 JS 执行的时候,去创建一个 link 标签来加载 CSS 代码。

    还有一个办法呢就是利用 link 上的 media 属性,将它设置为和用户当前浏览器环境不匹配的值,比如:media="print",甚至可以设置为一个完全无效的值 media="jscourse" 之类的。

    这样一来,浏览器就会认为这个 CSS 文件优先级非常低,就会在不阻塞的情况下进行加载。但是为了让 CSS 规则生效,最后还是要将 media 值改对才行。所以,这个办法落实到代码就是这样:

    <link rel="stylesheet" href="cssfile.css" media="jscourse" onload="this.media='all'">

    介绍完了老方子,我们再来看看新药方。

    新的异步加载方式

    新方子就是利用规范中新增加的 rel="preload" ,就像这样:

    <link rel="preload" href="cssfile.css" as="style" onload="this.rel='stylesheet'">

    通过 preload 属性值就是告诉浏览器这个资源文件随后会用到,请提前加载好。但是这只是加载,所以你看当它加载完毕后,还是需要将 rel 值改回去,这才能让 CSS 生效。

    你是不是想问:这和老方子也没多大区别嘛!

    看上去确实如此,但是呢,语义上更加好一些。另外就是你仔细点就会发现 as="style"这个属性,所以 preload 不仅仅可以用在 CSS 文件上,而是可以用在绝大多数的资源文件上。比如:JS 文件

    <link rel="preload" href="scriptfile.js" as="script">

    然后要用的时候,就创建一个 script 标签指向它:

    var script = document.createElement("script");
    script.src = "scriptfile.js";
    document.body.appendChild(script);

    这个时候浏览器就直接从缓存中拿这个文件了,不会再发请求了,因为此前已经加载好了。

    那么 preload 中的 as 属性支持哪些资源文件呢?下面这些都可以:

    • audio
    • document
    • embed
    • fetch
    • font
    • image
    • object
    • script
    • style
    • track
    • worker
    • video

    是不是迫不及待想去试试了?告诉你个坏消息,目前 preload 只有 Chrome 是完美支持的,其他浏览器惨不忍睹,哎!

  • 相关阅读:
    mysql ndb笔记
    oracle asmlib下载地址
    mysqldump
    mysqlsrlib
    AFDownloadRequestOperation
    [iphone]Code Sign error: Provisioning profile XXXX can"t be found
    cocos2d粒子效果
    如何以最好的方式实现游戏关卡
    关于autorelease pool一个较好的理解
    cocos2d场景转换的方法执行顺序
  • 原文地址:https://www.cnblogs.com/cjx-work/p/8133858.html
Copyright © 2011-2022 走看看