Skip to content

《现代前端技术解析》精读笔记

写在前面

  • 书籍介绍:本书在前端知识体系上做了很好的总结和梳理,涵盖了现代前端技术绝大部分的知识内容,起到一个启蒙作用,能帮助读者快速把握前端技术的整个脉络,培养更完善的体系化思维,掌握更多灵活的前端代码架构方法,使读者获得成为高级前端工程师或架构师所必须具备的思维和能力。
  • 我的简评:本书知识量相当大,从时间维度上看,从原始的前端开发模式到现在先进的开发模式,从空间维度上看,从最初的pc网页开发到现在跨端跨栈,均有涉及。如果你想对前端的知识有系统的了解,这本书再适合不过了。
  • !!福利:文末有笔记思维导图、随书资料打包等下载地址哦

第1章 Web前端技术基础

1.1.现代Web前端技术发展概述

    1. 前端开发模式先后经历了静态黄页时期、服务器组装动态网页数据时期、后端为主的MVC(Model-View-Controller,一种数据模型、视图、逻辑分离的开发模式)模式时期、前后端分离方案开发时期、纯前端MV*(Model-View-,数据模型、视图、控制方式分离的开发设计方式,这里的控制方式有多种实现方法,所以一般用代替)为主与中间层直出的时期,最后进入到前端Virtual DOM(虚拟DOM,用来描述页面DOM树节点之间关系的一种特殊JavaScript对象)、MNV*(Model-NativeView-*,数据模型、原生视图、控制方式分离的开发设计模式,这里的控制方式也可以有多种实现方法,所以用*代替)模式以及前后端同构的开发时代
    1. 从以下几个方面来思考:页面内容多而复杂,怎样保证开发效率;页面内容多且复杂,项目的管理和维护该如何去做;页面加载的内容很多,怎样保证尽快将网页内容显示给用户;怎样限制页面内图片的大小以保证页面快速展示;对于重复打开的页面,能否让浏览器不再向服务器请求重复的内容;如果页面地址在移动端浏览器打开,又该怎么处理;
    1. 前端结构的开发实现模式先后经历了静态黄页时期、服务器组装动态网页数据时期、后端为主的MVC模式时期、前后端分离时期、纯前端MV为主和中间层直出时期、前端Virtual DOM、MNV、前后端同构时期

1.2.浏览器应用基础

    1. 从我们打开浏览器输入一个网址到页面展示网页内容的这段时间内,浏览器和服务端都发生了什么事情?1.在接收到用户输入的网址后,浏览器会开启一个线程来处理这个请求,对用户输入的URL地址进行分析判断,如果是HTTP协议就按照HTTP方式来处理;2.调用浏览器引擎中的对应方法,比如WebView中的loadUrl方法,分析并加载这个URL地址;3.通过 DNS 解析获取该网站地址对应的 IP 地址,查询完成后连同浏览器的 Cookie、userAgent等信息向网站目的IP发出GET请求;4.进行HTTP协议会话,浏览器客户端向Web服务器发送报文;5.进入网站后台上的Web服务器处理请求,如Apache、Tomcat、Node.js等服务器;6.进入部署好的后端应用,如 PHP、Java、JavaScript、Python等后端程序,找到对应的请求处理逻辑,这期间可能会读取服务器缓存或查询数据库等;7.服务器处理请求并返回响应报文,此时如果浏览器访问过该页面,缓存上有对应资源,会与服务器最后修改记录对比,一致则返回304,否则返回200和对应的内容;8. 浏览器开始下载HTML文档(响应报头状态码为200时)或者从本地缓存读取文件内容(浏览器缓存有效或响应报头状态码为304时);9.浏览器根据下载接收到的HTML文件解析结构建立DOM(Document Object Model,文档对象模型)文档树,并根据HTML中的标记请求下载指定的MIME类型文件(如CSS、JavaScript脚本等),同时设置缓存等内容;10.页面开始解析渲染DOM, CSS根据规则解析并结合DOM文档树进行网页内容布局和绘制渲染,JavaScript根据DOM API操作DOM,并读取浏览器缓存、执行事件绑定等,页面整个展示过程完成。
    1. 通常我们认为浏览器主要由七部分组成:用户界面、网络、JavaScript引擎、渲染引擎、UI 后端、JavaScript 解释器和持久化数据存储。用户界面包括浏览器中可见的地址输入框、浏览器前进返回按钮、打开书签、打开历史记录等用户可操作的功能选项。浏览器引擎可以在用户界面和渲染引擎之间传送指令或在客户端本地缓存中读写数据等,是浏览器中各个部分之间相互通信的核心。浏览器渲染引擎的功能是解析DOM文档和CSS规则并将内容排版到浏览器中显示有样式的界面,也有人称之为排版引擎,我们常说的浏览器内核主要指的就是渲染引擎。网络功能模块则是浏览器开启网络线程发送请求或下载资源文件的模块,例如DOM 树解析过程中请求静态资源首先是通过浏览器中的网络模块发起的,UI 后端则用于绘制基本的浏览器窗口内控件,比如组合选择框、按钮、输入框等。JavaScript解释器则是浏览器解释和执行JavaScript 脚本的部分,例如 V8引擎。浏览器数据持久化存储则涉及 cookie、localStorage等一些客户端存储技术,可以通过浏览器引擎提供的API进行调用
    1. 渲染引擎在浏览器中主要用于解析HTML文档和CSS文档,然后将CSS规则应用到HTML标签元素上,并将HTML渲染到浏览器窗口中以显示具体的DOM内容
    1. 解析HTML构建DOM树时渲染引擎会先将HTML元素标签解析成由多个DOM元素对象节点组成的且具有节点父子关系的 DOM 树结构,然后根据 DOM 树结构的每个节点顺序提取计算使用的CSS规则并重新计算DOM树结构的样式数据,生成一个带样式描述的DOM渲染树对象。DOM渲染树生成结束后,进入渲染树的布局阶段,即根据每个渲染树节点在页面中的大小和位置,将节点固定到页面的对应位置上,这个阶段主要是元素的布局属性(例如position、float、margin等属性)生效,即在浏览器中绘制页面上元素节点的位置。接下来就是绘制阶段,将渲染树节点的背景、颜色、文本等样式信息应用到每个节点上,这个阶段主要是元素的内部显示样式(例如color、background、text-shadow等属性)生效,最终完成整个DOM在页面上的绘制显示
    1. Webkit内核和Gecko内核渲染DOM的主要流程。两种渲染引擎工作流程的主要区别在于解析HTML或CSS文档生成渲染树的过程:Webkit内核中的HTML和CSS解析可以认为是并行的;而Gecko则是先解析HTML,生成内容Sink(Content Sink可以认为是构建DOM结构树的工厂方法)后再开始解析CSS。这两种渲染引擎工作过程中使用的描述术语也不一样:Webkit内核解析后的渲染对象被称为渲染树(Render Tree),而Gecko内核解析后的渲染对象则称为Frame树(Frame Tree)。
    1. HTML文档解析过程是将HTML文本字符串逐行解析生成具有父子关系的DOM节点树对象的过程
    1. CSS解析和HTML解析类似,首先也要通过词法解析生成CSS分析树,而且也使用特定的CSS文本语法来实现,不同的是,HTML是使用类似XML结构的语法解析方式来完成分析的
    1. 浏览器缓存是浏览器端用于在本地保存数据并进行快速读取以避免重复资源请求的传输机制的统称。有效的缓存可以避免重复的网络资源请求并让浏览器快速地响应用户操作,提高页面内容的加载速度。
    1. 现代浏览器的8种缓存机制:HTTP文件缓存、LocalStorage、SessionStorage、indexDB、Web SQL、Cookie、CacheStorage、Application Cache,另外还有一种使用不太多的Flash缓存方式。
    1. 浏览器HTTP文件缓存判断机制的流程图:1.浏览器会先查询Cache-Control(这里用Expires判断也是可以的,但是Expires一般设置的是绝对过期时间,Cache-Control设置的是相对过期时间)来判断内容是否过期,如果未过期,则直接读取浏览器端缓存文件,不发送HTTP请求,否则进入下一步。 2.在浏览器端判断上次文件返回头中是否含有Etag信息,有则连同If-None-Match一起向服务器发送请求,服务端判断Etag未修改则返回状态304,修改则返回200,否则进入下一步。 3.在浏览器端判断上次文件返回头中是否含有 Last-Modified 信息,有则连同If-Modified-Since一起向服务器发送请求,服务端判断Last-Modified是否失效,失效则返回200,未失效则返回304。 4.如果Etag和Last-Modified都不存在,直接向服务器请求内容。

