zoukankan      html  css  js  c++  java
  • 天了噜,为什么外链css要放在头部,js要放在尾部?

    (题图:梵高-向日葵)


    我们最开始学前端的时候都会看到教程在处理外部css,js的时候会将css放在header中,js放在body的最后。为什么要这样子处理,今天参考一些资料好好分析下。

    为什么外链css为什么要放头部?

    首先整个页面展示给用户会经过html 的解析与渲染过程。

    外链css无论放在html的任何位置都不影响html的解析,但是影响html的渲染。

    如果将css放在尾部,html的内容可以第一时间显示出来,但是会阻塞html行内css的渲染。

    浏览器的这个策略其实很明智的,想象一下,如果没有这个策略,页面首先会呈现出一个行内css样式,待CSS下载完之后又突然变了一个模样。用户体验可谓极差,而且渲染是有成本的。

    如果将css放在头部,css的下载解析是可以和html的解析同步进行的,放到尾部,要花费额外时间来解析CSS,并且浏览器会先渲染出一个没有样式的页面,等CSS加载完后会再渲染成一个有样式的页面,页面会出现明显的闪动的现象。

    为什么script要放在尾部?

    因为当浏览器解析到script的时候,就会立即下载执行,中断html的解析过程,如果外部脚本加载时间很长(比如一直无法完成下载),就会造成网页长时间失去响应,浏览器就会呈现“假死”状态,这被称为“阻塞效应”。

    具体的流程是这样的:

    1. 浏览器一边下载HTML网页,一边开始解析。
    2. 解析过程中,发现script标签
    3. 暂停解析,网页渲染的控制权转交给JavaScript引擎
    4. 如果script标签引用了外部脚本,就下载该脚本,否则就直接执行
    5. 执行完毕,控制权交还渲染引擎,恢复往下解析HTML网页

    外链的script包含async或者defer如何处理?

    这两个属性只是script标签在header标签中使用的,如果你把它放在body后面是无效的。

    script 的这两个属性主要用于其js文件没有操作DOM的情况,这时候就可以将该js脚本设置为异步加载,通过async或defer来标记代码。

    async和defer的区别:

    0、async和defer都仅对外部脚本有效,对于内置而不是连接外部脚本的script标签,以及动态生成的script标签不起作用。

    1、async和defer虽然都是异步的,不过使用async标志的脚本文件一旦加载完成就会立即执行;而使用defer标记的脚本文件,会在 DOMContentLoaded 事件之前(也就是页面DOM加载完成时)执行。

    2、如果有多个js脚本文件,async标记不保证按照书写的顺序执行,哪个脚本先下载结束,就先执行那个脚本。而defer标记则会按照js脚本书写顺序执行。

    3、一般来说,如果脚本之间没有依赖关系,就使用async属性,如果脚本之间有依赖关系,就使用defer属性。如果同时使用async和defer属性,后者不起作用,浏览器行为由async属性决定。

    对于async标记,浏览器的解析过程是这样的:

    • 浏览器开始解析HTML网页

    • 解析过程中,发现带有async属性的script标签

    • 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本

    • 脚本下载完成,浏览器暂停解析HTML网页,开始执行下载的脚本

    • 脚本执行完毕,浏览器恢复解析HTML网页

    对于defer标记,浏览器的解析过程是这样的:

    • 浏览器开始解析HTML网页

    • 解析过程中,发现带有defer属性的script标签

    • 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本

    • 浏览器完成解析HTML网页,此时再执行下载的脚本

    由于使用了async或defer的script会放在header中,而header又会存在外链css,那么二者有顺序要求吗?

    header中script和外链css的位置顺序

    先说结论:

    如果在html的header中同时有js脚本和外链css,js脚本最好放外链css前面。

    其实js的执行是依赖css样式的。即只有css样式全部下载完成后才会执行js。

    因为如果脚本的内容是获取元素的样式,宽高等CSS控制的属性,浏览器是需要计算的,也就是依赖于CSS。浏览器无法感知脚本内容到底是什么,为避免样式获取错误,因而只好等前面所有的样式下载完后,再执行JS。
    也就是说,如果有外链css,那么js的执行时需要等待外链css下载完


    (added in 20191204)

    根据一些网友的评论与反馈,然后查了一些资料,暂时得出的结论如下:

    由于现代浏览器很聪明会进行 prefetch 优化,就如 Chrome 浏览器,它会在解析 HTML 时收集外链,并在后台并行下载,由于会并行下载,那么head中外链js和css的位置其实就没有什么很大影响了。

    参考链接:

    (啾咪 ^.<)

  • 相关阅读:
    MongoDB 释放磁盘空间 db.runCommand({repairDatabase: 1 })
    RK 调试笔记
    RK Android7.1 拨号
    RK Android7.1 移植gt9271 TP偏移
    RK Android7.1 定制化 itvbox 盒子Launcher
    RK Android7.1 双屏显示旋转方向
    RK Android7.1 设置 内存条作假
    RK Android7.1 设置 蓝牙 已断开连接
    RK Android7.1 进入Camera2 亮度会增加
    RK 3128 调触摸屏 TP GT9XX
  • 原文地址:https://www.cnblogs.com/lvonve/p/14180315.html
Copyright © 2011-2022 走看看