#hello,JS:00了解JS(包括白屏和fouc)

说明:

之前通过学习html+css用写博客的方式记录知识点,因为方方老师(方应杭老师)的缘故有幸获得一些人的关注,其实我是惶恐,在前端学习的路上,热爱的同时也走过很多弯路,这样的方式能够帮上正在学习前端的你固然好,不过梳理记录时难免会有知识点遗落或写错,切勿当成权威学习范本。

前言:

开始学javascript了,其实觉得CSS还有很多没学透,也没学完,:-( o(TωT)o ╭(╯^╰)╮哭唧唧啊~所以CSS学好并不简单呐,需要大量地试错练习啊!!!过后,我还是会继续配合大量实际项目去更新CSS知识。学习js,我是听着老师的课,再结合阮一峰js教程一起看,同样是适合前端新手使用的js手册,通俗易懂。

一、网页的构成

  • 网页 = Html+CSS+JavaScript
  • Html: 网页元素内容
  • CSS: 控制网页样式
  • JavaScript:操作网页内容,实现功能或者效果
  • 浏览器端(web应用)、服务端(nodejs)。。。

二、JavaScirpt 发展历史

参考:阮一峰js标准教程

  • 1995年5月,Brendan Eich只用了10天,就设计完成了这种语言的第一版。
  • 1996年8月,微软模仿JavaScript开发了一种相近的语言,取名为JScript(JavaScript是Netscape网景公司的注册商标,微软不能用),首先内置于IE 3.0。
  • 1996年11月,Netscape公司决定将JavaScript提交给国际标准化组织ECMA(European Computer Manufacturers Association),希望JavaScript能够成为国际标准,以此抵抗微软。
  • 1997年7月,ECMA组织发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript。这个版本就是ECMAScript 1.0版。
    基本上,JavaScript这个名字的原意是“很像Java的脚本语言”。在JavaScript语言中,函数是一种独立的数据类型,以及采用基于原型对象(prototype)的继承链。这是它与Java语法最大的两点区别。JavaScript语法要比Java自由得多。
  • 1999年12月,ECMAScript 3.0版发布,成为JavaScript的通行标准,得到了广泛支持。
  • 2008年7月,由于对于下一个版本应该包括哪些功能,各方分歧太大,争论过于激进,ECMA开会决定,中止ECMAScript 4.0的开发(即废除了这个版本),将其中涉及现有功能改善的一小部分,发布为ECMAScript 3.1,会后不久,ECMAScript 3.1就改名为ECMAScript 5。
  • 2009年12月,ECMAScript 5.0版正式发布。
    Harmony项目则一分为二,一些较为可行的设想定名为JavaScript.next继续开发,后来演变成ECMAScript 6;
  • 2006年,jQuery函数库诞生,作者为John Resig。jQuery为操作网页DOM结构提供了非常强大易用的接口,成为了使用最广泛的函数库,并且让JavaScript语言的应用难度大大降低,推动了这种语言的流行。
  • 2009年,Node.js项目诞生,创始人为Ryan Dahl,它标志着JavaScript可以用于服务器端编程,从此网站的前端和后端可以使用同一种语言开发。并且,Node.js可以承受很大的并发流量,使得开发某些互联网大规模的实时应用变得容易。
  • 2012年,微软发布TypeScript语言。该语言被设计成JavaScript的超集,这意味着所有JavaScipt程序,都可以不经修改地在TypeScript中运行。同时,TypeScript添加了很多新的语法特性,主要目的是为了开发大型程序,然后还可以被编译成JavaScript运行。
  • 2013年5月,Facebook发布UI框架库React,引入了新的JSX语法,使得UI层可以用组件开发。
  • 2015年4月,Angular框架宣布,2.0版将基于微软公司的TypeScript语言开发,这等于为JavaScript语言引入了强类型。

三、JS引入使用

 <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>标题</title>
     /*这里引入css代码*/
    <link href="index.css" rel="stylesheet">
    <style>
        body{
            background: red;
        }
    </style>
    </head>
    <body>
        <p>
        </p>

        /*一般来说,这里引入js代码*/
        <script src="index.js">/*空*/</script>
         或
        <script>
            alert(1);
        </script>
    </body>
    </html>

*四、浏览器渲染机制

你所看到的浏览器网页,浏览器是经历了什么你才能看到?

  • 解析 HTML 标签, 构建 DOM 树
  • 解析 CSS 标签, 构建 CSSOM 树
  • 把 DOM 和 CSSOM 组合成 渲染树 (render tree)
  • 在渲染树的基础上进行布局, 计算每个节点的几何结构
  • 把每个节点绘制到屏幕上 (painting)

当发一个请求到服务器之后,服务器会把页面上的html发给浏览器,浏览器收到之后则会解析该html标签,解析的过程中遇到了类似需要加载的样式,如link,则会再次发送请求到服务器。这样一来,如此循环,标签属性的请求不断被发出到服务器,资源不断被获取
资源获取之后,如何被用户看见?

首先,先对html标签进行解析。解析成一个dom树(即类似于树状结构,dom,即文档、模型)同时,也对css样式进行解析,同时也解析成cssom树,将css样式(默认+添加)汇聚一起形成css树——dom树元素和css树元素结合起来获得一个对象,该对象所拥有的元素和具体位置都有其相互关系,对应节点和对应数据形成一个渲染树——执行layout(布局)计算它的位置和样式——绘制——排列形成页面

五、浏览器引起的Repaint 和 Reflow问题

1、Repaint问题:

重新绘制。将css样式改变的话,其他元素并未改变,只需要重新绘制某一处就行。

2、Reflow问题:

重新回流,重新计算。即自身位置发生变化,给其他元素带来了影响,要重新进行计算。

从一个外网中截取出来的关于Repaint 和 Reflow分辨片段:

Anything that changes input information used to construct the rendering tree can cause a repaint or a reflow, for example:
Adding, removing, updating DOM nodes
Hiding a DOM node with display: none (reflow and repaint) or visibility: hidden(repaint only, because no geometry changes)
Moving, animating a DOM node on the page
Adding a stylesheet, tweaking style properties
User action such as resizing the window, changing the font size, or (oh, OMG, no!) scrollin

Let's see a few examples:

var bstyle = document.body.style; // cache

bstyle.padding = "20px"; // reflow, repaint

bstyle.border = "10px solid red"; // another reflow and a repaint

bstyle.color = "blue"; // repaint only, no dimensions changed

bstyle.backgroundColor = "#fad"; // repaint

bstyle.fontSize = "2em"; // reflow, repaint

/* new DOM element - reflow, repaint */
document.body.appendChild(document.createTextNode('dude!'));

六、白屏和FOUC

1、即指影响浏览器页面加载顺序的两种场景

  • 白屏:特指一种场景,打开页面是一片白色,突然页面出现,样式正确。那么一片白色的时间,则称之为白屏。
  • FOUC (Flash of UnstyledContent):无样式内容闪烁,网速情况差,打开页面时仍有样式,之后样式时有时无,甚至一开始并无出现样式,突然样式恢复。(常出现在firefox浏览器)
    此类现象,在不同浏览器进行的资源加载和页面渲染时,所采用的不同的处理方式,并不是bug。

2、写一个server,验证白屏和fouc效果

在index.html中

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>fouc & 白屏</title>

 <!--在下面模拟一个延时装置-->  
     <link rel="stylesheet" href="b.css?t=10"> //设置这个工具,当请求该文件时,服务器会延迟请求10s再去加载这个资源,以此可以模拟一个网速特别慢的情况
     <link rel="stylesheet" href="a.css?t=3"> 
  
</head>
<body>

  <p>hello</p>
  
  <p>饥人谷</p>
<!--   <script src="A.js?t=5"></script> 
  -->
  <img src="https://user-gold-cdn.xitu.io/2018/8/15/1653c442f35af77c?w=211&h=200&f=png&s=8004" alt="">

<!--   <link rel="stylesheet" href="c.css?t=6">  -->
 
<!--   <script src="http://a.jrg.com:8080/B.js?t=4" ></script>  
  <script src="http://b.jrg.com:8080/A.js?t=8" ></script>   -->
  
</body>
</html>

(1)关于白屏,
需要注意的是,浏览器对于样式和js的处理,即CSS和JS放置顺序。推荐:将样式放在 <head>里面,将JS放在<body>内部下方。

如上面代码所示,html页面里引入了两个css:a.cssb.cssb.css引用了c.ss@import"./c.css?t=5";b.css中加入了一个10s的延时文件(<link rel="stylesheet" href="b.css?t=10">),加载这个10s的css样式文件,浏览器是如何完成加载工作,有两种方式:

第1种: html解析完成,此时10s延时的css文件先不管,先展示<body>里所展示的内容,等css文件全加载后再去计算样式,再去重新渲染一次

第2种: 即使html的dom树已经解析、渲染都完成,对未加载完成的样式都必须等待,即css样式要全部加载、获取,img资源加载完成,此时底部JS立刻执行,才一次性展示出页面。例子中展示这种方法,即为白屏很久的原因。

(2)不同浏览器的不同处理机制所出现的场景不同

A、白屏场景(常出现在chrome):
打开一个国外网站,使用国外服务器,嵌在css的字体使用的是谷歌字体,运行特别慢,等了好久突然出现页面样式效果。这是因为页面需要等待css样式加载所有完成,甚至出现404加载失败,最后才展示出页面。那么那段加载时间,等待了几秒左右的白色一片的页面,就是白屏

B、Fouc场景(常出现在Firefox):
一开始的时候,先让你看见样式,如字的小号样式,样式加载完后看到所规定字号的大字。对用户来说,同样的样式,突然从小变大,则这个场景就是Fouc(无样式内容闪烁)。

总结:不管是css样式,还是js文件,只要加长延时,都会造成白屏

(3)CSS 和 JS 最佳放置顺序

  • 使用 link 标签将样式表放在顶部
  • 将JS放在底部

(3.1)场景:假设JS文件页面顶部:

  • JS脚本会阻塞后面内容的呈现
  • JS脚本会阻塞其后组件(如图片)的下载
  • JS加载时间过长,css需等待,则会出现一段时间白屏
  • 场景说明:引入一个JS文件在顶部,设置一个延时时间。
  • 加载顺序:css—js—img—全部获取到展现页面效果
    此时,img和css加载时会并发加载,即如一个域名下同时加载两个文件(并发是有限度的),加载在顶部的js时,会禁用并发img和css,并阻止其他内容下载和渲染。

js并不影响css加载,但是会影响css样式的一个计算。当js加载时,css已经获取到(不过此时页面还是一片空白),直到js获取立即执行后,图片立刻出现,页面才展示效果。所以js文件放入页面顶部<head>里,也会导致白屏现象出现

(3.2)JS加载特点总结

A、优先加载js文件,加载后js立刻去执行,展示页面(CSS样式则是全部加载完,然后一次性展示出页面)

注:

  • css放前面,优先加载;
  • 若放后面,其他资源则会阻碍css加载,那么时机就太晚。

B、由于渲染线程和js脚本线程是互斥的,白屏是渲染进程被阻塞的原因,当碰到script标签的时候,会先执行js脚本,然后再渲染。

(放顶部时)JS加载时机过晚导致一系列问题,脚本会阻塞后面内容的呈现、脚本会阻塞其后组件的下载(主要指img资源下载)、白屏等。

而(放底部)则可以先让其他先加载完成,JS立刻执行的特点可以“扫尾”最后的页面效果

C、JS脚本操作页面上的html+css元素,(放顶部时)JS先执行,元素都未加载到(即不存在),未出现在文档流中【加载,这里指资源加载和资源是否出现在文档流中】,所以也不能操作相应JS功能,此时后台将会报错。

D、(放顶部时)其他JS若作为一种框架语言,则能提前形成一个初步的框架有效构成页面结构。

七、JS脚本的异步加载

1、一个问题?

即一个放在<head>的js文件,如下:

<script src="script.js">
</script>

原本放在顶部的这个js文件,会提前加载,如何使它在顶部仍然稍后加载呢?

2、解决方法:asyncdefer

(1)作用:

没有 deferasync,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该script标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。也就是说,使用deferasync后能够改变这种加载、执行的时机。常应用在引用了广告和统计的页面中,不会影响、堵塞,更不会影响到到页面其他元素

(2)async

HTML5里为script标签里新增了async属性,用于异步加载脚本:不保证顺序(独立的个体)

<script async src="script.js"></script>

<script type="text/javascript" src="alert.js" async="async"></script>

浏览器解析到HTML里的该行script标签,发现指定为async,会异步下载解析执行脚本(即加载后续文档元素的过程将和script.js的加载并行进行)。

页面的DOM结构里假设<script>在img之前,如果你的浏览器支持async的话,就会异步加载脚本。此时DOM里已经有img了,所以脚本里能顺利取到img的src并弹框。

(3)defer
script标签里可以设置defer,表示延迟加载脚本:
脚本先不执行,延迟到文档解析和显示后执行,有顺序

<script defer src="script.js">
</script>

<script type="text/javascript" src="alert.js" defer="defer">
</script>

浏览器解析到HTML里该行script标签,发现指定为defer,会暂缓下载解析执行脚本,等到页面文档解析并加载执行完毕后,才会加载该脚本(更精确地说,是在DOM树构建完成后,在DOMContentLoaded 事件触发前,加载defer的脚本)。

页面的DOM结构里假设script在img图片之前,如果你的浏览器支持defer的话,就会延迟到页面加载完后才下载脚本。此时DOM里已经有img元素了,所以脚本里能顺利取到img的src并弹框。

总结: JS实质采用一种可以更自由地选择加载时机和任何位置,让处于顶部的js文件能够像在底部时,在页面必要元素加载完成时进行“异步”加载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容