Skip to content

尤大的知乎live/高屋建瓴 #2

Description

@Joulloy

上年在知乎听的第一场live,也算是为知识付费捐了点入场费,前端圈好像崇拜风气还是有的,因为我就是这样的人,哈哈,我觉得可以这样想,尤大是个人开发者,技术不用说,能开发出完整的前端框架,在营销,设计,拓宽影响力方面也是一流,大概这就是受欢迎的原因吧,每个开发者心中大概都有一个梦,创造出自己的作品。不可否认vue的火和代码思想,设计,作者个人魅力,群众的需求共同紧密相连,下面是上一年看完后写的记录,搬到此处,live只能听懂前半部分,手动狗头,当然作者也说了,每个部分拿出来都可以讲几节课的,注:总体按照大纲进行,中间穿插作者引申的概念等

组件的理解和分类

主流框架已经把组件作为最基本的抽象单元,最早前端开发以页面为抽象单位,但由于复杂度的上升,页面逐渐变为了应用,应用就有模块封装切分的需求,很快我们发现应用可以抽象为组件树。

React在该领域最大贡献是揭示了一个事实,组件可以是函数,一个组件可以调用其他函数,构成了一个树状结构。但是简单函数在实际应用中是不够的,所以 React 默认组件形式还是有 state ,用类似 class 的形式去包装。

组件的状态(state)
一个组件可以有多种形态,比如上面的柱状组件可以是硬直状态,也可以是疲软状态。(原谅我飙车了)。

四种类型的组件
展示型 单纯的显示 View。
接入型 即 container component,主要和数据层的 service 打交道。
交互型 比如各类加强版的表单组件,通常强调复用。
功能型 比如 ,,作为一种扩展、抽象机制存在。

模板和JSX的对比

JSX:本质上就是 js,具有 js 的灵活性,在书写功能型组件是远超模板的。
模板:写纯展示型更方便,强制分离交互逻辑,只做纯展示。
JSX 适合逻辑多的场景,模板适合逻辑少的场景。

Colocation
把该放在一起的东西放在一起。
跟几年前的 HTML、CSS、JS 分离对应。

Separation of Concerns
关注点分离
前端的关注点分离就是 HTML、CSS、JS 分离。

现在前端框架渲染最重要的就是声明式(Declarative)。相比较的就是命令式(Imperative),命令式最直接的例子 jQuery 代码,写到最后因为不直观很难维护。但声明式渲染方式好处是直接描述 DOM 和数据的结构关系是怎样的,一目了然。
Declarative Programming 声明式编程
你说有啥,就有啥。
Imperative Programming 命令式编程
你让我干啥,我就干啥。

意大利面条式编程
你觉得谁的代码烂,你就可以说谁的代码是意大利面条。Spaghetti code

view = render(state)
给我一个 state(数据),我就造出一个 view(DOM)。
熟悉 React 框架的都熟悉这个等式,view 的模版由输入的 state 渲染(render) 生成,底层实现可以是 virtual dom,但不是唯一选择,也可以使用细粒度的绑定(如 VUE),本质上是一样的,区别是在不同场景下更新效率的区别。

Change detection 变化侦测
监听一个对象,当对象变化时,你可以做一些事情。

Pure Component
一个 Pure Component 就是一个无副作用的函数。(React Components)

onclick="clickHandler" 的问题
clickHandler 是全局变量,这很烦人。
全局变量借祸害。

变化侦测机制

使用 VUE 的开发者都知道 VUE 的数据是响应式的,VUE 会把交给它的数据进行转化后展示,转化完成之后当你改变属性值(mutate)VUE 也会做出相应更新(Reactivity in Frontend JavaScript Frameworks)。
变化侦测主要分为两种 push 和 pull。
pull
React 的 setState 和 Angular 的脏检查都属于 pull,系统不知什么时候变,有可能变了,他需要一个信号,暴力的比对查出哪些变了,可以这样做的原因呢 ,就是js快了,虽然尤浪费,但可接受框架需要一个信号告知数据有改变,系统才会作出一个 diff,在 React 中是 dom diff,在 Angular 中是脏检查,能够这样做是现在 Javascript 足够快,虽然性能有浪费,但是整体还是可以接受。
push
VUE1 或 RxJS,数据变了之后可以立即知道哪些数据变动,可以进行更细粒度的更新,但是这也有代价,每一个绑定都会有一个 observerable 的 watcher,会带来内存开销。

VUE2 采用中等粒度的方案,在组件级别是 push,每一个组件是一个响应式的 watcher,当数据变动之后可以直接知道哪些组件变了,组件可以进行更新,在组件内部使用 virtual dom 进行比对。vue相当于采用混合式的

push 和 pull 之间本质区别是用侦测成本换取一定程度的自动优化。

路由

路由就是映射。给路由一个 url,路由就可以还你一个页面

路由是 SPA 时期遇到的问题,Angular2 是采用路径映射到组件的形式,React Router 和 VUE Router 也是采用组件映射路由的方式。
最简单的路由是一个动态组件,但是需要实现的时候路由会有很多问题:hash 模式和 history 模式如何兼容和 fallback;重定向;别名;懒加载;最复杂的是跳转,跳转需要提供钩子,钩子里面会使用异步操作,异步操作还有取消等一系列问题。

