刚做前端的时候,就被前辈指导过,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
标签: 技术分享
还木有评论哦,快来抢沙发吧~