第四章 现代前端交互框架

(需要进行理解,再完善笔记)

​ 数据的处理和操作的核心就是DOM的处理和操作,即便是今天,所有前端JavaScript框架最终要解决的仍然是如何实现高效,高性能DOM交互操作的问题。

​ DOM API类型分为以下几种类型:节点查询型,节点创建型,节点修改型,节点关系型,节点属性型和内容加载型。

​ JQuery主要实现了选择器,DOM操作方法,事件绑定封装,AJAX,Deferred这五个方面的封装和常见的兼容性问题的处理,我们还可以基于jQuery扩展更多的方法功能来提高业务开发效率。

​ SPA的思路是将整个应用的内容都在一个页面中实现并完全通过异步交互来根据用户操作加载不同的内容。

​ 通过DOM交互框架已经可以比较高效地处理DOM操作和事件绑定等问题。这种高效的方式带来了效率上的提升,但随着页面结构和交互复杂性的提升,仅靠这种方式会增加管理的难度。随着AJAX技术的盛行,SPA应用开始被广泛使用,而直接操作DOM的方式进行SPA的开发和维护是比较麻烦的。为解决这个问题,通常将页面上与DOM相关的内容抽象成数据模型,视图,事件控制函数三部分,这就有了前端MVC设计思路。

MVC可以认为是一种开发设计模式,其基本思路是将DOM交互的内容分为数据模型,视图和事件控制函数三个部分,并对他们进行统一管理。Model用来存放数据结果和数据对象,View用于页面DOM的更新与修改,Controller则用于根据前端路由条件来调用不同的Model给View渲染不同的数据内容。

​ 前端框架从直接的DOM操作到MVC设计模式,然后到MVP,再到MVVM框架,前端设计模式改进原则一直向着高效,易实现,易维护,易扩展的基本方向发展。虽然目前前端各类框架也已经成熟并开始向高版本迭代。但是还没有结束,我们现在的编程对象依然没有脱离DOM编程的基本套路,一次次框架的改进大大提高了开发效率,但是DOM元素运行的效率仍然没有变。

4.3 Virtual DOM 交互模式

4.3.1 Virtual DOM 设计理念

​ MVVM的前端交互模式大大提高了编程效率,自动双向数据绑定让我们可以将页面逻辑实现的核心转移到数据层的修改操作上,而不再是在页面中直接操作DOM。但实际上,尽管MVVM改变了前端开发的逻辑方式,但是最终数据层反应到页面上View层的渲染和改变仍是通过对应的指令进行DOM操作来完成的。而且通常一次ViewModel的变化可能会触发页面上多个指令操作DOM的变化,带来大量的页面结构层DOM操作来渲染。

Virtual DOM是一个能够直接描述一段HTML DOM结构的JavaScript对象,浏览器可以根据它的结构按照一定规则创建出确定唯一的HTML DOM结构。

​ 整体来看,Virtual DOM的交互模式减少了MVVM或其他框架中对DOM的扫描和操作次数,并且在数据发生改变后只在合适的地方根据JavaScript对象来进行最小化的页面DOM操作,避免大量重新渲染。

4.3.2 Virtual DOM的核心实现

​ Virtual DOM模式来控制页面DOM结构更新的过程:创建原始页面或组件的Virtual DOM结构,用户操作后需要进行DOM更新时,生成用户操作后页面或组件的Virtual DOM结构并与之前的结构进行比对,找到最小变化Virtual DOM的差异化描述对象,最后把差异化的Virtual DOM根据特定的规则渲染到页面上。

​ 所以核心操作可以抽象成三个步骤:

  1. 创建Virtual DOM
  2. 对比两个Virtual DOM生成差异化Virtual DOM
  3. 将差异化Virtual DOM渲染到页面上

其中 :

​ 创建Virtual DOM:创建Virtual DOM即把一段HTML字符串文本解析成一个能够描述它的JavaScript对象。

根据HTML字符串解析创建Virtual DOM的过程相当于实现一个HTML文本解析器,但是没有生成DOM对象树,只是生成一个操作效率更高的JavaScript对象,因此通常不会直接将HTML交给浏览器去解析,因为浏览器的DOM解析很慢,这也是Virtual DOM交互模式和普通DOM编程最本质的区别。

​ 当用户进行了页面操作需要进行页面视图改变时,通常会生成一个新的Virtual DOM结构来表示改变后的状态,而且不会将这个改变后的Virtual DOM内容立即重新渲染到页面中,而是通过对比找出两个Virtual DOM的差异性,得到一个差异树对象。对于Virtual DOM的对比算法实际上是对于多叉树结构的遍历算法。对多叉树遍历就有广度优先算法和深度优先算法。

