js和css引入位置(实例详解)

前端这点事 31 0

刚做前端的时候,就被前辈指导过,css要放在head标签里面,js放在body里面且在最底部最好,前面两篇系统学习了下浏览器的工作原理之后,用实战代码看下,为什么要这么做。

1、写个简单node服务,目的就是控制http请求在请求某个文件的时候,控制response返回的时长,代码如下:

const app = require('express')()
const port = 9999;
const fs = require('fs');
app.get('*', function(req, res) {
    const { url } = req
    switch (url) {
        case '/':
            fs.readFile('./index.html', 'utf-8', function(err, data) {
                res.writeHead(200, { 'Content-Type': 'text/html' })
                res.write(data)
                res.end()
            })
            break;
        case '/1.js':
            //延迟 2s
            fs.readFile("./1.js", "utf-8", function(err, data) {
                res.writeHead(200, { 'Content-Type': 'text/plain' });
                setTimeout(function() {
                    res.write(data);
                    res.end();
                }, 2000);
            })
            break;
        case '/1.css':
            //延迟 15s
            fs.readFile("./1.css", "utf-8", function(err, data) {
                res.writeHead(200, { 'Content-Type': 'text/css' });
                setTimeout(function() {
                    res.write(data);
                    res.end();
                }, 15000);
            })
            break;
    }
})

app.listen(port)

2、同级目录下,新建index.html文件,用于请求http://localhost:9999 端口时静态页面输出,html链接上了css、js文件,那么就会向我们的node server发送http请求,通过控制返回的文件时长和页面效果,

分析css、js文件引入的位置和区别,代码如下:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta http-equiv="cache-control" content="no-cache,no-store, must-revalidate" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>浏览器渲染demo</title>
</head>

<body>
    <link rel="stylesheet" href="./1.css">
    <div id="div">dom渲染被阻塞了</div>
    <div>
        图片渲染被阻塞了
        <img src="https://www.runoob.com/wp-content/uploads/2013/10/bs.png">
    </div>
    <script src="./1.js"></script>
</body>

</html>

3、css和js代码如下:

html,
body {
    background: gray;
}
const div = document.getElementById('div');
alert(div);

接下来,先看下css加载时间过长对html页面渲染的影响。

css返回设置15s,js设置成2s,node server.js 访问http://localhost:9999 发现

清楚看到,页面无任何展示,js已经下载完毕,但是并没有执行,但是资源文件会并发的下载,所以,结论是,css会影响html渲染和js执行,过了15s以后,效果如下

js正常执行了。

接着代码稍作改动,我们把js放在head部分延迟10s获取,css放在js后面无任何延迟,看下效果:

可以看到,页面资源不受影响,全部下载了下来,但是页面并没有任何展示,所以,可以看出js影响到了css的渲染,即使css很早之前就已经下载下来了,所以得到结论就是:

 

1:因为CSS解析和DOM解析可以同时进行,所以CSS资源放在头部不会影响DOM解析,而且放在头部也会优先开始加载CSS样式,在渲染DOM的时候也已经知道了自己的样式,所以一次就可渲染成功,如果将CSS放在底部,那么会优先渲染DOM,而浏览器为了更好的用户体验,渲染引擎会尝试尽快在屏幕上显示内容,也就是说渲染引擎会边解析、边渲染、边布局显示,已尽快减少白屏时间,所以随着CSS规则树的构建,还需要对之前渲染树重新渲染,可能会导致回流和页面跳动。

 

2:JS放在body标签结束之前,首先可以确保能取到需要操作的DOM对象,也可缩短因JS阻塞。而造成的白屏时间,提升用户体验。因为如果把JS放在head部分,JS运行会阻塞DOM树和CSS树构建,导致白屏时间延长,影响用户体验。

 

3:因为JS在运行时,如果需要操作CSS,但该CSS还没有下载和构建,则首先会阻塞JS线程,然后开启新线程去下载解析构建CSS规则树,再执行JS代码

 

下面放下代码仓库。有兴趣的可以自己跑一下,还是很有意思的~~

 

https://github.com/zzxiexin/css-js-load

标签: 技术分享

发表评论 (已有0条评论)

还木有评论哦,快来抢沙发吧~