JS相关概念总结

简单介绍JavaScript的发展历史

JavaScript因互联网而生,回顾它的历史要从浏览器的历史讲起。

  • 1990年底,欧洲核能研究组织科学家Tim Berners-Lee发明了万维网(World Wide Web),但只能在操作系统的终端里浏览和操作,非常不方便。
  • 1992年底,美国国家超级电脑应用中心开发了人类历史上第一个浏览器Mosaic,从此网页可以在图形界面的窗口浏览。
  • 1994年10月,NCSA的主要程序员Marc Andreessen联合风险投资家Jim Clark,成立了Mosaic通信公司,后改名为Netscape。这家公司的方向,就是在Mosaic的基础上,开发面向普通用户的新一代的浏览器Netscape Navigator。
  • 1994年12月,Navigator发布了1.0版,该公司很快发现浏览器需要一种可嵌入网页的脚本语言来控制浏览器行为。
    管理层对这种浏览器脚本语言的设想是:功能够用,语法简单,容易学习。当时就职于Netscape的Brendan Eich着手计划于1995年2月发布的Netscape Navigator2开发LiveScript脚本语言,那年正逢Sun公司的Java语言问世,市场推广活动非常成功,为赶在发布日期前完成LiveScript开发,Netscape公司与Sun公司建立了开发联盟。
  • 1995年5月,Brendan Eich只用了10天,就设计完成了LiveScript第一版,所以这门语言比较随意。
  • 1995年12月,Netscape公司与Sun公司达成协议,后者允许将这种语言叫做JavaScript,于是Netscape在二代浏览器问世前顺利蹭到了java的热度,场面一度十分火爆。
  • 1996年3月,Navigator 2.0浏览器正式内置了JavaScript脚本语言。
  • 1996年8月,微软模仿JavaScript开发了一种相近的语言,取名为JScript。
  • 1996年11月,Netscape公司决定将JavaScript提交给国际标准化组织ECMA,希望JavaScript能够成为国际标准,以此抵抗微软。
  • 1997年7月,ECMA组织发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript。这个版本就是ECMAScript 1.0版。ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。日常场合这两个词是可以互换的。
  • 1998年6月,ECMAScript 2.0版发布。
  • 1999年12月,ECMAScript 3.0版发布,成为JavaScript的通行标准,得到了广泛支持。
  • 2007年10月,ECMAScript 4.0版草案发布,对3.0版做了大幅升级,预计次年8月发布正式版本。
  • 2008年7月,由于对于下一个版本应该包括哪些功能,各方分歧太大,争论过于激进,ECMA开会决定,中止ECMAScript 4.0的开发(即废除了这个版本),将其中涉及现有功能改善的一小部分,发布为ECMAScript 3.1,而将其他激进的设想扩大范围,放入以后的版本,由于会议的气氛,该版本的项目代号起名为Harmony(和谐)。会后不久,ECMAScript 3.1就改名为ECMAScript 5。
  • 2009年12月,ECMAScript 5.0版正式发布。
  • 2011年6月,ECMAscript 5.1版发布,并且成为ISO国际标准(ISO/IEC 16262:2011)。到了2012年底,所有主要浏览器都支持ECMAScript 5.1版的全部功能。
  • 2013年3月,ECMAScript 6草案冻结,不再添加新功能。
  • 2013年12月,ECMAScript 6草案发布。
  • 2015年6月,ECMAScript 6正式发布,并且更名为“ECMAScript 2015”。
  • 2016年6月,《ECMAScript 2016标准》发布。

简述网页的渲染机制

  1. 解析HTML标签,构建DOM树
  2. 解析CSS标签,构建CSSOM树
  3. 把DOM和CSSOM组合成渲染树
  4. 在渲染树的基础上布局,计算每个节点的几何结构
  5. 把每个节点绘制到屏幕上

CSS和JS在网页中的放置顺序是怎样的?

  1. css放入head中,link引入样式表和写在head內的style标签里都可以,也可以直接在元素中写入样式,但注意要放在js脚本之前。

  2. js放置位置:

  • 放入body底部,</body>之前。
  • 放入head中同时使用defer或async来延迟或异步加载js。
  • 使用creatElement动态生成但要注意加载顺序。
  • 用ajax加载。

原因:当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因,即无论当前JS代码是内嵌还是在外部文件中,页面的下载和渲染都必须停下来等待脚本执行完成,JS执行过程越久,浏览器等待响应用户输入的时间就越长,所以尽量把JS放在底部、设置script标签的defer或async属性、合并脚本等方法可起到性能优化效果。

