Frontend, and frameworks

前言
2020 秋天,我将用 30 天的时间,来尝试回答和网路前端开发相关的 30 个问题。30 天无法一网打尽浩瀚的前端知识,有些问题可能对有些读者来说相对简单,不过期待这趟旅程,能帮助自己、也帮助读者打开不同的知识大门。有兴趣的话,跟着我一起探索吧!

来到铁人赛的最後一天,应观众要求,今天来聊聊前端 framework。

如果在 Google 上搜寻 "frontend framework" 然後点入前几个搜寻结果,可以看到当今热门的前端 frameworks,像是

  • React.js
  • Angular.js
  • Vue.js
  • jQuery
  • Ember.js
  • ...

另外,还有常见的 frameworks 像是

  • Bootstrap
  • Sematic UI
  • Material UI
  • ...

这两组都叫做 framework,但做的事情好像又不太一样。到底什麽是 framework,前端为什麽需要 framework 呢?

What is a "framework"

In computer programming, a software framework is an abstraction in which software providing generic functionality can be selectively changed by additional user-written code, thus providing application-specific software. It provides a standard way to build and deploy applications and is a universal, reusable software environment that provides particular functionality as part of a larger software platform to facilitate development of software applications, products and solutions...

根据 Wiki 上的解释:

  1. 「框架」是一种 "abstraction",提供了普遍性的功能,但开发者又能根据自己或产品的需求,选择或调整当中的功能,以打造出独特的应用程序。
  2. 「框架」提供了标准的方法,来让开发者打造并部署应用程序。

那麽 "framework" 跟 "library" 有什麽差别呢?

Frameworks have key distinguishing features that separate them from normal libraries:

  1. inversion of control: In a framework, unlike in libraries or in standard user applications, the overall program's flow of control is not dictated by the caller, but by the framework.[1] This is usually achieved with the Template Method Pattern.
  2. default behaviour: This can be provided with the invariant methods of the Template Method Pattern in an abstract class which is provided by the framework.
  3. extensibility: A user can extend the framework – usually by selective overriding – or programmers can add specialized user code to provide specific functionality. This is usually achieved by a hook method in a subclass which overrides a template method in the superclass.
  4. non-modifiable framework code: The framework code, in general, is not supposed to be modified, while accepting user-implemented extensions. In other words, users can extend the framework, but cannot modify its code.

我想最大的差别在於,framework 不仅仅提供了功能性的支援,更规范出了规则与模式,也就是说,当使用了一个 framework 之後,就需要依照它所规定的范本来打造应用程序。当然使用时容许客制化,不过整体「架构」不会跑出该 framework 的规范。

所以举例来说:

  • AJAX 不是 framework 也不是 library,它只是一种网站技术开发技术的集合 ( a set of web development techniques)
  • D3.js 是 library,提供资料视觉化的功能,但并没有规范应用程序该如何打造
  • Mocha 是 framework,规范了测试的实作方式,同时也可以采用不同的 assertion library 像是 chai.js
  • jQuery 是 library,提供许多 DOM 操作的方法。

等等,刚刚上面不是看到 jQuery 是 framework 吗?

如果在网路上走走,其实会发现并不是所有人都有相同精确的 framework 和 library 定义与区别,如果参考 Stack Overflow 或是 Quara 上面的讨论,就会发现两种说法都有人拥护。

当然在 jQuery 的官网 上,自己说自己是个 library(主角都自己说了,那其他人在吵什麽 XD)。不过我的看法是,早年 jQuery 推出之後,除了提供方面的操作功能之外,也改变了开发者在「特定范围」内的开发方法与模式,因此有人会觉得 jQuery 会是个 framework。但今日的工具能力越来越强,管辖范围也越来越大,大至整个应用程序的架构,也因此回头看 jQuery 的时候就觉得它只是个 library。

我觉得争论是 "framework" 或是 "library" 其实没那麽重要,重要的是在开发的时候,需要知道这些工具的「角色」,不要使用的时候身在其中而不自知。

A little bit of history

我在铁人赛的 第一篇文章 当中来了点历史,在最後一天也再来一点吧。

HTML

1980 年代,欧洲核子研究中心 (CERN) 的科学家 Tim Berners-Lee 推出了 HTML 以及网际网路相关的协定,基本上形塑了当今网路的样貌。我也在过去的许多文章当中提到了 Tim 的事蹟,这里就不多说了。

最早期的网站非常简单,当使用者向 server 送出请求之後,server 会送回静态页面 (HTML) 到使用者的浏览器,让使用者能够浏览资讯。这样的静态网站,其实没有什麽方法可以和使用者互动,可能仅能够透过 HTTP request 来更新页面内容,或是送出资料 (form data)。

JavaScript

在 1993 年,Mosaic web browser 诞生,也是第一个拥有图形化介面的浏览器,除了更适合非工程师的使用者使用,也刺激大家对於浏览器更多可能性的想像!

1994 年 Netscape Navigator 推出,短时间成为最多人使用的浏览器。不过,Netscape 也希望能够为网站创造出更多的互动性,因此在 1995 年,Netscape 的工程师 Brendan Eich ,以神话般的 10 天创造出 JavaScript,为网站注入了生命力!

很快的,在 1996 年 Netscape 将 JavaScript 提交到 ECMA International 成为公开标准规范,让世界上所有的浏览器都能够依照相同的标准,来创造出网站与使用者的互动机制。

同一时间,Tim Berners-Lee 的同事 Håkon Wium Lie 在 1994 年提议了第一版的 CSS,并在 1996 年正式推出。

jQuery

有了 JavaScript 之後,各家浏览器就可以透过 DOM 来操作网站页面,并可以与使用者互动。不过在发展初期,虽然各家都遵守 ECMA 的规范,但实作上可能还是有所差异;另一方面,在互动的设计越来越复杂的时候,程序码也就越来越庞大和难以维护。

因此在 2006 年(一转眼 10 年过去了)jQuery 诞生!jQuery 的核心功能在於让开发者可以更简单方便的操作、遍历 DOM 元素。更重要的是,jQuery 帮助开发者可以跨越不同浏览器之间的差异。

另外,许多套件与 libraries 也因为 jQuery 而诞生,譬如早期的 Bootstrap,让前端开发的领域开始加速发展,可以说是在 HTML, CSS, JavaScript 之後的重要发明之一!

AJAX

不过到目前为止,整个网路应用程序的架构都还是 SSR (server-sdie rendering)

如果以 server side 为 MVC 的架构为例


Source

MVC 分别代表 Model, View, Controller。当使用者透过浏览器发出 HTTP request 之後,server 当中的 controller 会解析并处理这个 request,并透过 model 来操作资料库,像是提取资料或是更新资料。当 controller 拿到最新的资料之後,就会将资料和相对应得 view,送回给使用者,呈现出新的画面。

也就是说,画面的更新其实主要是由後端所驱动。

虽然之前的 JavaScript 或是 jQuery 能够让网站和使用者互动,但是如果某个互动需要让画面呈现「新的资料内容」,那麽就一定需要发出 HTTP request 到後端,才能让整个画面重新载入资料和渲染。

而如果在一个应用程序当中,使用者需要有大量资料操作的互动,那麽网站画面更新的频率就会很高,这样在使用体验或效率上都没有很好。因此早在 1996 年,大家就在思考如何如何可以提高网站画面更新的效率。

直到 2004 年,Google 在 Gmail 和 Google Map 两个应用程序使用 Asynchronous JavaScript and XML 成果相当不错,也吸引更多人对於 AJAX 设计的兴趣。2005 年,AJAX 这个词也正式的被大家所采用。

Frontend MVC

AJAX 的出现,让前端能够处理更多的互动、资料与画面的呈现。这时候开发者又有更大胆的想法:那这样是不是能够直接在前端盖 MVC 呢?

在过去,网站主要的画面还是由後端,经过资料的更新後所提供,而 AJAX 只负责「部分」资料与画面的更新。如果就让前端完全负责使用者的互动与画面更新(包含状态管理),然後资料的存取仅透过 AJAX 和 API 来向 server 发出请求,这样 server 就完全不需要在 HTTP response 当中的 body 夹带任何画面相关的档案,是不是就能够更有效率呢?

也因为要达到这个目的,前端需要有更多处理资料的能力,因此 Backbone.js 在 2010 年诞生,也让网站进入了更丰富的 SPA (single-page application) 的时代,前端的角色也就越来越重要了!

(不过 SPA 的概念其实早在 2003 年就被提出)


Source

Angular, React, Vue

差不多在 Backbone.js 推出的同一时间 (2010),Google 大神推出了 Angular.js。

2013 年社群老大 Facebook 推出 React.js。

2016 年前 Google/Angular 工程师 Evan You 只手遮天推出 Vue.js。


Source

Angular, React, Vue 就这样成为今日前端框架的三大家。这里就先不谈三者之间的差异,先来说明三者共同在前端所采用的 MVVM 设计模式。


Source

MVVM 分别代表

  • Model
  • View
  • ViewModel

最初在 2010 年左右由 Microsoft 所提出,和 MVC 架构最大的差异是将原本 的 Controller 拆分为 View Controller 和 View Model。

View controller 负责处理来自使用者的互动,在 MVVM 当中被并入到 view 里面。view model 则负责管理对应到的 view 的资料状态。

在 MVVM 当中,viewview model 是双向绑定,也就是说 view 当中的使用者操作,可以引发 view model 当中状态的改变;另一方面,view model 当中资料状态的改变,也会引发 view 的改变。

这样其中之一的好处,是能够达成「数据驱动」,只要资料状态有变动,就会同步更新画面,也可以确保画面和资料的一致性。

So?

前端的发展从一开始单纯的 HTML, CSS, JavaScript,三者各司其职,变成後面看起来复杂的各种框架,我想最大的原因是,为了追求更好的使用者体验,开发者越来越依赖前端的功能,而当前端的角色从单纯呈现页面,变成要同时「呈现页面」、「管理使用者互动」、「管理资料与状态」,很难想像如果只靠 JavaScript, DOM 和 AJAX,可以怎麽「快速」做到今日开发者可以做到的成果。

也因此,使用 framework (这里指 Angular, React, Vue) 的好处在於

  • 将资料、画面呈现、逻辑分开处理,提升未来开发与管理效率
  • 承上,也间接产生了可以重复利用的 UI 组件,可以在不同页面中出现,呈现不同的资料
  • 大幅提升开发速度
  • ...

缺点可能是,因为 frameworks 本身定义了许多规范,因此不见得像单纯的 HTML, CSS, JavaScript 容易上手。另外要能够顺利 debug 的话,也需要对该 framework 本身有足够的认识才行。

而在上面比较少提到的 CSS frameworks (e.g., bootstrap),则提供了许多设定好的 CSS 与 JavaScript 的设定,让开发者可以快速将特定样式与互动套用在自己的专案上,省去自己写 CSS 或是 JavaScript 的时间。其他好处像是:

  • 提升开发速度
  • 提供一致性的 UI 设计样板
  • 提供完善的 layout 设计
  • 解决部分跨浏览器的问题
  • ...

当然缺点就是,如果遇到需要高度客制化 CSS 的情况,使用 framework 就不见得会比较快。另外通常使用 framework 需要载入较多的程序码,其中许多可能是专案用不到的程序码,无形中增加网页载入的负担。

End

在最後一天挑战 frontend framework 实在是件不讨好的事情,范围很大,也不好找到切入点(然後也容易引战 XD)。不过我想是一个很好的机会,停下来看看 frontend development 的发展以及各种 frameworks 的由来。

虽然技术发展日新月异,但我认为旧的技术不代表就完全没有价值去了解,如果能知道旧技术在历史洪流当中所扮演的承先启後的角色,那麽,我们可能可以更能够掌握技术发展的脉络与趋势,以及做好遇到下一次变革的准备。

前端开发 30 个问题到今天暂时告一个段落,希望过程中有些主题有引发读者的兴趣。写作的过程中我也是不断的在学习,如果有任何想法或指教,都欢迎和我说一声。

再次谢谢所有花时间阅读我的文章的朋友们!

Ref


TD
Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player

More about me

"Life is like riding a bicycle. To keep your balance, you must keep moving."


<<:  Day28-Alpine.js vs Vue.js浅谈(5)

>>:  【Day28】Figma篇 : 实作

SCPM requires Internet Explorer,version 5.5 or 6.x

IE Web 网站执行时产生问题! 它让我马上用google大神找到了答案---打开 IE-->...

Day 30 | 将flutter web 部署至 netlify

最後一天就来部署我们的flutter web吧,也算是这系列文中真的跟「web」唯一有关的一篇文XD...

Swift纯Code之旅 Day1. 「前置作业」

这次的挑战赛并不是什麽特别难的目标,由於我是转职写Swift的,因此也想写些比较基础入门的资讯提供...

图的连通 (4)

9 三连通图 如果一图 G 有至少 k 个点、并且拿掉任何 k-1 个点以後都还是保持连通的,那麽我...

[Day30] 总结

终於到最後一天啦! 在嘉实工作 5 年多来,虽然一直知道公司发展的 XS 是国内程序交易的先驱者,...