1.3.前端高效开发技术

    1. 就前端而言,主流的开发工具主要有 Sublime、Webstorm、Vscode、Vim 等
    1. 一款高效的开发工具都应该具备以下几个方面的能力:代码格式化 Format 能力;自动检测错误能力;编辑快捷键能力;自动Debug能力;Git 或 Svn 版本控制插件能力;自动文档工具;
    1. 前端高效调试工具: 前端快速调试工具Chrome浏览,Chrome的调试面板主要包括设备模拟、Elements、Console、Sources、Network、Timeline、Profiles、Resources、Security、Audits这些内容;网络辅助工具,Fiddler;Node调试工具,node-supervisor、node-inspector;前端远程调试工具,有一些例如Vorlon.js、Weinre等用于移动端浏览器的远程调试工具;

第2章 前端与协议

2.1.HTTP协议简介

    1. HTTP(HyperText Transport Protocol,超文本传输协议)协议是WWW服务器和用户请求代理(例如浏览器等)之间通过应答请求模式传输超文本(例如HTML文件、JavaScript文件、CSS文件、图片甚至服务器接口数据等)内容的一种协议,协议的详细规范序号为RFC2616
    1. 通常一个完整的HTTP报文由头部、空行、正文三部分组成。空行用于区分报文头部和报文正文,由一个回车符和一个换行符组成。
    1. 目前使用最为广泛的仍然是HTTP 1.1版本。HTTP 1.1标准发布于1999年,相对于HTTP 1.0增加了协议扩展切换、缓存、部分文件传输优化、长连接、消息传递、host头域、错误提示等一些重要的增强特性。
    1. 协议扩展切换是指,HTTP 1.1协议支持在请求头部域消息中包含Upgrade头并让客户端通过头部标识令服务器知道它能够支持其他备用通信协议的一种机制,服务器根据客户端请求的其他协议进行切换,切换后使用备用协议与客户端进行通信。
    1. HTTP 2即超文本传输协议2.0版本,是HTTP协议的下一个版本。HTTP 2相对于之前的HTTP协议有以下几个优点: HTTP 2采用完全二进制的格式来传输数据,而非HTTP 1.x的默认文本格式。 HTTP 2使用TCP多路复用的方式来降低网络请求连接建立和关闭的开销,多个请求可以通过一个TCP连接来并发完成。HTTP 2支持传输流的优先级和流量控制机制。支持服务器端推送。

2.2.Web安全机制

    1. 基础安全知识:XSS(Cross Site Script,跨站脚本攻击)、SQL(Structured Query Language,结构化查询语言)注入和CSRF(Cross-site RequestForgery,跨站请求伪造)均属于基础的前端安全知识
    1. XSS通常是由带有页面可解析内容的数据未经处理直接插入到页面上解析导致的。需要注意的是,XSS分为存储型XSS、反射型XSS、MXSS(也叫DOM XSS)三种
    1. 存储型XSS的攻击脚本常常是由前端提交的数据未经处理直接存储到数据库然后从数据库中读取出来后又直接插入到页面中所导致的;反射型XSS可能是在网页URL参数中注入了可解析内容的数据而导致的,如果直接获取URL中不合法的并插入页面中则可能出现页面上的 XSS 攻击;MXSS 则是在渲染 DOM 属性时将攻击脚本插入DOM 属性中被解析而导致的。XSS 主要的防范方法是验证输入到页面上所有内容来源数据是否安全,如果可能含有脚本标签等内容则需要进行必要的转义。
    1. SQL注入攻击主要是因为页面提交数据到服务器端后,在服务器端未进行数据验证就将数据直接拼接到SQL语句中执行,因此产生执行与预期不同的现象。主要防范措施是对前端网页提交的数据内容进行严格的检查校验
    1. CSRF 是指非源站点按照源站点的数据请求格式提交非法数据给源站点服务器的一种攻击方法。通常比较安全的是通过页面 Token(令牌)提交验证的方式来验证请求是否为源站点页面提交的,来阻止跨站伪请求的发生。
    1. 网络请求劫持目前主要分为两种:DNS劫持与HTTP劫持。
    1. DNS劫持通常是指攻击者劫持了 DNS 服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致用户对该域名地址的访问由原IP地址转入到修改后的指定IP地址的现象,其结果就是让正确的网址不能解析或被解析指向另一网站IP,实现获取用户资料或者破坏原有网站正常服务的目的。
    1. HTTP 劫持是指,在用户浏览器与访问的目的服务器之间所建立的网络数据传输通道中从网关或防火墙层上监视特定数据信息,当满足一定的条件时,就会在正常的数据包中插入或修改成为攻击者设计的网络数据包,目的是让用户浏览器解释“错误”的数据,或者以弹出新窗口的形式在使用者浏览器界面上展示宣传性广告或者直接显示某块其他的内容
    1. 几个典型的安全消息头域设置: X-XSS-Protection、Strict-Transport-Security、Content-Security-Policy、Access-Control-Allow-Origin