解释白屏和FOUC

  1. 白屏:
  • 对IE来说,把样式放在底部时,在某些场景下(如打开新窗口/刷新页面等)页面会出现白屏,而不是内容逐步展现。
  • 如果使用@import标签,即使将CSS写入外部样式表由link引入并放在头部,也可能出现白屏。
  • 把js文件放入页面顶部而未使用defer或async延迟或异步加载js文件,从而阻塞html与css的加载也会导致白屏。
  • 另外:Chrome会同时加载html和css分别构建DOM树和CSSOM树,等到二者都构建完成后再绘制渲染树,然后显示出页面,当外部css样式表设置了延时或者加载的时间比较久时就会显示出白屏,与浏览器的渲染机制有关。
  1. FOUC:
    Flash of unsettled content:无样式内容闪烁。对IE来说,把样式放在底部时,在某些场景下(如点击链接、输入URL、使用书签进入等)页面会出现FOUC现象,具体表现为逐步加载无样式的内容,等CSS加载完成后页面突然展现样式;对Firefox来说会先显示已加载的html内容,再逐步加载无样式内容,等css全部加载完成后页面突然展现样式,所以Firefox会一直表现出FOUC。

async和defer的作用是什么?有什么区别

async和defer用于异步或延迟加载脚本。
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是读到就加载并执行。也就是说脚本会阻塞其后内容的解析和执行。

  1. 作用:
  • async(异步):定义了async属性的脚本相对于页面的其他部分异步执行(同时执行),作用是不让页面等待两个或以上的脚本下载和执行,从而异步加载页面的其他内容。
<!DOCTYPE html>
<head>
    <title>Example HTML Page</title>
    <script type="text/javascript" async src="example1.js"></script> 
    <script type="text/javascript" async src="example2.js"></script>
</head>
<body>
    <!-- 这里放内容 --> 
</body>
</html>

以上代码中evample2.js可能会在example1.js之前执行,所以确保二者之间互不依赖很重要。

  • defer(延迟):定义了defer属性的脚本会被延迟到整个页面都解析完毕后再执行。
<!DOCTYPE html>
<head>
    <title>Example HTML Page</title>
    <script type="text/javascript" defer src="example1.js"></script>
    <script type="text/javascript" defer src="example2.js"></script>
</head>
<body>
    <!-- 这里放内容 -->
</body>
</html>

以上代码中虽然我们把<script>放在了<head>中,但其中包含的脚本文件将延迟到浏览器遇到</html>后再执行。HTML5规范要求脚本按照它们出现的先后顺序执行,即第一个延迟脚本先于第二个延迟脚本执行,而这两个脚本会先于DOMContentLoaded事件执行,但现实中延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件触发前执行,所以一个文档里最好只包含一个延迟脚本。

async-VS-defer-图片来自文章最底部参考资料

上图的意思是:浏览器在解析HTML文件时,遇上没有设置defer或async属性的脚本,浏览器读到该脚本就加载并执行,脚本会阻塞其后内容的执行;
遇上设有async属性的脚本,会在HTML解析过程中下载该脚本,并在完成下载后暂停HTML的解析来执行这个异步脚本,直到执行完成后再继续HTML的解析;
遇上设有defer属性的脚本,会在HTML解析过程中下载该脚本,在HTML解析完成后才执行该文件。延迟脚本按照它们在文档中出现的顺序执行。

  1. 共同点:
  • 设置了async或defer属性的脚本不会阻塞页面渲染
  • async和defer属性决定了js脚本的执行方式,内联脚本会忽略这两个属性
  • 使用这两个属性的脚本中不能调用document.write
  • 所有defer和async脚本执行完毕后,DOMContentLoaded和load事件都将触发
  1. 区别:
  • 异步脚本一定会在页面的load事件前执行,但可能在DOMContentLoaded事件触发之前或之后执行,所以可能出现无顺序加载js的情况;延迟脚本在文档完成解析后,执行理论上是有序的但现实中并不能保证顺序,也不一定会在DOMContentLoaded事件触发前执行。
    (实际实验得到的结果是,在页面中有2个defer脚本,2个async脚本的情况下,这四个脚本的执行顺序是无序的,但单看defer或单看async,他们都是有序的,且这四个脚本文件都会在DOMContentLoaded事情之前执行完毕,load事件永远最后触发。)
  1. 关联:
  • async为true,脚本将在加载完成后立即执行
  • async为false,defer为true,脚本将在页面全部解析完成后执行
  • async和defer都为false,脚本将阻塞页面解析,即页面解析被挂起转而下载并立即执行脚本文件
  1. 注意事项:
    如果一个外部脚本依赖于另一外部脚本,请将它们标记为defer,并按它们被声明的顺序执行。
    浏览器发起资源请求request的时间都比较接近,除非DOM树非常长,时间可能会有明显差别。但资源响应时间responsive的时间差别较大,浏览器会根据情况作出优化,图片字体等优先级较低,一般等到最后才加载完成(比js还久)。