​ 经过Virtual DOM的差异性对比,我们获得了用户操作后的差异性Virtual DOM,差异性类型和差异性的位置,那么剩下的操作就是根据对比返回的结构将差异化内容经过DOM操作渲染到页面上,整个交互过程就完成了。

Virtual DOM交互模式的优势 与以前交互模式相比,Virtual DOM最本质的区别在于减少了对DOM对象的操作,通过JavaScript 对象来代替DOM对象树,并且在页面结构改变进行最小代价的DOM渲染操作,提高了交互的性能和效率。这也是提高前端交互性能的根本原因。

4.4 前端MNV*时代

尽管Virtual DOM的交互模式能在页面数据的渲染和变更时尽可能地减少DOM操作,但仍无法完成脱离DOM交互的模式,我们知道DOM的操作效率不高,在移动设备的Hybrid WebView上表现会更慢,所以为了进一步改进Hybrid应用中DOM性能,希望完全脱离DOM的编程模式来进行结构层的操作。

为什么可以这样子实现:首先,目前,主要主流Hybrid App的Web内容通常是在原生应用中嵌入WebView来实现的,而原生应用的界面数据渲染可以通过调用原生控件来实现,它不仅没有HTML DOM的性能缺陷,而且还可以调用Native系统底层的API;其次,Hybrid App可以通过统一的JavaScript交互协议来调用原生的方法和控件,所以使用JavaScript直接调用和产生原生控件进行界面数据渲染的方式是可以实现的。

4.4.1 MNV*模式简介

我们把这种使用JavaScript调用原生控件或事件绑定生成应用程序的交互模式称为前端MNV*开发模式。这种模式目前仅使用于移动端Hybrid应用,因为需要依赖原生控件的调用支持,而只有这种特殊的应用场景才满足条件。

4.4.2 MNV* 模式的实现原理

主要是将JSBridge和DOM编程的方式进行结合,让前端能够快速构建开发原生界面的应用,从而脱离DOM的交互模式。

第五章 前端项目与技术实践

现代前端技术飞速发展,最终形成了以效率和质量为核心的两大趋势。

5.1 前端开发规范

开发规范可以认为软件开发工程师之间的另一种语言,它在一定程度上决定了团队协作过程中开发的程序代码是否具有一致性和易维护性,统一的开发规范可以降低代码的出错率和团队开发的协作成本。

5.1.1 前端通用规范

  1. 三层结构分离

    前端页面开发应做到结构层(HTML),表现层(CSS),行为层(JavaScript)分离,保证它们之间的最小耦合,这对前端开发和后期维护都是至关重要。推荐相关样式和JavaScript逻辑在外部引入的CSS和JavaScript文件中。

  2. 缩进

    统一使用tab(或4个进行缩进)来进行缩进,可以在开发编辑器或IDE里进行设置。

  3. 内容编码

    在HTML文档中使用<meta charset='utf-8'>来指定编码,一避免出现页面乱码问题。

  4. 小写

    所有的HTML标签,HTML标签属性,样式名及规则建议使用小写,我们一般习惯使用小写英文字符。

    HTML属性的id属性可以使用驼峰大小写组合的命名方式,因为id属性常常只用于JavaScript的DOM查询引用,而JavaScript语言标准推荐使用驼峰大小写组合的命名方式,因此HTML页面上的id属性也尽量使用这种标准来写。

  5. 代码单行长度限制

    代码单行长度不要超过120字符(或80字符,根据团队习惯决定),长字符串并接通常使用加号来连接换行的内容

  6. 注释

    尽可能为代码写上注释,HTML,CSS 还是JavaScript,必要的注释是不能少的。

  7. 行尾空格与符号

    删除行尾空格与多余的符号,这些内容是没有必要存在的。