2.3.前端实时协议

    1. 包括AJAX的方式在内,目前可用来在前端浏览器上进行实时通信的功能实现方式主要有WebSocket、Poll、Long-poll和DDP协议
    1. Poll 方案很容易理解,即浏览器采用定时向服务器发送请求轮询的方法不断发送或拉取消息。相对来说实时性较差,比较消耗系统资源
    1. HTTP请求可以设置一个较长的Timeout等待时间,这样网络轮询请求就可以维持一段较长的时间后返回结果,这也就是Long-poll(长轮询)的基本思路。
    1. 相比于Poll, Long-poll的实现更加节省系统资源,实时性更好,不用持续地定时发送网络请求。很典型的应用场景就是网站通过对应的移动客户端进行扫描二维码登录。
    1. DDP(Distributed Data Protocol,分布式数据协议)是一种新型的客户端与服务器端的实时通信协议,由于兼容性的原因,目前使用还不广泛。有名的Meteor Web框架的双向实时数据更新机制底层使用的就是DDP

2.4.RESTful数据协议规范

    1. REST(Representational State Transfer,表述性状态转化)并不是某一种具体的协议,而是定义了一种网络应用软件之间的架构关系并提出了一套与之对应的网络之间交互调用的规则。

2.5.与Native交互协议

    1. 从技术开发上来看,相比于传统的桌面浏览器端的Web App,它具有以下几方面明显的特征:Hybrid App可用的系统网络资源更少;支持更新的浏览器特性;可实现离线应用;较多的机型考虑;支持与Native交互;
    1. Web到Native协议调用:通过URI请求,主要原理是,Native应用可在移动端系统中注册一个Scheme协议的URI,这个URI可在系统的任意地方授权访问来调起一段原生方法或一个原生的界面;通过addJavascriptInterface注入方法到页面中调用,以通过addJavascriptInterface方法将Native的一个对象方法注入到页面中,供JavaScript调用,主要实现原理是通过 addJavascriptInterface 将 Java 的实例对象注入到WebView中,让WebView中的页面JavaScript可以直接使用,采用这种方法也可以实现更加复杂的调用功能
    1. Native到Web协议调用:Native向HTML5发起的调用是通过loadUrl方法(Android平台下面方法名为loadUrl, iOS系统下通常为stringByEvaluatingJavaScriptFromString)实现的
    1. 在Android上,JavaScript 还可以通过另一种setWebChromeClient 方法来实现:JavaScript 在执行WebView 中 JavaScript 的 alert()或 prompt()方法时,Native 端会自动触发 onJsAlert或onJsPrompt的方法回调函数,一般情况下,因为前端需要常常使用alert()方法,因此通过重写Native中的onJsPrompt方法,JavaScript就可以通过执行prompt()方法把数据内容传递到Java代码中执行,即JavaScript在执行prompt()方法时将数据传入到Native的onJsPrompt方法中,而onJsPrompt里则是我们重写的调用Native程序代码。
    1. Java也可以主动通过loadUrl()再次回调JavaScript的方法返回内容到WebView中,以Android为例,目前使用较多的解决方案是通过一个协议串定义Native和JavaScript间的数据通信规则:jsbridge://className:callbackMethod/methodName? jsonObj,这个协议串必须包括以下内容:调用Native App的特定标识头、类名称、方法名、参数、回调JavaScript的方法。
    1. JSBridge.call()方法做的事情很简单,将传入的参数组装成上述jsbridge://className:callbackMethod/methodName? jsonObj的形式,然后调用prompt(iOS一般用iframe, Android建议使用window.prompt)的方法将协议串传递到Native应用层解析执行,这时候Native层会收到这个协议串,再进一步解析并调用对应的类和方法名称,调用方法成功后执行WebView中声明的callbackMethod()函数,这样整个交互协议调用的过程就完成了。

第3章 前端三层结构与应用

3.1.HTML结构层基础

    1. 前端的三个基本构成:结构层HTML、表现层CSS和行为层JavaScript
    1. 现代的Web前端应用开发早已经不是简单的三层结构就能轻松解决的了,而是已经形成了编译流程化、生产环境基础优化结构运行的模式。简单来讲,例如HTML开发可以由Component(实现的形式较多,例如Web Component、目录级Component、其他框架自定义形式的Component)来管理结构,CSS由SASS、postCSS、stylus等预处理器的语法开发来代替,JavaScript则使用ECMAScript 6+、TypeScript等特性标准进行高效开发。这些就是目前主要的前端开发技术,其主要过程是开发完成后将开发项目管理的三层结构内容编译输出为浏览器支持运行的基础三层结构解释执行。
    1. HTML 4.01是W3C在1999年制定发布的HTML语言规范。要知道的是,HTML4.01是基于SGML(Standard Generalized Markup language,标准通用标记语言)规范来制定的。HTML5正式发布于2014年,HTML5不是基于SGML演化而来的,可以理解为是W3C的另一套实现规范。
    1. Web语义化是指在HTML结构的恰当位置上使用语义恰当的标签,使页面具有良好的结构,使页面标签元素具有含义,能够让人或搜索引擎更容易理解。
    1. 基于此定义,我们需要首先理解以下几点:用正确的标签做正确的事情;HTML语义化能让页面内容更具结构化且更加清晰,便于浏览器和搜索引擎进行解析; 即使在没有样式CSS的情况下,网页内容也应该是有序的文档格式显示,并且是容易阅读的;使项目维护人员更容易对网站进行分块,便于阅读理解;
    1. Web语义化规范并不是在任何时候都需要严格遵守的,有时直接使用甚至会产生一些副作用
    1. 流动网页提速(Accelerated Mobile Pages, AMP)是google推行的一个提升页面资源载入效率的 HTML 提议规范。基本思路有两点:使用严格受限的高效 HTML 标签以及使用静态网页缓存技术来提高网络访问静态资源的性能和用户体验。
    1. <video>标签载入解析时会去直接请求src里面的资源内容,这样就占用了浏览器的下载线程,阻塞了页面关键资源的下载
    1. 总结来看,使用AMP提升页面性能的基本的原则如下: 只允许异步的script脚本;只加载静态的资源;不能让内容阻塞渲染;不在关键路径中加载第三方JavaScript;所有的CSS必须内联;字体使用声明必须高效;最小化样式声明;只运行GPU加速的动画;处理好资源加载顺序问题;页面必须立即加载;提升AMP元素性能

3.2.前端结构层演进

    1. 选择浏览器调试工具设置中的show userAgent Shadow DOM,就可以看到Shadow DOM里的内容
    1. Shadow DOM是HTML的一个规范,它允许浏览器开发者封装自己的HTML标签、CSS样式和特定的JavaScript代码,同时也可以让开发人员创建类似<video>这样的自定义一级标签,创建这些新标签内容和相关的 API 被称为 WebComponent。
    1. 利用Web Component API创建实现一个Shadow DOM时需要注意哪些方面:注册的Shadow host名称不能与浏览器自带的原生Shadow host名称相同;注意样式模块的隔离,一定要保证当前的Shadow DOM样式只在当前Shadow DOM内生效;暴露合理的有效属性配置和DOM API接口;如果需要在实际项目中使用,我们还需要解决好如何构建打包的问题

3.3.浏览器脚本演进历史

    1. CoffeeScript的创建者Jeremy Ashkenas借鉴了部分其他语言简洁、开发高效的特性,重新定义了一套语法规则,然后按照统一的规则转译成规范、可读、默认在严格模式下运行的JavaScript代码,这样就有效地保证了最后运行的JavaScript代码是具有一定规范且风格统一的,而CoffeeScript本身定义的语法规则也是十分高效且带有较好设计规范的。相比之下,CoffeeScript语法更加简洁易用,限制避免了eval、with这类不安全语法的使用。
    1. 在工程开发实践中,ECMAScript 6的应用也很快被推广并分为两个方向:一是用于浏览器端应用开发,由于浏览器版本较多,需要将ECMAScript 6转译为ECMAScript 5的语法运行,其实这跟CoffeeScript的使用方式是一样的;二是Node端的应用开发,由于Node环境对新版本特性支持较为完善,因此可以使用ECMAScript 6的新特性,尤其是对于完善或增强类特性的支持,能够大大提升开发效率,完善功能实现效果。
    1. TypeScript相对于ECMAScript 6+标准的差异性很小,大部分与ECMAScript 6+保持一致。
    1. JSX语法的官方声明,使用它的原因是其定义了更简洁且支持对应DOM属性的树状结构描述语法
    1. 不同的JavaScript衍生脚本均具有一些共性:基于JavaScript,是JavaScript的超集;适用于特定的场景;具有自己的规范;可以按一定的规则解释运行或转译成JavaScript运行
    1. 前端脚本语言的演进过程主要包括以下几个阶段:ECMAScript 5、CoffeeScript、ECMAScript 6+、TypeScript和衍生脚本。

3.4.JavaScript标准实践

    1. ECMAScript 5于2009年12月发布,内容主要包括严格模式、JSON对象、新增Object接口、新增Array接口和Function.prototype.bind。可以认为ECMAScript 5规范的推出在原来没有规范的JavaScript语法上添加了有限的限制标准。其中最重要的一条可能就是严格模式的提出
    1. IE8更低版本的浏览器中不能直接使用JSON的解析方法。不过现在我们通常可以在浏览器中添加es5-shim来增加浏览器对ECMAScript 5功能的支持,让浏览器支持JSON对象的解析
    1. EECMAScript 6借鉴了ECMAScript 5和其他语言的特性,并在此基础上进行了补充和增强,最终形成了一套完整的特性集合,使得JavaScript语言规范更加高效、严谨、完善。例如字符串模板、集合、箭头函数、Promise、for...of循环等均是借鉴其他语言的优秀特性而增加的功能点,class类和import/export模块规范则可以认为是对原有ECMAScript标准缺失特性的补充,迭代器、生成器、解构赋值、函数参数等可认为是对原有标准特性的增强。
    1. 有几个需要注意的地方:一是let和const都只能作为块级作用域变量的声明,且只能在块作用域内生效,块内声明的变量无法在块级外层引用;二是使用 const 声明的变量必须进行初始化赋值,而且一旦赋值就不能再进行二次修改赋值;三是使用 let、const 在全局作用域下声明的变量不会作为属性添加到全局作用域对象里面,这点和 var 是不同的;四是通过测试,使用let、const赋值语句的执行速度比使用var快约65%左右
    1. ECMAScript 6中还添加了更多关于数组迭代的方法:entries()、keys()和values(),均可用来遍历数组。它们都返回一个迭代器对象,也可以用for...of循环进行遍历,区别是keys()是对数组键名进行遍历、values()是对数组键值进行遍历,entries()是对数组中键值对进行遍历,另外Array.prototype[Symbol.iterator]也可以用来获取遍历数组对象的迭代器
    1. 怎样区分Promise/A+规范和Promise/A规范:符合Promise/A+规范的promise实现一般以then方法为交互核心;Promise/A+规范要求onFulfilled或onRejected返回promise后的处理过程必须是作为函数来调用,而且调用过程必须是异步的;Promise/A+规范严格定义了then方法链式调用时onFulfilled或onRejected的调用顺序。
    1. Reflect可以理解为原有对象上的一个引用代理,它用于对原有对象进行赋值或取值操作,但不会触发对象属性的getter或setter调用,而直接使用=对对象进行赋值或取值操作会自动触发getter或setter方法
    1. SIMD(single instruction, multiple data)代表的是单指令多数据流,涉及并行计算范畴的语法指令,可以看出未来 JavaScript 有可能会在并行计算领域内使用

3.5.前端表现层基础

    1. 简单回顾一下CSS有哪几类选择器:id选择器、类选择器、元素选择器、组合选择器、伪类、伪元素等。一般认为CSS中选择器属性优先级顺序为!important > 内联样式(权重1000)>id选择器(权重100)> 类选择器(权重10)> 元素选择器(权重1),多种组合情况按照权重相加的原则来计算,! important优先级最高
    1. CSS样式统一化,目前主要有三种实现思路:reset、normalize和neat。用reset的方式进行样式统一化的思路:将不同浏览器中标签元素的默认样式全部清除,消除不同浏览器下默认样式的差异性;normalize的做法是在整站样式基本确定的情况下对标签元素统一使用同一个默认样式规则;neat 可以认为是对上面两种实现的综合,因为我们通常不能保证网站界面上的所有元素的内外边距都是确定的,又不想将所有样式都清除后再进行覆盖重写。
    1. SASS 的预处理实现主要包含模块引用、嵌套、父级选择符、嵌套属性、注释、变量、数据类型、运算、圆括号、函数、篡写、变量默认值、规则指令、控制指令、mixin、继承extend等这些属性。
    1. 一个高效的预处理语法工具一般具有以下特性:变量声明和计算;语法表达式;函数处理;属性的继承;兼容性补全;

3.6.前端界面技术

    1. 通常前端中,实现动画的方案主要有6种:JavaScript直接实现动画、可伸缩矢量图形(Scalable Vector Graphics, SVG)动画、CSS3 transition、CSS3 animation、Canvas动画、requestAnimationFrame。
    1. JavaScript直接实现动画:主要思想是通过 JavaScript 的setInterval方法或setTimeout方法的回调函数来持续调用改变某个元素的CSS样式以达到元素样式持续变化的结果
    1. SVG 动画由SVG 元素内部的元素属性控制,通常通过<set><animate><animateColor><animateTransform><animateMotion>这几个元素来实现。
    1. CSS3 animation的动画则可以认为是真正意义上页面内容的CSS3动画,通过对关键帧和循环次数的控制,页面标签元素会根据设定好的样式改变进行平滑过渡,而且关键帧状态的控制一般是通过百分比来控制的,这样我们就可以在这个过程中实现很多动画的动作了
    1. Canvas动画的实现思路和SVG的思路有点类似,都是借助元素标签来达到页面动画的效果,都需要借助对应的一套API来实现,不过SVG的API可以认为主要是通过SVG元素内部的配置规则来实现的,而Canvas则是通过JavaScript API来实现的。
    1. requestAnimationFrame是前端表现层实现动画的另一种API实现,它的原理和setTimeout及 setInterval 类似,都是通过 JavaScript 持续循环的方法调用来触发动画动作的,但是requestAnimationFrame 是浏览器针对动画专门优化而形成的 API,在实现动画方面性能比setTimeout及setInterval要好,可以将动画每一步的操作方法传入到requestAnimationFrame中,在每一次执行完后进行异步回调来连续触发动画效果
    1. 在项目实践中,一般我们在桌面浏览器端仍然推荐使用JavaScript直接实现动画的方式或SVG动画的实现方式,移动端则可以考虑使用CSS3 transition、CSS3 animation、canvas或requestAnimationFrame