repaint 和 reflow

  • 什么是repaint和reflow:
    浏览器根据自己默认的或开发人员给出的样式表来计算DOM结构中的各个盒模型该出现的位置就是reflow;当各种盒子的位置、大小及其他属性,例如颜色、字体大小等都确定下来后,浏览器开始布局渲染树并将其绘制到屏幕上,这个过程就是repaint。

浏览器解析和渲染页面过程中会涉及到reflow(回流)和repaint(重绘),就某些浏览器如Opera而言,大部分的reflow将导致页面重新渲染,其变化涉及到部分甚至是整个页面的布局,而repaint则导致浏览器必须验证DOM树上其他节点元素的可见性。reflow和repaint过程非常消耗性能,尤其在移动设备上,会破坏用户体验,造成页面卡顿,所以应尽可能减少reflow和repaint。

  • 导致回流的原因:

    • 调整窗口大小
    • 改变字体
    • 增加或移除样式表
    • 内容变化,如在input框中输入文字
    • 激活CSS伪类,如hover
    • 操作class属性
    • 脚本操作DOM
    • 计算offsetWidth和offsetHeight属性
    • 设置style属性的值
  • 如何避免回流或将它们对性能的影响降到最低:

    • 尽可能在DOM树最末端通过改变元素的class名的方式设定元素的样式:回流会顺行或逆行传递给周围的节点,在DOM树里改变class限制了回流的范围,使其影响尽可能少的节点。
    • 避免设置多项内联样式:因为每个内联样式都会造成回流,样式应合并在一个外部类,这样当该元素的class属性被操控时只会产生一个回流。
    • 应用元素的动画使用position属性的absolute或fixed值:这样设置不影响其他元素的布局,只会导致重绘而不是完整回流。
    • 牺牲平滑度换取速度:你可能想每次1px移动一个动画,但是此动画及随后的回流使用了100%的CPU,动画看上去就会是跳动的,因为浏览器正在与更新回流做斗争。而动画元素每次移动3px,在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动。
    • 避免使用table布局:table是个和罕见的可以影响在它们之前已经进入的DOM元素的显示的元素。想象一下,因为表格最后一个单元格的内容过宽而导致纵列大小完全改变。这就是为什么所有的浏览器都逐步地不支持table表格的渲染。另外一个原因说明表格布局很糟糕,根据Mozilla,一些小的变化将导致表格(table)中的所有其他节点回流。
    • 避免使用CSS的JS表达式:因为他们每次都重新计算全部或部分文档而导致每秒产生成千上万次回流。
    • 设置box-sizing: border-box;把标准盒模型转换为IE盒模型,告诉浏览器去理解你设置的边框和内边距的值是包含在width内的。设置后,即使padding或者border发生了改变,盒子宽高不会发生变化,只会重绘,不会回流。

关于浏览器渲染更详细内容可参考我的博客第六节


参考资料

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

推荐阅读更多精彩内容

  • 1. CSS和JS在网页中的放置顺序是怎样的?CSS必须是在html之前载入,所以放在head标签里。JS放在CS...
    好好顽阅读 65评论 0 0
  • 1. CSS和JS在网页中的放置顺序是怎样的? css放在head标签内,防止渲染时出现白屏 js放在最后body...
    billa_8f6b阅读 530评论 0 0
  • 前端开发面试知识点大纲: HTML&CSS: 对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:...
    秀才JaneBook阅读 2,249评论 0 25
  • JavaScript的发展历史 JavaScript因浏览器而生,回顾它的历史要从浏览器的历史讲起。 1990年底...
    左冬的博客阅读 309评论 0 5
  • 网页 什么是网页? 网页 =Html+CSS+JavaScriptHtml是网页的内容CSS是网页的样式JavaS...
    YM雨蒙阅读 201评论 0 3