5.1.2 前端HTML规范

  1. 文档类型定义

    统一使用HTML5 的标准文档类型<! DOCTYPE html>来定义,这样更简洁,而且向后兼容。不使用HTML4.01的DTD定义。

  2. head内容

    head中必须定义titlekeyworddescription,保证基本的SEO页面关键字和内容描述。移动端页面head要添加viewport控制页面缩放,有利于提高页面渲染性能。

  3. 省略type属性

    在引用CSS或JavaScript时,可以省略type属性不写,因为HTML5在引入CSS时默认type值为text/css,在引入JavaScript时默认typetext/javaScritp

  4. 使用双引号包裹属性值

    所有的标签属性值必须要用双引号包裹,不推荐单引号,不允许有的双引号,有的单引号。

  5. 属性值省略

    非必要的属性值可以省略,例如输入框里的readonlydisabledrequired等属性值是非必要的,可以省略不写。如<input type="text" disabled>

  6. 嵌套

    所有元素必须正确嵌套,尽量使用语义化标签,不允许交叉,也不允许在inline元素中包含block元素。

  7. 标签闭合

    非自闭合标签必须添加标识,自闭合标签无须关闭。

  8. 使用imgalt属性

    img加上alt属性

  9. 使用lablefor属性

    为表单内部元素<lable>加上for属性或者将对应的控件放在<lable>标签内部。这样在点击<lable>标签时,会关联到对应的inputtextarea上选中,可以增加输入的响应区域。

  1. 按模块添加注释

    在每个大的模块的开始和结束的地方添加起始注释标记,便于开发者识别,维护。

  2. 标签元素格式

    块级元素一般另起一行写,行内元素可以根据情况换行,尽量保证行内元素代码长度不超过一行,否则要考虑另起一行。HTML的子元素要尽量相对父级进行缩进,这样更有层次。

  3. 语义化标签

    在合适的地方选择合适的标签。不要使用被HTML废弃用于样式表现的无语义标签。

5.1.3 前端CSS规范

  1. CSS引用规范

    使用link的方式调用外部样式文件,外部样式文件可以复用并能用浏览器缓存提高加载速度。禁止在标签内使用内联样式,否则后期很不容易管理,强烈不建议使用。

  2. 样式的命名

    CSS类名命名一般由单词,中画线,当然也有BEM方案,这里推荐一种规范-----所有命名都使用小写,加上ui-等前缀,表示这个类名只用于控制元素的样式展示,不推荐使用拼音作为样式名,尤其是使用缩写的拼音和英文混合的方式,很让人费解。尽量不以infocurrentnews等单个单词类名直接作为类名称,单独一级命名很容易造成冲突覆盖,并且很难理解。

  3. CSS高效实现规范

    标签名,与idclass组合的选择器会造成冗余,而且降低CSS的解析速度,应避免。

  4. 使用预处理脚本编码开发

    使用预处理嵌套的方式描述元素之间的层次关系,尽可能使用预处理器的高效语法来提高开发效率,如嵌套,变量,嵌套属性,注释,继承等,避免直接使用CSS开发。使用SASS来编写CSS就高效很多。

  5. 简写方式

    单位0的缩写。如果属性值为0,则不需要为0加单位,如果以0为个数为的小数,前面的0可以省略不写。尽量带上分号。如 opacity:.6

    去掉url中引用资源的引号,这是没必要的。如background-image:url(sprites.png)

    颜色值写法,所有的颜色值要使用小写并尽量缩写至3位 如#FF0000 可写成#f00

  6. 属性书写顺序

    CSS属性书写顺序遵循先布局后内容,即先写元素的布局属性,再写元素的内容属性。常用布局属性有:position, display, float, overflow

  7. hack写法

    尽可能减少对CSS hack的使用和依赖,可以使用其他的解决方案替代hack思路。如果必须要使用浏览器hack,尽量选择稳定,常用并易于理解的书写方式。

5.1.4 ECMAScript5 常用规范

  1. 分号

    JavaScript语句后面统一加上分号

  2. 空格

    在所有运算符,符号与英文单词之间添加必要的空格,利于开发者阅读。

  3. 空行

    一般推荐在代码块后面保留一行空行,显得块内容层次更加分明

  4. 引号

    推荐JavaScript字符串最外层统一使用单引号

  1. 变量命名

    标准变量采用驼峰式命名。常量使用全大写形式命名,并采用下画线连接。构造函数首字母大写,jQuery对象推荐以"$"为开头命名,便于分辨JQuery对象和普通对象。

  2. 对象

    对象属性名不需要加引号。对象属性键值以缩进的形式书写,不要写在同一行。数组,对象属性后不能有逗号,否则部分浏览器可能会解析出错。

  1. 大括号
    程序中的代码块推荐使用大括号包裹,要注意换行,这样更加清晰,而且方便后面扩展增加内容。

  2. 条件判断
    尽量不要直接使用undefined进行变量判断,使用typeof和字符串“undefined”对变量类型进行判断。分别用===!==代替==!=更加严谨

  3. 不要在条件语句或循环语句中声明函数

5.1.5 ECMAScript 6+ 参考规范

  1. 正确使用ECMAScript 6 的变量声明关键字

  2. 字符串拼接使用字符串模板完成

  3. 解析赋值尽量使用一层结构,否则声明变量嵌套太深难以理解

  4. 数组拷贝推荐使用…实现,更加简洁高效

  5. 数组循环遍历使用for...of非必须情况下不推荐使用forEachmap,简单循环

  6. 使用ECMAScript6 的类来代替之前的实现方式,尽量使用constructor进行属性成员变量赋值

  7. 模块化多变量导出时尽量使用对象解构,不使用全局导出。尽量不要把importexport写在一行

  8. 导出类名时,保持模块名称和文件名相同,类名首字母需要大写

  9. 生成器中yield进行异步操作时需要使用try...catch包裹,方便对异常进行处理。

  10. 推荐使用promise,避免使用第三方库或直接回调,原生的异步处理性能更好而且符合语言规范。

  11. 如果不是必须,避免使用迭代器

  12. 不要使用统一码,中文的正则匹配和计算较消耗时间,而且容易出问题

  13. 合理使用Generator,推荐使用ascyn/await,更加简洁

5.1.6 前端防御性编程规范

防御性编程是指通过检测任何可能存在的逻辑异常问题的代码实现,提高脚本执行过程的健壮性的一种编程手段。防御性编程要求我们对程序的实现进行更加全面,严谨的考虑。

  1. 对外部数据的安全检测判断
  2. 规范化的错误处理
    对于常用的AJAX请求或长时间文件读写等可能失败的异步操作,需要进行错误情况的处理或异常捕获处理,而不应该被静默,否则一旦出错,用户得不到正常的提示,对用户体验影响极大。

5.2 前端组件规范

什么是组件规范?
为什么需要组件规范?
组件规范和开发规范有什么区别和联系呢?
组件通常是指采用代码管理中的分治思想,将复杂的项目代码结构拆分成多个独立、简单、解耦合的结构或文件的形式进行分开管理,达到让项目代码和模块更加清晰的目的。
组件规范则是我们进行拆分、组织、管理项目代码方法的一种约定。
所以,和开发规范相似,组件规范也是一种约定。不同的是,开发规范关注文件内部代码级别的一致性, 组件规范则更关注项目中业务功能模块内容组织的一致性。 一定程度上,组件规范包含了开发规范,因为若开发规范不统一,开发出来的组件风格便不一致,组件规范便也无从说起了。组件规范能够帮助我们对功能模块进行统一的约定管理, 通过这一约定, 任何一个独立的功能模块之间都应该是无耦合并能和其他模块很好对接和组合的。
目前前端主流的一些组件相关规范: UI (User Interface, 用户界面)组件规范、模块化规范、项目组件化设计规范。注意这三者的区别和联系,UI规范一般指UI层设计和实现的规范及统一性, 而模块化主要指的是JavaScript 模块化开发的文件模块封装方式,项目组件规范则指的是实际开发中整个项目业务代码之间的组织形式。

5.2.1 UI组件规范

简单来说,UI 组件规范强调了一个网站中所有网页结构层和表现层实现的一致性。 多个地方出现的相同按钮样式可以通过公共定义的样式规范类来描述,而不用每个地方都重复书写样式,避免使用不同的代码实现同一个效果。试想如果没有规范的存在,相同作用的按钮有时是红色,有时是绿色,开发维护时就比较难统一处理了。 从Web前端的角度来看,UI层的规范能带来一些明显的好处。

  1. UI层风格统一化。UI层风格统一化避免了不同页面的差异化设计风格,能让用户使
    用Web站点的不同网页外观风格是一致的。
  2. 增加UI层复用性。使用UI规范的情况下,UI层代码复用性增强,可以提高开发效率,
    相同功能的结构和样式不用重复实现。
  3. 更符合用户的体验习惯。例如红色按钮统一 用来表示警告,绿色按钮统一 表示安全或
    成功操作等。
  4. 增加了 开发规范的统一-性。 遵循统一的规范, 避免重复开发,避免产生多种风格的代码。

在实际团队开发中,UI组件规范的完成可能需要以下几个方面的协作:

  1. UI设计一致2.
  2. 开发实现一致。这就涉及开始说的编码开发规范,尽可能让所有UI层实现使用同样的开发规范和方式。例如样式定义,图片引用,命名规范等,就图片引用来说,图标使用base64实现还是使用小图片实现,又或者使用iconfont实现,都需要统一,不能多种方法混合,否则增加UI组件的使用复杂度。

从开发实现上,如果想设计一个具有通用组件规范的UI库,必须考虑以下几个方面的问题。

  1. 统一的页面布局方案。页面布局使用网格布局还是REM方案,是否需要支持响应式,
    如果是移动端应该怎样适配,这些是需要优先考虑的。
  2. 基础UI结构和样式实现。样式reset、 按钮、图片、菜单、表单等基础结构与样式的统一化设计实现,可以极大提高页面内容的复用性和开发效率。
  3. 组件化UI结构和样式实现。例如按钮组、字体图标、下拉菜单、输入框组、导航组、面包屑、分页、标签、轮播、弹出框、列表、多媒体、警告框等常用组件的实现。当然网站可能不会一次性用到这么 多,但是如果要考虑设计一个通用的UI组件库,这些仍然是要考虑的。
  4. 响应式布局。如果需要支持页面响应式,布局、结构、样式、媒体、javascript响应式。

5.2.2 模块化规范

模块化规范是JavaScript文件之间相互依赖引用的一种通用语法约定,就是按照一定的规范来写JavaScript文件,让它可以方便地被其他JavaScript文件引用。
就规范种类来说,主要包括AMD(异步模块定义),CMD(通用模块定义),CommonJS,import/export等。

  1. AMD
    AMD是运行在浏览器端的模块异步加载规范,主要以requireJS为代表。基本原理是定义definerequire方法异步请求对应的JavaScript模块文件到浏览器端运行。模块执行导出时可以使用函数中的return返回结果。
  2. CMD
    CMD是seajs提出的一种模块化规范,在浏览器端调用类似CommonJs的书写方式进行模块引用,但却不是完全的CommonJs规范,CMD遵循按需执行依赖的原则,只有在用到某个模块的时候才会执行模块内部的require语句,同时加载完某个依赖模块文件后并不会立即执行,在所有依赖模块加载完成后进入主模块逻辑,遇到模块运行语句的时候才执行对应的模块,这和AMD是有区别的。
  3. CommonJs
    CommonJs是Node端使用的JavaScript模块化规范,使用require进行模块引入,并使用modules.exports来定义模块导出。与前面两种方法来比,它的写法更加清晰简洁。
  4. import/export
    import/export是ECMAScript6定义的JavaScript模块引用方式,是唯一一个遵循JavaScript语言标准的模块化规范,使用import引入其他模块,export来进行模块导出。

5.2.3 项目组件化设计规范

目前组件化的方案已经越来越多,Web Component组件化,MVVM框架组件化,基于Virtual DOM框架组件化,直接基于目录管理的组件化等
高效组件化规范应该解决哪些问题:

  1. 组件之间独立、松耦合。组件之间的HTML、JavaScript、 CSS之间相互独立,尽量不重复,相同部分通过父级或基础组件来实现,最大限度减少重复代码
  2. 组件间嵌套使用。组件可以嵌套使用,但嵌套后仍然是独立、松耦合的。
  3. 组件间通信。主要指组件之间的函数调用或通信,例如A组件完成某个操作后希望B组件执行某个行为,这种情况就可以使用监听或观察者模式在B组件中注册该行为的事件监听或加入观察者,然后选择合适的时机在A组件中触发这个事件监听或通知观察者来触发B组件中的行为操作,而不是在A组件中直接拿到B组件的引用并直接进行操作,因为这样组件之间的行为就会产生耦合。
  4. 组件公用部分设计。组件的公用部分应该被抽离出来形成基础库,用来增加代码的复用性。
  5. 组件的构建打包。构建工具能够自动解析和打包组件内容。
  6. 异步组件的加载模式。在移动端,通常考虑到页面首屏,异步的场景应用非常广泛,所有异步组件不能和同步组件一起处理。这时可以将异步组件区别于普通组件的目录存放,并在打包构建时进行异步打包处理。
  7. 组件继承与复用性。对于类似的组件要做到基础组件复用来减少重复编码。
  8. 私有组件的统一管理。为了提高协作效率,可以通过搭建私有源的方式来统- - 管理组件库,例如使用包管理工具等。但这点即使在大的团队里面也很难实施,因为业务组件的实现常常需要定制化而且经常变更,这样维护组件库成本反而更大,目前可以做的是将公用的组件模块使用私有源管理起来。
  9. 根据特定场景进行扩展或自定义。如果当前的组件框架不能满足需求,我们应该能够很便捷地拓展新的框架和样式,这样就能适应更多的场景需求。比如在通过目录管理组件的方案下,既可以使用MVVM框架进行开发,也可以使用Virtual DOM框架进行开发,但要保持基本的规范结构不变。

5.3 自动化构建

5.3.1 自动化构建的目的

前端构建工具的作用可以认为是对源项目文件或资源进行文件级处理,将文件或资源处理成需要的最佳输出结构和形式。在处理过程中,我们可以对文件进行模块化引入、依赖分析,资源合并、压缩优化、文件嵌入、路径替换、生成资源包等多种操作,这样就能完成很多原本需要手动完成的事情,极大地提高开发效率。

5.3.2 自动化构建的原理

构建的流程主要分为7个基本步骤(不同构建工具各有差异,但基本原理是类似的):

读取入口文件 -> 分析模块引用 -> 按照引用加载模块 -> 模块文件编译处理 -> 模块文件合并 -> 文件优化处理 -> 写入生成目录

5.4 前端性能优化

​ 前端优化的最终目的都是 提升用户体验,改善页面性能。

​ 前端性能可以认为是用户获取所需要页面数据或执行某个页面动作的一个实时性指标,一般以用户希望获取的数据操作到用户实际获得数据的时间间隔来衡量。

​ 例如用户希望获得数据的操作时打开某个页面,那么这个操作的前端性能就可以用用户操作开始到屏幕展示页面内容给用户的这段时间间隔来评判。

​ 用户的等待延时可以分为两部分:可控等待延时和不可控等待延时。可控等待延时可以理解为能通过技术手段和优化来改进缩短的部分,例如减少图片大小让请求加载更快,减少HTTP请求数等。不可控等待延时则是不能或很难通过前后端技术手段来改进优化的,例如CPU计算时间延时,ISP网络传输延时等。

​ 前端中,所有优化大师针对可控等待延时这部分来进行的。

5.4.1 前端性能测试

获取和衡量一个页面的性能,主要可以通过以下几个方面:Performance Timing API,Profile工具,页面埋点计时,资源加载时序图分析。

5.4.2 桌面浏览器前端优化策略

网络加载类

  1. 减少HTTP资源请求次数

在前端页面中,通常建议尽可能合并静态资源图片、JavaScript 或CSS代码,减少页面请求数和资源请求消耗,这样可以缩短页面首次访问的用户等待时间。通过构建工具合并雪碧图、CSS、JavaScript 文件等都是为了减少HTTP资源请求次数。另外也要尽量避免重复的资源,防止增加多余请求。

  1. 减小HTTP请求大小.
    除了减少HTTP资源请求次数,也要尽量减小每个HTTP请求的大小。如减少没必要的图片、JavaScript、 CSS及HTML代码,对文件进行压缩优化,或者使用gzip压缩传输内容等都可以用来减小文件大小,缩短网络传输等待时延。前面我们使用构建工具来压缩静态图片资源以及移除代码中的注释并压缩,目 的都是为了减小HTTP请求的大小。

  2. 将CSS或JavaScript放到外部文件中,避免使用<style><script>标签直接引入

  3. 避免页面中空的hrefsrc

  4. 为HTML指定Cache-Control或Expires

    为HTML内容设置Cache-Control或Expires可以将HTML内容缓存起来,避免频繁向服务器端发送请求。前面讲到,在页面Cache-Control或Expires 头部有效时,浏览器将直接从缓存中读取内容,不向服务器端发送请求。

    <meta http-equiv="Cache-Control" content= "max-age=7200" / >
    <meta http-equiv="Expires" content="Mon, 20 Jul 2016 23:00:00 GMT" />

  5. 合理设置Etag和Last-Modified

    合理设置Etag和Last-Modified使用浏览器缓存,对于未修改的文件,静态资源服务器会向浏览器端返回304,让浏览器从缓存中读取文件,减少Web资源下载的带宽消耗并降低服务器负载。

<meta http-equiv="last -modified" content="Mon, 03 Oct 2016 17:45:57 GMT"/>

  1. 减少页面重定向

    页面每次重定向都会延长页面内容返回的等待延时,一次重定向大约需要600毫秒的时间开销,为了保证用户尽快看到页面内容,要尽量避免页面重定向。

  2. 使用静态资源分域存放来增加下载并行数

    浏览器在同一时刻向同一个域名请求文件的并行下载数是有限的,因此可以利用多个域名的主机来存放不同的静态资源,增大页面加载时资源的并行下载数,缩短页面资源加载的时间。通常根据多个域名来分别存储JavaScript、CSS和图片文件。

  3. 使用静态资源CDN来存储文件

  4. 使用CDN Combo下载传输内容

  5. 使用可缓存的AJAX

  6. 使用GET来完成AJAX请求

    使用XMLHttpRequest时,浏览器中的POST方法发送请求首先发送文件头,然后发送HTTP正文数据。而使用GET时只发送头部,所以在拉取服务端数据时使用GET请求效率更高。

  7. 减少Cookie的大小并进行Cookie隔离

    HTTP请求通常默认带上浏览器端的Cookie一起发送给服务器,所以在非必要的情况下,要尽量减少Cookie来减小HTTP请求的大小。对于静态资源,尽量使用不同的域名来存放,因为Cookie默认是不能跨域的,这样就做到了不同域名下静态资源请求的Cookie隔离。

  8. 缩小favicon.ico并缓存

  9. 推荐使用异步JavaScript资源

    异步的JavaScript 资源不会阻塞文档解析,所以允许在浏览器中优先渲染页面,延后加载脚本执行。例如JavaScript的引用可以如下设置,也可以使用模块化加载机制来实现。

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

  10. 消除阻塞渲染的CSS及JavaScript

    对于页面中加载时间过长的CSS或JavaScript文件,需要进行合理拆分或延后加载,保证关键路径的资源能快速加载完成。

  11. 避免使用CSS import引用加载CSS

    CSS中的@import可以从另一个样式文件中引入样式,但应该避免这种用法,因为这样会增加CSS资源加载的关键路径长度,带有@import的CSS样式需要在CSS文件串行解析到@import时才会加载另外的CSS文件,大大延后CSS渲染完成的时间。

页面渲染类

  1. 把CSS资源引用放在HTML文件顶部

    一般推荐将所有CSS资源尽早指定在HTML文档<head>中,这样浏览器可以优先下载CSS并尽早完成页面渲染。

  2. JavaScript资源引用放到HTML文件底部

    JavaScript资源放到HTML文档底部可以防止JavaScript的加载和解析执行对页面渲染造成阻塞。由于JavaScript资源默认是解析阻塞的,除非被标记为异步或者通过其他的异步方式加载,否则会阻塞HTMLDOM解析和CSS渲染的过程。

  3. 不要在HTML中直接缩放图片

  4. 减少DOM元素数量和深度

    HTML中标签元素越多,标签的层级越深,浏览器解析DOM并绘制到浏览器中所花的时间就越长,所以应尽可能保持DOM元素简洁和层级较少。

  5. 尽量避免使用<table><iframe>等慢元素

<table>内容的渲染是将table的DOM渲染树全部生成完并–次性绘制到页面上的,所以在长表格渲染时很耗性能,应该尽量避免使用它,可以考虑使用列表元素<u1>代替。尽量使用异步的方式动态添加iframe,因为iframe内资源的下载进程会阻塞父页面静态资源的下载与CSS及HTML DOM的解析。

  1. 避免运行耗时的JavaScript

    长时间运行的JavaScript会阻塞浏览器构建DOM树、DOM渲染树、渲染页面。所以,任何与页面初次渲染无关的逻辑功能都应该延迟加载执行,这和JavaScript资源的异步加载思路是一致的。

  2. 避免使用CSS表达式或CSS滤镜

5.6 前端搜索引擎优化基础

搜索引擎优化简称SEO

5.6.1 title, keywords, description的优化

titlekeywordsdescription 是可以在HTML的<meta>标签内定义的,有助于搜索引擎抓取到网页的内容。要注意的是,一般title的权重是最高的,也是最重要的,因此我们应该好好利用title来提高页面的权重。keywords相对权重较低,可以作为页面的辅助关键词搜索。description的描述一般会直接显示在搜索结果的介绍中,可以使用户快速了解页面内容的描述文字,所以要尽量让这段文字能够描述整个页面的内容,增加用户进入页面的概率。

  1. title的优化

    一般title的设置要尽量能够概括页面的内容,可以使用多个title关键字组合的形式,并用分隔符连接起来。分隔符一般有“_”, “-”, “”, “”等,其中 “_” 分隔符比较容易被百度搜索引擎检索到,“-”分隔符则容易被谷歌搜索引擎检索到,“,”则在英文站点中使用比较多,可以使用空格。title的长度在桌面浏览器端一般建 议控制在30个字以内,在移动端控制在20个字以内,若长度超出时浏览器会默认截断并显示省略号。

    关于title格式的优化设置可以遵循以下规则:

    1. 每个网页都应该有独一无二的标题,切忌所有的页面都使用同样的默认标题
    2. 标题主题明确, 应该包含网页中最重要的信息
    3. 简明精练, 不应该罗列与网页内容不相关的信息
    4. 用户浏览通常从左到右的, 建议将重要的内容放到title靠前的位置
    5. 使用用户所熟知的语言描述,如果有中、英文两种网站名称,尽量使用用户熟知的语 言作为标题描述

    对于网站不同页面title的定义可以设置如下:

    1. 首页:网站名称_提供服务介绍或产品介绍
    2. 列表页: 列表名称_网站名称
    3. 文章页:文章标题_文章分类_网站名称

5.6.2 语义化标签的优化

  1. 使用具有语义化的HTML5标签结构
  2. 唯一的H1标题
  3. <img>添加alt属性

《现代前端技术解析》第4-5章 阅读笔记相关推荐

  1. 现代前端技术解析读书笔记

    思维导图链接:http://v3.processon.com/view/link/5f7ec592762131119546c899 取材自<现代前端技术解析> 本文只是个人读书笔记,更多详 ...

  2. 现代前端技术解析:Web前端技术基础

    ​ 最近几年,越来越多的人投入到前端大军中:时至至今,前端工程师的数量仍然不能满足企业的发展需求:与此同时,互联网应用场景的复杂化提高了对前端工程师能力的要求,一部分初期前端工程师并不能胜任企业的工作 ...

  3. 快速搞定前端技术一面 匹配大厂面试要求学习笔记

    快速搞定前端技术一面 匹配大厂面试要求学习笔记 第1章 课程介绍[说说面试的那些事儿] 本章会出几个面试题,分析每道题目设计的知识点,然后总结出一个完整的知识体系.让我们开始 "题目-> ...

  4. 西瓜书第三章阅读笔记

    西瓜书第三章阅读笔记 第三章 线性模型 1.机器学习三要素 2.基本形式 3.线性回归 3.1 模型 3.2 策略 3.3 求解算法 4.对数几率回归 4.1 模型 4.2 策略 4.3 求解算法 5 ...

  5. 西瓜书第四章阅读笔记

    西瓜书第四章阅读笔记 1.基本概念 1.1 基本算法 1.2 信息熵 1.3 信息增益 2.ID3决策树 3.C4.5决策树 4.CART决策树 5.剪枝操作 6.连续与缺失值处理 7.多变量决策树 ...

  6. 西瓜书第一章阅读笔记

    西瓜书第一章阅读笔记 第一章 绪论 1.机器学习基本术语 2.归纳偏好 3.所有学习算法一样优秀? 4.补充资料 第一章 绪论 1.机器学习基本术语 记录:对一个事件或对象的描述,也称为"示 ...

  7. 西瓜书第二章阅读笔记

    西瓜书第二章阅读笔记 第二章 模型评估与选择 1.经验误差与过拟合 2.模型评估方法 2.1 留出法 hold out 2.2 交叉验证法 cross valildation 2.3 自助法 boot ...

  8. 《现代前端技术解析》读后鬼扯

    别名:前端工程师培养大纲 评分:4星 作者:张成文 GitHub:https://github.com/ouvens/ 豆瓣:https://book.douban.com/subject/27021 ...

  9. 《前端技术架构与工程》之性能笔记

    <前端技术架构与工程>之性能 前言: <前端技术架构与工程>这本书真的越看越有味.目前写了部分这本书的笔记,共分为三部分做笔记,已写了两篇如下. <前端技术架构与工程&g ...

最新文章

  1. 谁说程序员干不过写ppt的,码农就该这样雄起
  2. IronRuby and ASP.NET MVC
  3. GPIO模拟I2C程序实现
  4. 一文深入理解协同过滤
  5. html设置表格和div的距离,CSS/HTML Div调整大小和表格定位
  6. jQuery1.4 API 中文版手册(chm格式)
  7. tmap | R语言中专门绘制地图的工具包
  8. ValueError: could not broadcast input array from shape (*,*) into shape (*)
  9. 洛谷P1136 迎接仪式
  10. 五天学redhat系列之---安装篇(下)
  11. Myeclipse6.0安装svn插件
  12. python英文词频统计软件_英语词频统计软件功能介绍
  13. iPhone 开发分辨率 持续更新
  14. 《最重要的事,只有一件》读书笔记
  15. 响应式Web设计在跨终端广告创意中的应用
  16. cdr圆形渐变填充怎么设置_cdr渐变怎么设置?CorelDRAW渐变设置方法
  17. 微信小程序——获取用户的运动步数
  18. 金典指纹考勤机安装及使用操作步骤
  19. mysql ext3 ext4_Mysql如何选择文件系统?(ext4 vs ext3 vs jfs vs xfs vs reise
  20. 更高的等级、更强的暴力

热门文章

  1. CAA-二次开发给几何图形集添加参数
  2. uni-app生成海报并分享
  3. vector的find用法
  4. C++:值传递和引用传递
  5. android 在androidStudio中对空包进行签名,打入签名文件信息(重签名)
  6. 计算机视觉(十五):综合案例:垃圾分类
  7. Pythonxy'import sitecustomize'错误的解决办法
  8. TID-MOP:面向数据交易所场景下的安全管控综合框架
  9. python中map函数中的str_python中map()函数用法
  10. 中国首个泛工业品展览会即将开幕! ——2021易派客工业品展览会将亮相苏州!