3.7.响应式网站开发技术

    1. 目前比较主流的实现方法有两种:一是通过前端或后端判断userAgent来跳转不同的页面完成不同设备浏览器的适配,也就是维护两个不同的站点来根据用户设备进行对应的跳转;二是使用media query媒体查询等手段,让页面根据不同设备浏览器自动改变页面的布局和显示,但不做跳转
    1. 先来总结一下上面这两种方案的所有问题描述:能否使用同一个站点域名避免跳转的问题;能否保证移动端加载的资源内容最优;如何做移动端和桌面端浏览器的差异化功能;如何根据更多的信息进行更加灵活的判断,而不仅仅是userAgent
    1. 结构层响应式设计可以理解成HTML内容的自适应渲染实现方式,即根据不同的设备浏览器渲染不同的页面内容结构,而不是直接进行页面跳转
    1. 两种不同的设计思路:一是页面内容是在前端渲染,二是页面内容在后端渲染
    1. 表现层响应式的具体实现,至少要了解两个方面的内容:响应式布局和屏幕适配布局。响应式布局的思路比较直接,一般是通过栅格系统来解决百分比方式布局。屏幕适配布局是在移动端解决内容按照不同屏幕大小自动等比例缩放的一种布局计算方式。
    1. REM方案目前应用广泛。我们知道标签元素的CSS大小尺寸的表示单位主要有像素px、相对父元素大小百分比%、相对于当前对象内文本字体font-size的大小em、相对于文档根元素font-size的大小rem(当然还有新的vh、vw、vmax、vmin,此处先不做讨论
    1. REM方案目前是移动端上很成熟和使用最广泛的屏幕适配方案,因为相对于zoom属性的设置,更加灵活可控,可以结合不需要缩放的px单位一起使用,所以建议在移动端尽量都用REM来做屏幕适配布局

第4章 现代前端交互框架

4.1.直接DOM操作时代

    1. 包括HTML5新增加的DOM API与AJAX的API在内,这些API可以分成以下几种类型:节点查询型、节点创建型、节点修改型、节点关系型、节点属性型和内容加载型
    1. jQuery帮我们解决的问题太多了,添加了丰富的API方法的封装和网络操作,这些都是浏览器本身没有的,极大地提升了开发效率。
    1. jQuery 1.x版本帮我们解决了许多问题: 简化选择器;DOM操作方法; AJAX;事件绑定统一处理; 延时对象;兼容性实现;
    1. 想要高效地使用jQuery,可以参考以下的优化建议和原则:(1)尽可能使用id选择器进行DOM查询操作,不要使用组合选择器;(2)缓存一切需要复用的jQuery DOM对象,使用find()子查询;(3)不要滥用jQuery,尽量使用原生的代码代替;(4)尽可能使用jQuery的静态方法;(5)使用事件代理,不要直接使用元素的事件绑定;(6)尽量使用较新的 jQuery 版本;(7)尽可能使用链式写法来提高编程效率和代码运行效率。

4.2.MV*交互模式

    1. MVC可以认为是一种开发设计模式,其基本思路是将DOM交互的内容分为数据模型、视图和事件控制函数三个部分,并对它们进行统一管理。Model 用来存放请求的数据结果和数据对象,View 用于页面 DOM 的更新与修改,Controller 则用于根据前端路由条件(例如不同的HASH路由)来调用不同Model给View渲染不同的数据内容
    1. MVC和MVP不同的是,用户在进行DOM修改操作时将通过View上的行为触发,然后将修改通知给Presenter来完成后面的Model修改和其他View的更新,而MVC模式下,用户的操作是直接通过Controller来控制的。Presenter和View的操作绑定通常是双向的,View的改变一般会触发Presenter的动作,Presenter的动作也会改变View。
    1. MVVM则可以认为是一个自动化的MVP框架,并且使用ViewModel代替了Presenter,即数据Model的调用和模板内容的渲染不需要我们主动操作,而是ViewModel自动来触发完成,任何用户的操作也都是通过ViewModel的改变来驱动的
    1. 数据变更检测方式:手动触发指令绑定是比较直接的实现方式,主要思路是通过在数据对象上定义get()方法和set()方法(当然也可以使用其他命名方法),调用时手动触发get()或set()函数来获取、修改数据,改变数据后会主动触发get()和set()函数中View层的重新渲染功能;Angularjs是通过检查脏数据来进行View层操作更新的,脏检测的基本原理是在ViewModel对象的某个属性值发生变化时找到与这个属性值相关的所有元素,然后再比较数据变化,如果变化则进行Directive指令调用,对这个元素进行重新扫描渲染;数据劫持是目前使用比较广泛的方式。其基本思路是使用 Object.defineProperty 和Object.defineProperies对ViewModel数据对象进行属性get()和set()的监听,当有数据读取和赋值操作时则扫描元素节点,运行指定对应节点的Directive指令,这样ViewModel使用通用的等号赋值就可以了;ECMAScript 6的Proxy特性,它可以用于在已有的对象基础上重新定义一个对象,并重新定义对象原型上的方法,包括get()方法和set()方法,同时我们也将它和defineProperty进行了比较。

4.3.Virtual DOM交互模式

    1. 通常认为,Virtual DOM是一个能够直接描述一段HTML DOM结构的JavaScript对象,浏览器可以根据它的结构按照一定规则创建出确定唯一的HTML DOM结构。整体来看,Virtual DOM的交互模式减少了MVVM或其他框架中对DOM的扫描或操作次数,并且在数据发生改变后只在合适的地方根据JavaScript对象来进行最小化的页面DOM操作,避免大量重新渲染。
    1. 使用Virtual DOM模式来控制页面DOM结构更新的过程:创建原始页面或组件的Virtual DOM结构,用户操作后需要进行DOM更新时,生成用户操作后页面或组件的Virtual DOM结构并与之前的结构进行对比,找到最小变化Virtual DOM的差异化描述对象,最后把差异化的Virtual DOM根据特定的规则渲染到页面上。
    1. Virtual DOM 最本质的区别在于减少了对 DOM 对象的操作,通过JavaScript对象来代替DOM对象树,并且在页面结构改变时进行最小代价的DOM渲染操作,提高了交互的性能和效率。

4.4.前端MNV*时代

    1. 前端MNV开发模式。可以简单理解为 Model-NativeView-,而后面的*可以表示 Virtual DOM 或MVVM中的ViewModel,我们也可以自己使用Controller来实现调用的方式。
    1. MNV*框架端的主要任务是解析Model、ViewModel或Virtual DOM组成JSBridge协议串并发送,而Native端的实现将会比较复杂,需要处理不同的标签元素解析,例如遇到<TextView>标签则创建TextView控件,遇到<Layout>标签创建Layout控件,还可能需要处理事件的绑定等,

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

5.1.前端开发规范

    1. 前端页面开发应做到结构层(HTML)、表现层(CSS)、行为层(JavaScript)分离,保证它们之间的最小耦合,这对前期开发和后期维护都是至关重要的
    1. 防御性编程是指通过检测任何可能存在的逻辑异常问题的代码实现,提高脚本执行过程健壮性的一种编程手段。

5.2.前端组件规范

    1. 可以认为所谓的组件通常是指采用代码管理中的分治思想,将复杂的项目代码结构拆分成多个独立、简单、解耦合的结构或文件的形式进行分开管理,达到让项目代码和模块更加清晰的目的,而组件规范则是我们进行拆分、组织、管理项目代码方法的一种约定。
    1. 从 Web 前端的角度来看,UI 层的规范能带来一些明显的好处:UI 层风格统一化; 增加UI层复用性;更符合用户的体验习惯;增加了开发规范的统一性;
    1. 就规范种类来说,主要包括AMD(Asynchronous Module Definition,异步模块定义)、CMD (Common Module Definition,通用模块定义)、CommonJS、import/export等
    1. AMD是运行在浏览器端的模块化异步加载规范,主要以requireJS为代表,基本原理是定义define和require方法异步请求对应的javascript模块文件到浏览器端运行
    1. CMD是Seajs提出的一种模块化规范,在浏览器端调用类似CommonJS的书写方式来进行模块引用,但却不是完全的 CommonJS 规范。CMD 遵循按需执行依赖的原则,只有在用到某个模块的时候才会执行模块内部的require语句,同时加载完某个依赖模块文件后并不立即执行,在所有依赖模块加载完成后进入主模块逻辑,遇到模块运行语句的时候才执行对应的模块
    1. CommonJS是Node端使用的JavaScript模块化规范,使用require进行模块引入,并使用modules.exports 来定义模块导出。
    1. import/export是ECMAScript 6定义的JavaScript模块引用方式,是唯一一个遵循JavaScript语言标准的模块化规范
    1. 目前实现组件化的方案也已经越来越多:WebComponent组件化、MVVM框架组件化、基于Virutal DOM框架的组件化、直接基于目录管理的组件化等
    1. Web Component组件化:Polymer框架的设计主要分成三个层次,1. 基础层(platform.js):基本实现库;2. 核心层(polymer.js):可以理解为实现基础层的封装库;3. 元素层:建立在核心层之上的UI组件或非UI组件
    1. MVVM框架组件化,其基本思路是将页面中的模块按照元素来划分,并将与这个模块相关的 MVVM 描述语法、CSS 样式、执行脚本放在同一个文件里进行引用
    1. Virtual DOM的组件化方案:在组件化设计实现方面,它使用的仍是和Polymer类似的组织管理方式,所不同的是将HTML的结构描述换了另一种语法形式且JavaScript的调用API不同。
    1. 基于目录管理的通用组件化实践:对组件的三层结构进行文件划分,各个文件负责自己的功能部分,然后在构建生成的时候进行组件中不同类文件内容的打包处理
    1. 来看一下设计一个高效的组件化规范应该解决哪些问题:组件之间独立、松耦合;组件间嵌套使用;组件间通信; 组件公用部分设计;组件的构建打包;异步组件的加载模式;组件继承与复用性;私有组件的统一管理;根据特定场景进行扩展或自定义;

5.3.自动化构建

    1. 构建的流程主要分成7个基本步骤(不同的构建工具各有差异,但基本原理是类似的):读取入口文件→分析模块引用→按照引用加载模块→模块文件编译处理→模块文件合并→文件优化处理→写入生成目录
    1. 现代前端实际开发中通常希望构建工具帮我们处理哪些问题: 模块分析引入;模块化规范支持; CSS编译、自动合并图片;HTML、JavaScript、CSS资源压缩优化;HTML路径分析替换; 区分开发和上线目录环境;异步文件打包方案;文件目录白名单设置;

5.4.前端性能优化

    1. 获取和衡量一个页面的性能,主要可以通过以下几个方面:Performance Timing API、Profile工具、页面埋点计时、资源加载时序图分析
    1. Performance Timing API描述了页面资源从加载到解析各个阶段的执行关键点时间记录,但是无法统计JavaScript执行过程中系统资源的占用情况。
    1. 除了Performance Timing的关键过程耗时计算,我们还希望检测代码的具体解析或执行时间,这就不能写很多的 console.profile()和console.profileEnd()来逐段实现,为了更加简单地处理这种情况,往往选择通过脚本埋点计时的方式来统计每部分代码的运行时间。
    1. 借助浏览器或其他工具的资源加载时序图来帮助分析页面资源加载过程中的性能问题。这种方法可以粗粒度地宏观分析浏览器的所有资源文件请求耗时和文件加载顺序情况,如保证 CSS 和数据请求等关键性资源优先加载,JavaScript 文件和页面中非关键性图片等内容延后加载。
    1. 目前来看,前端优化的策略很多,总结起来主要包括网络加载类、页面渲染类、CSS优化类、JavaScript执行类、缓存类、图片类、架构协议类等几类
    1. 相对于桌面端浏览器,移动端Web浏览器上有一些较为明显的特点:设备屏幕较小、新特性兼容性较好、支持一些较新的HTML5和CSS3特性、需要与Native应用交互等。

5.5.前端用户数据分析

    1. 通常页面上用户访问统计主要包括PV(Page View)、UV(Unique Visitor)、VV(Visit View)、IP(访问站点的不同IP数)等。
    1. 结合其他的辅助信息来识别统计不同用户的UV,这里介绍两种常用的方式
    1. 一般用于分析用户行为的参数指标主要包括:页面点击量、用户点击流、用户访问路径、用户点击热力图、用户转换率、用户访问时长分析和用户访问内容分析等
    1. 浏览器提供了try...catch和window.onerror的两种机制来帮助我们获取用户页面的脚本错误信息
    1. 一般来说,使用try...catch可以捕捉前端JavaScript的运行时错误,同时拿到出错的信息,例如错误信息描述、堆栈、行号、列号、具体的出错文件信息等
    1. 开发者怎样知道用户端打开页面时的性能如何呢,一个可行的方法就是将页面性能数据进行上报统计,例如将Performance Timing数据、开发者自己埋点的性能统计数据通过页面JavaScript统一上报到远程服务器,在服务器端统计计算性能数据的平均值来评判前端具体页面的性能情况。

5.6.前端搜索引擎优化基础

    1. title、keywords、description是可以在HTML的标签内定义的,有助于搜索引擎抓取到网页的内容
    1. 一般title的设置要尽量能够概括页面的内容,可以使用多个title关键字组合的形式,并用分隔符连接起来。
    1. keywords是目前用于页面内容检索的辅助关键字信息,容易被搜索引擎检索到
    1. 在搜索引擎检索结果中,description 更重要的作用是作为搜索结果的描述,而不是作为权值计算的重要参考因素
    1. robots.txt是网站站点用来配置搜索引擎抓取站点内容路径的一种控制方式,放置于站点根目录下。robots.txt可以指导搜索引擎爬虫禁止抓取网站某些内容或只允许抓取哪些内容。

5.7.前端协作

    1. 前端技术涉及UI界面、数据展示、用户交互等实现,因此作为一名合格的前端工程师就不可避免地要和团队其他成员进行协作沟通,如产品经理、UI设计师、交互设计师、后台工程师、运维工程师等。
    1. 通俗地说就是你向别人传达信息或从别人那里获取信息的能力。沟通技巧就是为了高效传达信息或获取信息使用的方法和手段。
    1. 尽量推荐使用RESTful的通用协议规范来定义数据接口

第6章 前端跨栈技术

6.1.JavaScript跨后端实现技术

    1. 前端开发者都热衷于在Node上开发有以下几个原因:Node 是一个基于事件驱动和无阻塞的服务器,非常适合处理并发请求;ode 端运行的是 JavaScript,对于前端开发者来说学习成本较低;作为一名前端工程师确实需要掌握一门后台语言来辅助自己的技术学习;Node 端处理数据渲染的方式能够解决前端无法解决的问题;
    1. Node后端开发基础: 进行Node后端上的应用开发通常需要具备哪些方面的基础知识和技术:服务器知识基础;简单的数据库设计能力;后端MVC设计理念;后端异步;模块化思想;中间件技术;接口设计规范;后端部署技术和基本运维能力;
    1. 早期MEAN介绍: Node开发一般用的比较多的方案就是使用Express作为Web框架进行小型的Web站点建设,与之结合的主流技术则以M(Mysql)、E(Express)、A(Angular)、N(Node)最为典型
    1. Node后端数据渲染:1. SPA场景下SEO的问题:使用Node后端数据渲染(有人称之为直出,后文中也称之为直出层),在页面请求时将内容渲染到页面上输出,那么搜索引擎获取到的HTML就已经包含页面完整的内容,页面也就更容易被检索到了;2. 前端页面渲染展示缓慢的问题:直出层接受前端的路由请求,并在Node端的Controller层异步请求服务接入层接口,获得Model数据并进行组装拼接,然后提取相对应的Node端View模板渲染出HTML输出给用户浏览器,而不用通过前端JavaScript请求动态数据后渲染。
    1. 前后端同构:1. 前后端同构的核心问题是实现前后台数据渲染的统一性;2. 前后端同构的网站具有一些明显的优势:(1)可以根据用户的需求方便地选择使用前端渲染数据还是后台直出页面数据;(2)开发者只需维护一套前端代码,而且可以沿用前端原有的项目组件化管理、打包构建方式,根据不同的构建指令生成类似的前后端数据模板或组件在前后端执行解析;3. 前就前后端同构的技术实现上来看,至少有三种思路:数据模板的前端渲染和后台直出、MVVM的前端实现和后台直出、Virtual DOM的前端渲染和后端直出;4. 无论选择哪一种前后端同构的实现方案,所需要处理的几个问题是类似的: 前后端框架选择;模板渲染机制;构建打包;渲染和直出区分;

6.2.跨终端设计与实现

  • 1.Hybird技术趋势:关于Native应用、Web应用、Hybrid应用,三者更全面的对比
  • 2.Hybird实现方式:1. 以前端为主的Hybrid实现方式:是以完全的前端模式来开发整个应用的,页面开发完成后,通过工具自动打包将前端资源目录装入Native容器中运行;2. Native和Web结合的Hybrid方式,主要是指移动端应用中Native和Web功能上的结合开发实现。Native就可以用来实现移动端应用的通用导航菜单、系统UI层、核心界面动效、默认访问界面、高效的消息推送或APP大版本的应用更新等,因为这些功能一般比较稳定,变化不大,而且不涉及需要快速迭代的业务逻辑。而Web端则可用来实现开发迭代速度更快的相关业务层界面逻辑,它很可能是某个Native应用内关联的某个Web轻应用
  • 3.基于localStorage的资源离线和更新技术:1. 在 Hybrid 应用开发时,常常需要在离线的情况下打开页面或者为了让 Hybrid 页面应用加载启动更快,避免长时间等待资源加载过程中造成页面空白的出现;2. Hybrid 应用中实现 Web 端资源离线与更新的可行方案都有哪些:ServiceWorker的资源离线与更新;localStorage资源离线缓存与更新;基于增量文件的更新方式;基于文件代码分块的增量更新机制;基于编辑距离的增量更新机制;
  • 4.基于Native与Web的资源离线和更新技术:1. 前端离线包的生成比较简单,一般是通过构建工具将站点资源目录直接压缩,在发布前端页面与静态资源的同时上传离线包到服务器或CDN 上
  • 5.资源覆盖率统计:1. 统计的方法很多,一个简单可行的方式就是后台统计上报版本号;2. 即便我们把前端优化做到极致,HTML DOM 的运行机制较慢仍是不可改变的。

第7章 未来前端时代

7.1.未来前端趋势

  • 1.新标准的进化与稳定:1. 就前端应用开发方向来讲,MVVM、Virtual DOM和同构的技术解决方案依然会延续发展一段时间;2. 现代前端已经革新到跨端、跨界面的阶段,主流以基于MVVM、Virtual DOM、移动端MNV*思路和前后端同构技术进行开发的项目居多,实现的方向也多种多样
  • 2.应用开发技术趋于稳定并将等待下一次革新:1. 经过大版本的更新稳定,目前前端三层结构实现已经处于HTML5、CSS3、ECMAScript 6+标准规范结合的阶段,后面标准的新变化也会越来越小
  • 3.持续不断的技术工具探索:1. 前端技术效率和性能的提升当然不是仅靠前端框架就能解决的,还需要其他各方面辅助工具的支持,例如高效的调试工具、构建自动化工具、自动发布部署工具等
  • 4.浏览器平台新特性的应用:1. 浏览器上已经可以实现较多的增强和实用特性,例如 Web Component、Service Worker、IndexDB、WebAssembly、WebRTC、ECMAScript 6+的支持等
  • 5.更优化的前端技术开发生态
  • 6.前端新领域的出现:1. 未来前端也会出现新的应用场景,例如VR、物联网Web化、Web人工智能等

7.2.做一名优秀的前端工程师

  • 1.学会高效沟通
  • 2.使用高效的开发工具
  • 3.处理问题方法论:1. 这些问题可以归为几类:业务代码类问题、需求变更或需求风险类问题、开会等其他类问题。
  • 4.学会前端项目开发流程设计:1. 一个很重要的方面应该就是学会前端项目开发流程设计的能力;2. 具体来说就是能否快速地设计建立一个项目开发的Codebase,这里面包括前端框架选型、模块化方案、代码规范化、构建自动化、组件化目录设计、代码优化处理、数据统计、同构项目结构设计等
  • 5.持续的只是和经验积累管理:1. 持续性的学习很重要;2. 作为前端开发者,学习的方式也有很多,例如看别人的技术博客、研究最新的技术方向、阅读开源代码、听技术分享会、看些书等
  • 6.切忌过分追求技术:1. 一切技术的最终目的都是为产品实现服务的
  • 7.必要的产品设计思维:1. 建议大家去看一两本关于产品经理方面的书籍。一是作为整个产品项目流程的下游实现者,有必要去了解一个互联网产品的生命周期是怎样的;二是学习一些常用的产品设计常识,在一定程度上学会分析需求的漏洞和完整性

写在后面

  • pdf书籍、笔记思维导图、随书代码打包下载地址:暂无
  • 思维导图在线查看:点击打开
  • 得到电子书地址:点击阅读
  • 京东纸质书地址:点击购买