Web前端

浏览器组成
渲染引擎
解析HTML构建DOM树 -> 构建渲染树 -> 渲染树布局阶段 -> 绘制渲染树
页面生成后 如果页面元素位置发生变化 就要从布局阶段开始重新渲染
HTML解析

当进行token解析后,就可以利用栈来构建一颗DOM树
CSS解析
依次拿到上一步构造好的元素,去检查它匹配到了哪些规则,再根据规则的优先级,做覆盖和调整
选择器的出现顺序,必定跟构建 DOM 树的顺序一致。这是一个 CSS 设计的原则,即保证选择器在 DOM 树构建到当前节点时,已经可以准确判断是否匹配,不需要后续节点信息
因为父元素选择器要求根据当前节点的子节点,来判断当前节点是否被选中,而父节点会先于子节点构建,这点跟原则冲突,所以目前并没有父元素选择器这种玩意
持久化存储机制
- HTTP缓存
 - localSorage:单个域下存放容量有限
 - sessionStorage:浏览器关闭自动清空
 - Cookie
- sessionCookie
 - HTTP only
 
 - WebSQL:特定浏览器的特性
 - IndexDB:NoSQL类型的数据库 大小限制50M
 - Application Cache
- 渐渐废弃 使用ServiceWorkers替代
 
 - cacheStorage
- ServiceWorker规范中的Cache对象
 
 - Flash缓存
 
浏览器Web安全
- X-XSS-Protection
- 控制浏览器对反射型XSS的防护
 
 - Strict-Transport-Security
- 强制所有通信使用HTTPS
 
 - Content-Security-Policy
- 控制浏览器只信任来自指定源的内容
 
 - Access-Control-Allow-Origin
 
前端与协议
- HTTP
 
实时协议
- WebSocket
 - Poll(轮询):实时性差 影响性能
 - Long-poll(长轮询):比上面好一点
 - 前端DDP(分布式数据协议)
- meteor:服务端-客户端双向数据更新
 
 
Native交互协议
混血应用特性:
- 可用系统资源少
 - 浏览器内核支持较新的特性
 - 可实现离线应用
 - 机型兼容(屏幕兼容)
 - 支持与Native交互
 
Web到Native协议调用:
- 通过URI
- Web应用通过发起一个URI请求 Native会进行捕获
 
 - addJavascriptInterface
- Native会注入一个全局对象给Web调用
 
 
Native到Web:
- Native通过loadURL调用Web暴露的全局对象或者方法
 
JSBridge协议规范
- Native注册一个自定义JSBridge Schema头
- 协议URL由几部分组成:欲被调用的类名、回调方法、欲被调用的方法、json对象(调用方法的参数)
 
 
三层结构
结构层
XML -> HTML -> HTML5
DOCTYPE:指示浏览器使用哪个HTML版本编写的指令进行解析
语义化标签:语义化标签帮助人更容易理解
AMP HTML:提升页面资源载入效率的规范
Shadow DOM:用来支持实现Web Component,如video标签等,其不会被外界的css或者js所影响
浏览器脚本
ES5 -> CoffeScript -> ES6 -> TS
表现层
CSS
CSS统一处理:
- reset:清除所有元素默认样式
 - normalize:为所有元素增加默认样式
 - neat:上面两种方式的组合
 
CSS预处理:sass less ...
一个良好的预处理器的功能:
- 变量声明计算
 - 语法表达式 if-else for
 - 函数处理
 - 属性继承
 - 兼容性补全 自动添加浏览器私有前缀
 
动画实现:
- js实现:由于频繁重绘 非常消耗性能
 - SVG动画:比js实现功能会更丰富 但一旦复杂起来 仍会影响性能
 - CSS3 transition:只能实现过渡变化
 - CSS3 animation:脱离JS 可以硬件加速 复杂动画也能应付
 - Canvas 动画:本质是通过js控制标签来实现
 
响应式页面
- 基于UA跳转
 - 基于媒体查询响应式
 
结构层响应式
- 结构层数据响应式
- 在前端判断不同端加载不同的数据
 
 - 后端数据响应式
- 后端渲染时直接判断 差别渲染
 
 - 结构层媒体查询
- 根据不同的屏幕渲染不同的图片 节省流量
 - Picture 可以包含多个图片 自动进行选择(Polyfill)
 - 后端模板判断渲染不同图片
 - CDN
 
 
表现层响应式
- 响应式布局:栅格布局
 - 屏幕适配布局:viewport
- 控制zoom
 - REM适配
 
 
行为层响应式
- 通过js进行判断执行不同脚本
 - 后端判断直接渲染不同脚本
 
现代前端交互框架
直接DOM操作
随着AJAX技术的发展 在DOM操作上面也越来越复杂
这个时期的代表性框架就是jQuery,其主要功能就是封装了浏览器的DOM API
MV*交互
- 前端MVC
 
通过将组件的数据及行为划分到 M V C 来进行管理,由系统统一来控制

- 前端MVP
 
使用P来处理逻辑 M 和 V 只反映视图和数据

各个部位职责更清晰 但是P的内容变得很重
- 前端MVVM
 
自动化的MVP 使用ViewModel 替代 P,这样数据的变化就会自动影响到识图 反之亦然
数据更新检测
- 手动触发更新
 - 脏检测机制:当ViewModel的某个值发生变化时找到其相关联的所有元素 然后比较更新
 - 前端数据对象劫持:通过Object.defineProperies来监听get和set,当发生变化 则需要运行相对应节点的指令
 - ES6 Proxy:实现效果跟上面一样
 
Virtual DOM交互
通过新建一个虚拟的DOM数据结构 并将其与真实DOM对比 找出差异部分进行更新

核心实现
- 将真实DOM转换为虚拟DOM:
 
自己解析HTML而非使用DOM API来生成
- 对比虚拟DOM
 
使用多叉树遍历算法 DFS或者BFS 遍历过程中需要记录节点改变的内容、差异化改变的类型及位置(在哪里增加、删除等)
前端MNV*
Model Native View *
JS调用原生控件或者事件绑定
前端开发规范
通用规范
- 三层结构分离:js css html 分离
 - 缩进保持一致
 - 内容编码:为html指定utf8编码
 - 注意大小写的使用场景
- html属性名一律使用小写以-分割
 - 属性值可以使用驼峰命名
 
 - 代码单行长度限制
 - 注释可以参考java
- 代码自描述
 
 - 删除行尾空格及符号
 
HTML规范
- 文档类型定义统一使用HTML5的!DOCTYPE 避免使用HTML4的DTD定义
 - head必须定义title keyword description等基本SEO字段 移动端注意定义viewport
 - 引入style标签或者script标签可以省略type属性
 - 标签属性值统一使用双引号
 - 诸如readonly disabled等属性的属性值可以省略
 - 元素标签必须正确嵌套 尽量使用语义化标签
 - 非自闭和标签需要添加关闭标识 自闭和标签无需添加(img br)
 - 避免img的alt属性为空
 - label标签经历增加for属性与输入域进行关联
 - 按模块添加注释 start end
 - 标签元素格式:块级元素另起一行 行内元素根据情况内联或者换行
 
CSS规范
- 尽量使用外部样式文件,避免使用内联样式
 - 命名:避免过于笼统,根据功能和内容进行命名,可以根据需要统一添加某种前缀
 - 简写
- 值为0可以省略单位
 - 0.x的单位可以省略0
 - 颜色尽量缩写到3位
 
 - 属性书写顺序:优先写布局元素,然后再写元素的内容属性
 - 避免CSS奇淫技巧
 - 若要兼容多种浏览器私有样式 则私有样式写前 标准样式写后
 - 避免类名或ID与类选择器组合使用 会造成冗余
 - 使用简短的CSS实现 合并写法
 - 元素之间存在继承关系时 提取公共部分 避免重复定义
 - 使用预处理来提高编码效率
 
ES5规范
- 语句添加分号结束可以使语句之间关系更清晰
 - 在合适的地方添加空格
 - 代码块后留空一行,使内容块更有层次
 - 字符串最外层统一使用单引号
 - 变量命名参考JAVA
 - 对象属性名不需要引号
 - 对象属性过多可以使用缩进的方式书写
 - 代码块必须加花括号
 - 不适用undefined直接进行判断 可以使用typeof
 - 避免使用 != ==
 - 禁止在条件语句或者循环语句里声明函数
 - for-in循环访问属性前要判断 避免访问不存在的属性报错
 - 避免在Array Date基础类库对象原型添加方法 否则会污染JS内置对象
 
ES6规范
- 正确使用变量声明let const
 - 字符串拼接尽量使用模板字符串
 - 解构赋值尽量只使用一层
 - 数据拷贝使用...来高效简洁实现
 - 数组循环遍历优先使用for...of
 - 尽量使用ES6的class实现oop
 - 模块化多变量导出尽量使用对象结构 不要讲import和export写在同一行
 - 导出类时,保持模块名称和文件名相同
 - 生成器yield使用时需要注意对异常的处理
 - 使用Promise代替回调
 - 尽量避免使用迭代器 性能太差
 - 推荐使用async await
 
防御性编程规范
- 对于外部传入的数据 需要做校验 避免为空导致的模板报错
 - 注意错误处理
 
前端组件规范
UI组件规范
- 统一的页面布局方案
 - 基础UI结构和样式实现
 - 组件化UI结构和样式实现
 - 响应式布局
 - UI可扩展性
 
模块化规范
- AMD 浏览器端的模块化异步加载规范
 - CMD 用到模块才会执行
 - CommonJS Node端使用的模块化规范
 - import/export ES6定义的规范
 
项目组件化规范
- Web Component 组件化
 - MVVM框架组件化 每个组件以单文件的形式引入模块 通过构建或者动态解析的方式注入到页面
 - 虚拟DOM组件化 reactjs为代表的jsx
 - 基于目录管理的通用组件化
 
组件化规范应该解决的问题:
- 组件之间独立 松耦合
 - 组件可以嵌套使用
 - 组件通信问题
 - 组件公用部分设计
 - 组件构建打包
 - 异步组件加载
 - 组件继承与复用
 - 私有组件的管理
 
自动化构建
目的:对源项目文件或资源进行文件级处理 将文件或资源处理成最佳输出结构和形式

构建工具的设计
- 模块分析引入:通过分析依赖调用生成AST,生成依赖字典
 - 模块化规范支持:目前较多的构建工具都是将ES6转换为ES5 构建工具应尽可能支持较多标准
 - CSS编译 图片合并
 - 资源压缩优化
 - 路径分析替换
 - 环境区分
 - 异步文件打包
 - 文件目录白名单
 
前端用户数据分析
用户访问统计
- PV
 - UV
- IP配合其他手段
 
 - VV:对用户访问网站多次跳转统计为一次VV
 - IP
 
用户行为分析
- 页面点击量
- 页面某个区域点击量
 
 - 用户点击流
- 在用户一次VV记录用户的点击行为
 
 - 用户访问路径
 - 用户点击热力图
 - 用户转化率:访问用户与注册用户之比
 - 导流转化率:原页面与导流页面之比
 - 访问时长
 
前端日志上报
- 性能日志上报
 - 错误日志上报
 
获取错误日志方式:
- try catch:无法捕获语法错误 无法捕捉不同作用域
 - window.onerror:功能比try catch全 ,但无法处理跨域情况
 
错误信息上传:
- 如果访问量大 注意按一定条件上传
 
错误排查:
- 对错误归类 注意版本问题
 
前端跨栈技术
后端:node
- web框架:koa,express
 - 后端数据渲染
 - 前后端同构
- 基于模板:不同的请求渲染不同的模板
 - 基于MVVM:在服务端对MVVM模板语法直接渲染
 - 基于虚拟DOM
 
 
跨终端
- 前端为主:直接将前端页面打包进安装包 主要执行这些页面
 - Native和Web结合:分别实现自己最擅长的
- 自己设计交互协议
 
 - Web资源离线和更新
- serviceWorker
 - localStorage
 - 基于增量文件
 - 基于文件代码块
 
 - Native与Web资源离线和更新
- 根据时机向服务端主动拉取 否则使用本地缓存
 
 - 资源覆盖率统计
- 日志上报
 
 
其他
- 前端代码编译为Native
 - 桌面应用
 
趋势
- 标准技术趋向于稳定
 - 工具仍会持续不断发展
 - 浏览器平台新特性未来应用的可能
 - 前端开发生态
- 效率
 - 维护成本
 - 性能
 - 扩展性
 
 - 前端新领域
- 物联网
 - AI
 - VR