一文解决async defer prefetch preload @import link:media dns-prefetch (下)

如果将async defer prefetch preload @import link:media dns-prefetch称之为对html文件的配置,那么这些配置对于初学者来说很难理解的,本文分为上下两个部分对这些概念进行分析,力求做到简单易懂。

4.7 测试7:使用preload利用空闲时间加载资源

首先这个"利用空闲"就已经明白的说出了这种做法是不阻塞的!

将index.html修改成如下所示:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="preload" href="http://localhost:3000/fast" as="script">
</head>
<body>
    <h1>我出现了!</h1>
    <button id="btn">点我翻页</button>
    <script>
        const btn = document.getElementById('btn');
        const o = document.createElement('script');
        o.src = "http://localhost:3000/fast";
        btn.addEventListener('click', ()=>{
            document.body.append(o);
        })
    </script>
</body>
</html>

需要注意的事情是:link中的as="script"一定要写,否则的话就不会起到任何作用!

在点击按钮之前,控制台中不会打印任何内容,网络面板所示为:

注意这里的优先级是:

而在点击了按钮之后立马打印出fast

此时网络面板中并没有任何变化!

对比prefetch,可以发现,prefetch不一定要写as但是preload一定需要!

此外注意fast资源的图标,在prefetch加载完资源之后是空白的,而preload是由icon的,这就是为什么它非要指定资源的类型了;并且preload完成之后其响应和预览中是有值的。

4.8 测试8:验证浏览器请求css资源是采用并发的方式

请求两个css,名字分别为2.css和3.css,表示它们的耗时分别为2s和3s。 touch 2.css 3.css

css 复制代码
:root{
    color:pink;
}

:root{
    background-color:pink;
}

然后修改后端服务器,增加两条路由,如下所示:

js 复制代码
app.get('/2',(req,res)=>{
    res.setHeader('Connection', 'close');
    setTimeout( () => {
        const fileContent = fs.readFileSync(path.join(__dirname, './2.css'));
        res.end(fileContent);  
    } , 2000)
})

app.get('/3',(req,res)=>{
    res.setHeader('Connection', 'close');
    setTimeout( () => {
        const fileContent = fs.readFileSync(path.join(__dirname, './3.css'));
        res.end(fileContent);  
    } , 3000)
})

然后修改index.html中的内容如下所示:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/2">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/3">
</head>
<body>
    <h1>我出现了!</h1>
</body>
</html>

打开index.html发现:

而对应的:

完成用时:3.02 秒

DOMContentLoaded:3.02 秒

加载时间:3.02 秒

所以起码在这个时候请求css是并发的。

接下来展示一下使用@import的不好之处:

修改3.css为:

css 复制代码
@import url('http://localhost:3000/2');

:root{
    background-color:pink;
}

修改index.html中的内容为:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/3">
</head>
<body>
    <h1>我出现了!</h1>
</body>
</html>

此时打开index.html,网络面板中的显示内容为:

完成用时:5.02 秒

DOMContentLoaded:5.02 秒

加载时间:5.02 秒

也就是说并行变成了串行,这肯定是有问题的!所以@import不被使用的原因也就在此了!

4.9 测试9:浏览器并发数目确定

修改index.html的内容为:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/2">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/3">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/4">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/5">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/6">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/7">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/8">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/9">
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/10">
</head>
<body>
    <h1>我出现了!</h1>
</body>
</html>

然后在后端增加相应的路由

也不必增加对应的css文件了,让这些不同的路由指向相同的css文件也是可以的!

打开index.html发现:

也就是说排队的有三个,所以此时最大的并发请求数目为6个!

4.10 测试10:css的懒加载,使用media字段

在使用link加载css文件的时候,使用media字段来实现具体情景下才加载css的效果,将index.html改写为:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="http://localhost:3000/3" media="(max-width:40em)">
</head>
<body>
    <h1>我出现了!</h1>
</body>
</html>

将浏览器最大化,然后访问index.html,网络面板如图所示:

完成用时:3.04 秒

DOMContentLoaded:40 毫秒

加载时间:3.04 秒

然后将浏览器最小化,再访问index.html:

居然是最高!

完成用时:3.03 秒

DOMContentLoaded:3.01 秒

加载时间:3.02 秒

于是得出结论:使用了media字段之后的link标签可以根据media所设定的条件来改变此资源的优先级,以及是否阻塞DOM的渲染!

不仅如此,media字段还会让浏览器在宽度大于40em和小于40em的时候表现出不同的样式!拖拽改变窗口的大小就能够看到这种变化了!

4.11 测试11:dns预加载

首先要知道本机的hosts文件在哪里,这样的话就可以捏造一个域名,强行开启dns解析:hosts文件的位置在C:\Windows\System32\drivers\etc,打开这个文件,并在最后一行追加:

127.0.0.1 supx

然后以管理员身份保存此文件。

接下来访问http://supx:8800看能否成功,成功的话则说明已经配置成功了。

然后就是如何清除dns缓存,清除了才能够让浏览器每一次都发起dns解析:

正确的做法是:ctrl+shift+delete清除缓存,然后ctrl+shift+R强制刷新页面,这样就可以将浏览器缓存的dns清除了。

然后改变index.html文件内容如下所示:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="http://localh<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- <link rel="stylesheet" type="text/css" href="http://supcon:3000/3" media="(max-width:40em)"> -->
    <link rel="dns-prefetch" href="http://supcon">
</head>
<body>
    <h1>我出现了!</h1>
    <button id="btn">点我添加样式</button>
    <script>
        const btn = document.getElementById('btn');
        const lk = document.createElement('link');
        lk.rel = "stylesheet";
        lk.type = "text/css";
        lk.href = "http://supcon:3000/3";
        lk.media = "(max-width:40em)";
        btn.addEventListener('click', ()=>{
            document.head.append(lk);
        })
    </script>
</body>
</html>
<body>
    <h1>我出现了!</h1>
</body>
</html>

打开index.html然后等待一秒,点击按钮,网络面板上的信息如下:

可以看到dns解析过程只占用了5微秒;

然后删除dns预解析:
<link rel="dns-prefetch" href="http://supcon">

清除dns缓存之后,做相同的操作,效果为:

这时不要被它的比例迷惑了,这次整整用了61毫秒!

所以dns-prefetch显然是有效的!但是这5微秒也说明了,即使使用dns-prefetch在这个事情上还是要花费时间的。

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax