js和css文件位置对页面性能有什么影响?

CSS和JS文件的位置会影响页面效率。js脚本应放在底部,如果放在首部,当下载执行js时,会影响渲染行程绘制页面;而CSS应放在顶部,如果放在底部,页面可以逐步呈现,但在CSS下载并解析完毕后,已经呈现的文字和图片就要需要根据新的样式重绘。

js和css文件位置对页面性能有什么影响?

js脚本文件的位置

js脚本应该放在底部,原因在于js线程与GUI渲染线程是互斥的关系,如果js放在首部,当下载执行js的时候,会影响渲染行程绘制页面,js的作用主要是处理交互,而交互必须得先让页面呈现才能进行,所以为了保证用户体验,尽量让页面先绘制出来。

CSS文件的位置

CSS 是页面渲染的关键因素之一,(当页面存在外链 CSS 时,)浏览器会等待全部的 CSS 下载及解析完成后再渲染页面。关键路径上的任何延迟都会影响首屏时间,因而我们需要尽快地将 CSS 传输到用户的设备,否则,(在页面渲染之前,)用户只能看到一个空白的屏幕。

立即学习“前端免费学习笔记(深入)”;

CSS文件放在顶部一方面是因为放置顺序决定了下载的优先级,更关键的是浏览器的渲染机制。

css在加载过程中不会影响到DOM树的生成,但是会影响到Render树的生成,进而影响到layout,所以一般来说,style的link标签需要尽量放在head里面,因为在解析DOM树的时候是自上而下的,而css样式又是通过异步加载的,这样的话,解析DOM树下的body节点和加载css样式能尽可能的并行,加快Render树的生成的速度。

将CSS放在底部,页面可以逐步呈现,但在CSS下载并解析完毕后,已经呈现的文字和图片就要需要根据新的样式重绘,这是一种不好的用户体验。

js、css等脚本位置对性能的影响

用一句话概括就是: JS 全阻塞,CSS 半阻塞。(词是我发明的,方便记忆而已)

JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载。

CSS 不会阻塞后续 DOM 结构的解析,不会阻塞其它资源(如图片)的加载,但是会阻塞 JS 文件的加载。

现代浏览器很聪明,会进行 prefetch 优化,浏览器在获得 html 文档之后会对页面上引用的资源进行提前下载。(注意仅仅只是提前下载)

下面开始我就一边测试,一边解释上述测试的结果:

测试的浏览器是 Chrome,版本号为 55.0.2883.95 (64-bit)

先用 Nodejs 搭建一个简单 http 服务器:

//test.jsconst http = require('http');const fs = require('fs');const hostname = '127.0.0.1';const port = 9000;http.createServer((req, res) => {    if(req.url === "/") {        fs.readFile("index.html", "utf-8", function(err, data) {            res.writeHead(200, { 'Content-Type': 'text/html' }); res.write(data); res.end();})    }else if(req.url === "/yellow.js") {//延迟 5sfs.readFile("yellow.js", "utf-8", function(err, data) {    res.writeHead(200, { 'Content-Type': 'text/plain' });    setTimeout(function () {    res.write(data);    res.end();    }, 5000);})    }else if(req.url === "/blue.js") {//延迟 10sfs.readFile("blue.js", "utf-8", function(err, data) {    res.writeHead(200, { 'Content-Type': 'text/plain' });    setTimeout(function () {    res.write(data);    res.end();    }, 10000);})    }else if(req.url === "/red.css") {//延迟 15sfs.readFile("red.css", "utf-8", function(err, data) {    res.writeHead(200, { 'Content-Type': 'text/css' });    setTimeout(function () {    res.write(data);    res.end();    }, 15000);})    }else if(req.url === "/green.css") {//延迟 20sfs.readFile("green.css", "utf-8", function(err, data) {    res.writeHead(200, { 'Content-Type': 'text/css' });    setTimeout(function () {    res.write(data);    res.end();    }, 20000);})    }}).listen(port, hostname, () => {  console.log('Server running at ' + hostname);});

登录后复制

首页的代码结构:

//index.html                测试浏览器渲染    

First Line

Second Line

Third Line

Fourth Line

@@##@@

Fifth Line

登录后复制

以及其它 CSS 和 JS 文件:

//yellow.jsdocument.body.style.cssText = "background: yellow !important";//blue.jsdocument.body.style.cssText = "background: blue !important";

登录后复制

//red.cssbody {    background:red !important;}//green.cssbody {    background: green !important;}

登录后复制

说明下:yellow.js 和 blue.js 下载时间分别为 5s 和 10s,red.css 和 green.css 下载时间分别为 15s 和 20s。

之后将所有文件放到同个目录下,在控制台输入 node test.js,打开浏览器访问 127.0.0.1:9000 就可以访问。

先来看第三点结论:现代浏览器很聪明,会进行 prefetch 优化,浏览器在获得 html 文档之后会对页面上引用的资源进行提前下载。(注意仅仅只是提前下载)

js和css文件位置对页面性能有什么影响?

很好理解,从图中可以看出:CSS、JS、图片在浏览器在拿到 html 文档之后会将页面上引用资源几乎同时下载,但具体什么时候执行要看 html 的结构,注意我这里使用的是 Chrome 浏览器,其它浏览器可能会有差别。

还有就是一个奇怪的现象,Chrome 浏览器有时会对 img 进行 prefetch,有时则不会。

接着是第一点规则:

JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载。

1.png

从上图可以看出,当浏览器解析到 yellow.js 这行时候会等待 yellow.js 加载,阻塞后续 DOM 结构的解析(包括 DOM 结构,其他所有资源(CSS, JS, 图片))。

这个很好理解:

JS 运行在浏览器中,是单线程的,每个 window 一个 JS 线程,所以当然会阻塞后续 DOM 树的解析咯。

JS 有可能会修改 DOM 结构,给 DOM 添加样式等等,所以这就意味着在当前 JS 加载执行完成前,后续资源的加载可能是没有意义的。

其次第二点:

CSS 不会阻塞后续 DOM 结构的解析,不会阻塞其它资源(如图片)的加载,但是会阻塞 JS 文件的加载。

这个就相对比较复杂点,让我先上测试结果的图:

2.png

从图中可以得出以下总结:

在加载完 yellow.js 后,当在下载 red.css 时候并不会阻塞 DOM 解析,并且由于第一点规则,当解析到 blue.js 这行的时候,同样会阻塞后续 DOM 解析。

由于我们设置的 red.css 下载时间为 15s 而 blue.js 为 10s,而从前面第三条规则的图中也可以看到,blue.js 在 10s 左右下载完而 red.css 在 15s 左右下载完毕。

最后在 15s 时候页面变为了蓝色,这说明了 CSS 阻塞了 JS 的加载,后续的 JS 文件虽然提前下载完毕了,但还是要等前面 CSS 文件加载完后才能执行。

后续当 blue.js 加载完之后可以看到,green.css 的下载并不会影响到后续 img 的加载,所以说明 CSS 文件下载并不会影响后续图片等其它资源以及 DOM 的加载。

这个也好理解:JS 代码在执行前,浏览器必须保证在 JS 之前的所有 CSS 样式都解析完成,不然不就乱套了,前面的 CSS 样式可能会覆盖 JS 文件中定义的元素样式,这是 CSS 阻塞后续 JS 执行的根本原因。

最后这里说明下为什么最后 body 的背景色没有变成绿色:因为 js 定义的样式在内联样式,优先级高于在 CSS 文件中定义的样式,所以不是 green.css 没有加载,而是没有生效。看下图就知道了:(green 和 red 样式都被划掉了)

3.gif

所以知道了上述的结论之后,我们在开发的时候应该尽可能地:

将样式或 CSS 文件定义在 head 中,并且在处理此类请求的时候应该尽快能够响应(CDN 什么的),如果像上面请求一个 CSS 文件都要 10s 的话,那你这页面估计没多少人有耐心等下去。

将 JS 脚本文件放在 body 底部,让 DOM 结构能优先渲染出来,避免 DOM 被阻塞。

当编写比较耗时的 JS 代码时候尽可能使用异步的方式进行加载,比如 setTimeout, ajax 等等,同样也是为了避免页面渲染耗时过长,影响用户体验。

其他:

上面介绍了 JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载,这是在没有考虑到 defer, async 的情况下。

当浏览器碰到 script 脚本的时候:(不考虑浏览器的 prefetch)

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,当然还得等待前面的 CSS 文件渲染完。

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(下载异步,执行同步)。

有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

从使用的角度来看,首先把脚本丢到 body 底部是比较好的优化选择,此法可保证非脚本的其他一切元素能够以最快的速度得到加载和解析。

上述的三点用图可表示为:

4.png

蓝色线代表网络读取,红色线代表执行时间,这俩都是针对脚本的;绿色线代表 HTML 解析。

总结:

由于现代浏览器都存在 prefetch,所以 defer, async 可能并没有太多的用途,可以作为了解扩展知识,仅仅将脚本文件放到 body 底部就可以起到很不错的优化效果。

defer 和 async 都是异步加载脚本文件。

慎用 async,因为它完全不考虑依赖关系,只要下载完后就加载,不考虑此时页面样式先后的加载顺序,不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google Analytics。

耗时较长的脚本代码可以使用 defer 来推迟执行。

更多编程相关知识,请访问:编程视频!!

5.png

以上就是js和css文件位置对页面性能有什么影响?的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3129249.html

(0)
上一篇 2025年3月30日 05:32:57
下一篇 2025年3月3日 00:24:03

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Html5+JS实现手机摇一摇功能_html5教程技巧

    html5一个重要特性就是deviceorientation,它将底层的方向传感器和运动传感器进行了高级封装,提供了dom事件的支持。这个特性包括两种事件: 1、 deviceOrientation:封装了方向传感器数据的事件,可以获取手机…

    编程技术 2025年3月29日
    100
  • HTML5 audio标签使用js进行播放控制实例_html5教程技巧

    标签可以在html5浏览器中播放音频文件。 默认提供一个控制面板,但是有些时候我们只需要播放声音,控制面板由我们自己来定义其显示的状态。 立即学习“前端免费学习笔记(深入)”; 这里我们可以使用JS来进行控制,代码如下: 复制代码代码如下:…

    编程技术 2025年3月29日
    100
  • Vue.js适合制作移动端的Webapp吗?

    公司有个项目,要做移动的SPA,想要尝试使用Vue.js来制作,但是目前有几点疑问,不确定Vue.js是否适用。1.Vue.js是否适合移动端2.Vue.js做移动端的SPA,转场动画是否有相关的解决方案3.Vue.js是否有适合移动端的组…

    编程技术 2025年3月29日
    100
  • 当前主流HTML5的网页是否依然是以DIV + CSS为基础开发的?

    我是web前端的初学者,希望能够在学习中跟上主流,目前对于HTML和CSS都学习了语法,但考虑到在实际开发一个网站是如何通过这两者来进行的,有些不知所措。在网上搜了下大概都是讲通过DIV + CSS来布局网页的,但这个作为以往网页的开发手段…

    编程技术 2025年3月29日
    100
  • 如何系统的学习做网站?

    作为计算机专业学生,做网站方面只是略懂,在校学生会时改过一些校网站的代码,但从未从无到有的系统的做出一个网站,略懂HTML略懂css div略懂php 略懂cms,但还是想要系统的学一下web开发以达到以下水平:1.自己可以从无到有搭建出一…

    编程技术 2025年3月29日
    100
  • 如何删除多余无用的css?

    项目经过几个版本的迭代,几个css文件加起来都有快6k行了,目测一半都是没用的代码,有没有自动的工具识别并删除这些代码?网上搜了一些,要么就是不好用,要么就是只能搜索出没用的css,不能自动删除的。有没有人有更好的办法? 回复内容: 火狐的…

    编程技术 2025年3月29日
    100
  • 利用gulp实现压缩的实例

    1,下载安装node 访问  ,然后点击大大的绿色的 install 按钮,下载完成后直接运行程序,就一切准备就绪。 npm 会随着安装包一起安装, 2,打开代码行 node -v //查看node版本,如果显示版本号,则安装成功。 npm…

    编程技术 2025年3月29日
    100
  • JavaScript关于数组的方法有哪些不同之处?

    在javascript里,有很多新增,移除,替换数组元素的方法,很多方法都能实现同一个功能,但是他们却有很大的不同之处,今天我们就来对比一下,javascript里的数组方法到底有什么奥秘。 在JavaScript 提供了多种新增,移除,替…

    编程技术 2025年3月29日
    100
  • CSS如何正确命名

    大家都知道css命名有它的规则和方法,那大家都知道有哪些呢?本文主要和大家分享css命名规则和命名方法,希望能帮助到大家。 CSS命名规则   头:header   内容:content/containe   尾:footer 立即学习“前…

    编程技术 2025年3月29日
    100
  • 手机端怎样用rem+scss做适配

    这次给大家带来手机端怎样用rem+scss做适配,手机端做rem+scss适配的注意事项有哪些,下面就是实战案例,一起来看一下。 rem介绍 rem(font size of the root element)是指相对于根元素(即注意事项)…

    编程技术 2025年3月29日
    100

发表回复

登录后才能评论