主流的路由方案比较相似,变化比较大的是 React Router 4,推崇的是使用组件本身来做路由的思路,很大程度利用之前说的第四类组件(功能型组件),可以在父组件中使用抽象的 Router 组件来声明式的渲染其他组件,和其他传统路由方案他是去中心化的,传统的是将路由表写在一个地方,React Router 4 是把路由分散的写在各个组件中。好处是灵活性非常高,但是路由结构不方便维护。

WEB 路由和 APP 路由的区别
WEB 路由是把路由映射到组件树,新的 URL push 到历史的 stack 中,stack 前一个界面的状态其实是丢弃掉的,但原生应用路由模式(Navigation)是类似与一叠卡片的状态,跳转触发后,新的界面是盖在之前的界面上,一层一层叠加的,退回去的时候是把当前的卡片拿掉,之前的卡片会出现。ionic 的路由方案是类是原生应用那种的,但 ionic 的方案不够声明式。

状态和数据流管理

总得来说前端对状态管理还没有达成共识,但又没有特别大的分歧。
可以了解一下 Flux、Redux、MobX、Vuex 和 Rx.js(反正名字里都有一个 x)。
状态管理主要涉及 event、state 和 view 的变化的管理,主要分歧在于 event 与 state 变化的管理方式,各种方案皆有优劣。
状态管理的始祖是 flux,flux 在初期的混战方案形成了 redux 和 MobX,VUEX 其实受 redux 影响比较多。
状态管理的本质是从源事件(source event)映射到状态的改变,然后在映射到 UI 的变化。

redux 和 MobX 提现了两种不同的范式(paradigm),redux 强调的是数据不可变,reducer 是一个纯函数,拿到原来的 state 和 action,返回的是一个新的 state。MobX 的数据可变,数据本身是响应式的,当数据发生改变通过之前的定义的观察器做出操作。

可把 Vue 当 redux 用把 Vue 当 MobX 用
redux 和 MobX 两者很相似,也有相同的问题,都没有对异步做出较好的支持,redux 是把异步交给 middleware,MobX 和 VUE 是让用户在 action 中进行操作。因为 redux 的 middleware 众多,所以各自基于 redux 的 middleware 形成了各个不同的方案,对简单的 CRUD 应用没有必要采用如此复杂方案,对应复杂请求(推送,实时更新)推荐使用 RxJS 做一层封装。

RxJS 使用流的方式直接从事件源映射到我们想要的结果。

数据抓取和同步

CSS 管理方案

现行的主流的 CSS 方案:
跟 JS 完全解耦,靠预处理器和比如 BEM 这样的规范来保持可维护性,偏传统。一种 CSS 命名方式,很容易被新手玩坏(不遵守规则)
CSS Modules,依然是 CSS,但是通过编译来避免 CSS 类名的全局冲突。新手也玩不坏。
各类 CSS-in-JS 方案,React 社区为代表,比较激进。不写 CSS,写 JS,已经有几十种方案了,选择恐惧症的死讯。
Vue 的单文件组件 CSS,或是 Angular 的组件 CSS(写在装饰器里面),一种比较折中的方案。
在比较这几种 CSS 方案时要明确场景的问题,在传统静态界面使用传统的 CSS 方案没什么问题,但是在组件化,单页应用的场景下传统的 CSS 书写方式会有维护的问题,使用 BEM 其实是维护和组件平行的命名方式,思维负担比较重。

传统 css 的一些问题
作用域
组件对应的 CSS 不希望污染全局,CSS Modules 和 inline styles 等可以解决。
Critical CSS 关键 CSS
首屏 CSS 所需 CSS 不需要其他页面的 CSS,CSS-in-JS 解决该方案比较好。
Atomic CSS
尽可能把 CSS 规则压缩的更小,使用原子类。
分发复用
CSS-in-JS 可以发包到 NPM 复用,因为全部是 Javascript,但是现在 webpack 可以做到这一点,不必要 CSS-in-JS。
跨平台复用
也可以将 CSS 编译为 Javascript 可以复用。

构建工具链

大神张云龙的博客,关于前端工程化
任务的自动化
开发体验和效率(新的语言功能,语法糖,hot reload 等等)
部署相关的需求
编译时优化

构建工具日新月异,前端的能力越来越强,WEB 的需求也越来越复杂,对前端的要求也越来越高,面对复杂度不同的需求,需要的工具也不同。
构建工具 任务自动化 语法糖 编译和优化 热加载 构建 js有babel 部署优化 配置的时候付出很多代价,但是收益也很大的,webpack大,就是因为他解决的问题就很困难
grunt 和 gulp 在绝大多数情况下可以使用 npm script 替代,所以用的人比较少。

Rollup 在打包效率和 tree shaking 方面做的比 webpack 好,React 也采用 Rollup 打包。

同构/服务端渲染

vue SSR指南

跨平台渲染

跨平台渲染的本质是在设计框架的时候要让框架的渲染机制和 DOM 解耦,也有多种实现形式,并不一定需要 virtual dom,virtual dom 是一个比较简单的途径。只要把框架更新时的节点操作封装起来就可以做到跨平台了,换言之就是原生的渲染引擎,像 React Native 和 Weex 底层都是针对不同的平台有适配的渲染引擎,只要把渲染引擎暴露的API和运行时对接,就可以实现框架代码渲染到原生 APP 的目的。

类型系统

构建时优化

运行时优化

Web Components 和框架的关系

Web Component 和类 React、Angular、Vue 组件化技术谁会成为未来?

Web Assembly 和框架的关系

web assembly 是跑在浏览器中的汇编语言,可以对接其他语言,但现在不太成熟。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions