css和js 在网页中的放置顺序
js在网页的放置顺序
对于外部js的文件放置时,应该全部放在<head>标签内。但是这样的话,意味着必须等着全部的js代码都被下载、解析、执行完成后,才能呈现页面的内容(浏览器在遇到<body>标签时才开始呈现内容)。对于那些需要很多js 的页面来说,这无疑会导致浏览器在呈现页面时出现明显的延迟,而延迟期间的浏览器窗口中将是一片空白,为了避免这个问题,有时候会把外部的js文件放在<body>元素中页面内容的后面。
css在文件中的放置顺序
CSS一般放置在head标签内,要是页面在无CSS渲染的情况下先下载html的话将会面目全非,样式先行的话在加载html内容的时候可以同时渲染样式,避免fouc。
当css样式表和js外部文件同时在head标签中时,css样式表应该放置在js外部文件的上面
白屏和FOUC
当把css样式表放在底部或者使用@import方式引入样式、或将js放在头部造成其他内容阻塞加载时:
一些浏览器例如chrome和ie,它的加载和渲染机制是等头部的js 和底部的CSS全部加载解析完成后再渲染展示页面,而这个等待的时间就是白屏。
另一些浏览器例如firefox,它会在CSS未加载前先展现页面,等CSS加载后再重绘一次,这就造成了无样式内容闪烁(逐步加载无样式的内容,等CSS加载后页面突然展现样式)
解决方法就是在head中运用css样式表。
async和defer的作用及其区别
加载
即获取资源文件的过程,不同的浏览器以及不同的版本在实现这一过程中会有不同的实现效果。
加载过程中遇到外部的CSS文件,浏览器另外发出一个请求来获取CSS文件。
遇到图片资源浏览器也会发出另外的一个请求来获取图片资源这是异步请求,并不会影响html文档进行加载,但是当文档加载过程中遇到js 文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。
延迟脚本
html4.01为<script>标签定义了defer属性,这个属性的用途就是脚本会被 延迟到整个页面都被解析完毕后再运行,因此,defer属性告诉浏览器立即下载但是延迟执行。在现实中,两个延迟脚本的话,不一定按照顺序执行,因此最好只包含一个延迟脚本。
defer属性只适用于外部脚本文件。ie4~ie7还支持对嵌入脚本defer属性的支持,但是ie8及之后的版本则只适用于外部脚本的文件。
在xhtml文档中,要把defer属性设置为defer="defer"。
异步脚本
html5为<script>元素定义了async属性,这个属性与defer属性类似,都用于改变处理脚本的行为。同样与defer类似,async只适用于外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的两个脚本并不保证按照指定的它们的先后顺序执行。第二个脚本可能会在第一个脚本之前执行。指定async属性的目的就是不让页面等待两个脚本下载和执行,从而异步加载页面的其他内容。
简述网页的渲染顺序
如何渲染一个网页
- 在浏览器输入要访问的网页的url;
- 浏览器开始解析url,找寻其所属的协议,主机所在,所用的端口以及对应的路径;
- 浏览器通过进行dns查询将域名转为ip地址;
- 浏览器开启对应的通信端口并与解析出来的ip地址相连(通常会使用80端口);
- 当建立链接后,就会向主机地址发送一个http请求,包含了一些浏览器的基本属性和网页参数等。
- 主机将请求接收并转发给监听对应端口的服务器;
- 服务器解析请求路径,并根据设定的配置将其转交给对应的处理器处理(具体会根据不同语言而有所区别:php,pyhton等)
- 处理器接收请求,并着手准备回应请求;
- 根据具体情况,处理器可能会需要链接数据库获取数据来构建回应的内容(链接数据库-》执行查询-》获取并解析数据-》关闭数据库链接);
- 将所有的数据整合构成回应主体(对于网页而言是html字符串),加上必须要的元信息(http的header),以同样的协议返回给用户的浏览器;
- 浏览器接收回应的内容,根据回应的状态,如果有错误则进行处理,若无则进行解析。
- 浏览器会根据获得的内容(多数情况下为html)生成一个dom树;
- 然后针对其内引用的外部资源逐个发出请求获取,比如图片,样式,js等,此刻重复上述请求步骤;
- 浏览器获得返回的样式后开始解析其内容,将css构建cssom,而根据具体的属性来执行js的解析和执行;
- 针对更新后的dom和cssom,生成render tree即包含了视觉展现信息的树,浏览器根据render tree 来进行渲染,即你看到的页面;
- 根据css来对render tree进行布局、定位,然后再对定位好的部分进行painting,然后你就看到了呈现在你面前的页面。
css和js加载顺序
js
- 默认下,js的加载时同步的,即遇到<script>标签后立刻就会开始解析js,如果js本身是外部资源,则还会先去请求获取后再解析,同时dom的解析也会因此而暂停,一直等待js解析执行后才会继续。
- 对于外部引用的js,开发者可以通过给script标签增加defer属性来使js滞后加载,这样就不会影响到dom的解析了,其也会在dom解析后执行,但这种情况下,务必要保证js中不会用到document.write()这种直接创建dom node的语句;
- 除了defer,h5中新引入了async属性,可以让js 保持异步加载,如此js的解析执行就是在另一个线程中进行了。就和dom的解析互不影响了,当然,同样的,这种情况下,js中也不能有类似document.write()的函数;
- 同时,引擎方面目前也有一定的优化,一般来说,webkit或者firefox所用的引擎都会在执行某个脚本的同时,开启另一个线程继续处理下面的文档并请求所需的外部资源。
CSS
虽然css不会影响dom的结构,但是因为js对css有获取权限,所以css加载也会因为js的不同而有所不同。
firefox会在保证css加载后才会加载js;
webkit则智能些,它只会延迟加载那些会因为css未加载而受到影响的js。
即css的执行要优先于js。
js关键词
js
操作网页内容,实现功能或效果。是客户端(浏览器(pc/app嵌入浏览器/手机上))脚本语言
标识符
是指变量、函数、属性的名字或者函数的参数。
特征:区分大小写;
第一个字符必须是字母、下划线、或者是$。
后面的可以是字母、数字、下划线、$。
命名规约:使用有实际意义的单词。
变量使用驼峰规则,第一个单词首字母小写,后面的单词首字母大写。变量使用名词,方法函数使用动词开头,常量全部用大写字母,函数创建对象首字母大写。
变量
在js中变量是用来保存值的占位符,定义变量的时候要使用var运算符,后面跟一个作为名称的标识符即可。
弱类型
强类型:在声明变量的时候就要标识其类型。
弱类型:一个变量用来保存任何类型的数据、变量的类型。不是由声明时决定(声明时只是用了var运算符)而是在程序执行阶段由其值的类型决定的,随着程序运行其值类型改变,变量类型也会发生改变。
语句是为了完成某种任务而进行的操作。比如:var a=1+2
这条语句先用var运算符,声明了变量a,然后将1+2的运算结果赋值给变量a。js中语句以;结束,一行可以包含多条语句,如果省略分号不会产生语法错误,解释器会自动判断语句结束。
注释
//单行注释
/**/ 多行注释