2023 年前端 Web 发展趋势

虽然就个人观点,我觉得 Web 开发在最近几年都没什么进展(2016 年至 2021 年),但在刚刚过去的 2022 年中确实又出现了一些新的技术。在本文中,我想跟大家聊聊自己看到的最新 Web 开发的发展趋势。相信这波浪潮会继续激发 Web 开发者的关注,也让我对万象更新的 2023 年更具期待。

image.png

一、框架

单页应用程序(SPA)及各类相关框架(包括 React.js、Vue.js、Svelte.js 等)或多或少都经历过一定的炒作周期,也用多年阅历证明了自身强大的生命力。但随着以这些解决方案为基础的元框架的快速兴起,可以看到应用程序正在明显从客户端渲染(CSR)转向服务器端渲染(SSR)。如今,无论你使用哪一种 JavaScript 框架,总能看到 SSR (Server-side Rendering服务端渲染缩写)的影子。

image.png
其中,最具人气的 Next.js 元框架就以 React.js 为基础。React 核心开发者 Andrew Clark 将 2022 年发布的新版本称为“真正的 React 18”,因为其中包含 React 团队为底层库基础构建块构建的所有 battery(例如 Suspense、流式 SSR 等)。Vercel(Next.js 背后的公司)也与 React.js 核心团队紧密合作,共同打造出色的开发者体验。

虽然不少开发者都对 Next.js 和 React.js 之间过于“亲密”的关系颇有微词,但 React.js 并非不可替代。最近刚刚被 Shopify 收购的 Remix,就采用不同方法将 React.js 转化为元框架(例如将 Web 标准设为优先)。而且在竞争之外,两套框架之间也有一定程度的功能融合(例如嵌套路由)。

除了现代 SSR 领域最有力的参与者、帮助众多前端开发者顺利成型为全栈开发者的 Next.js,其他一些重要框架同样值得大家关注:SvelteKit(基于 svelte.js 构建)及其最新 1.0 版本是由 Vercel 和 SolidStart(基于 Solid.js 构建)提供支持,较 React.js 拥有更好的开发者体验。

二、应用程序与渲染模式

虽然过去的十年(2010 年至 2020 年),Web 世界一直由单页应用程序(SPA)及其客户端渲染模式(CSR)所主导——从 Knockout.js 到 Ember.js,再到 Angular.js、React.js 以及 Vue.js 莫不如是——但最近两、三年,人们对使用元框架的服务器端渲染(SSR)越来越青睐有加。从外部来看,这似乎只是历史的又一轮循环,毕竟在多页应用程序(MPA)中使用 SSR 和 JavaScript(例如 jQuery、MooTools、Dojo.js 等)的作法早在 2005 年到 2010 年就曾盛极一时。但这波浪潮的意义绝不只是曾经的 Java(例如 JSP)或后来的 Ruby on Rails 被纳入 SSR,而在于 JavaScript 依赖性的不断增长。几年以来,Next.js 一直是这股变化背后的核心驱力,而 SvelteKit 等其他元框架也正在加入战团、共同促成这一历史性转变。

尽管两种模式的基本用途并不相同,但凭借长久以来与静态站点生成(SSG)的竞争,SSR 如今已经拥有近乎完美的性能表现(参考 Next.js 和 Gatsby.js)。在应用场景下,SSG 一般用于静态内容,而 SSR 则用于动态内容(例如 Web 应用程序)。如果需要考虑 SEO(搜索引擎优化),则 SSR 和 SSG 均适用。但如果需要提供高度动态的内容,或者是交付以用户为中心的内容并涉及身份验证,则 SSG 适用性较差(在部署前一次性构建,即静态);这时候最好是在 SSR(能根据服务器上的单个数据请求按需构建)或者是最近热度飙升的 CSR(在客户端上按需获取个别数据)间做选择。

但这里要强调,CSR、SSR 和 SSG 都不属于新兴的渲染技术。虽然 SSR 和 SSG 在前几年迎来了一波性能优化趋势,但实际发展的只是增量静态再生成(ISR)和流式 SSR 等更具体的渲染技术。前者改善了 SSG 性能,允许在每页基础之上静态重建整个网站。更进一步的方法还有按需 ISR,也称按需重新验证,可通过应用程序公开的 API 触发重建(例如在 CMS 数据更新时触发)。

image.png

另一方面,流式 SSR 则优化了服务器端渲染的单线程瓶颈。普通 SSR 需要在服务器上等待数据就绪,之后再将渲染完成的内容发送至客户端。相比之下,流式 SSR 允许开发者将应用程序拆分成多个块,让各个块逐步由服务器并行发送至客户端,大大的提高了性能。

过去几年间,SPA/MPA 中的 SSG 和 SSR 渲染模式由极简单,逐步发展成如今愈发微妙的形态。而且不单是 ISR 和 SSR 流有所联系,部分水合(Partial Hydration,例如 React 服务器组件)允许仅在客户端上水合某些组件、渐进式水合可对水合顺序进行细粒度控制、Island 架构(例如 Astro)面向 MPA 中的隔离应用或组件,甚至出现了以可恢复性代表水合(例如 Qwik)的另一种有效方法。

三、无服务器

SSR 和 SSG 等渲染技术与边缘无服务器的普及态势高度相关,原因是这些趋势均受到性能驱动,目的是在浏览器中提供无缝的用户体验。从本质上讲,正是为了向用户提供更快的网站和 Web 应用程序响应速度,才最终催生出边缘无服务器这一技术分支。

这里咱们先来弄清楚几个概念:无服务器,又称无服务器函数、无服务器计算 (例如 AWS Lambda)或云函数(例如 Google.Firebase Cloud Functions),多年来一直在云计算领域占据一席之地。虽然无服务器并不是真正的不需要(远程)底层服务器,但开发者已经不必管理服务器及其相关任务(例如基础设施按需扩展)。相反,用户只需要将单一功能部署为无服务器函数,其他所有运维工作均由云服务商承担。

无服务器函数的出现带来了一大优势:由于不需要将应用程序服务器部署到特定一处或几处数据中心,我们首次实现了功能在世界各地的广泛覆盖。因此在理想情况下,无服务器函数能够尽可能贴近与用户间的距离,即最大程度降低客户端 - 服务器间的往返延迟,由此改善用户体验。也正是这种尽可能靠近用户部署无服务器函数的思路,创造出了边缘计算和边缘函数两个术语。

众多云服务商(包括 Cloudflare 和 Cloudflare Workers、Vercel 及其 Edge Network、Deno 及其 Deno Deploy 等)已经在这个领域展开竞争,各自努力为最终用户提供最佳交互时间(TTI)体验。边缘函数不仅能加快 SSG/SSR 内容的交付速度(因为连接最终用户的线路更短),而且能将结果缓存到离用户更近的位置。

除了性能之外,边缘计算还在成本等其他重要因素上具备优势。例如,对于边缘函数,客户端与服务器之间往来的数据中有相当一部分并不需要交由主数据中心处理。在物联网场景中,有大量非相关数据(例如内容无任何变化的视频记录帧)其实没有任何意义,直接在边缘位置筛选即可。这就大大节约了数据传输与集中设施处理带来的日常开销。

三、数据库复兴

随着无服务器(边缘位置)的出现,数据库也迎来一波复兴。使用无服务器函数,开发者很快就会遇到数据库连接开启过多的问题,这是因为新的边缘设施形态导致每台服务器不再固定保持一条开启连接,而是每个无服务器函数都与数据库一一连接。虽然连接池能够很好解决问题,但用户要么需要自建,要么由第三方服务商提供。

无服务器数据库领域的热门竞争者包括 PlanetScale(MySQL)、Neon(PostgreSQL)和 Xata(PostgreSQL),它们具备数据库分支、schema diffing 和强大的搜索、分析、洞察功能。遍布全球各地的无服务器设施只需要提供边缘缓存或分布式只读数据库,确保让数据尽可能靠近用户位置、最大程度降低延迟。

如果第三方服务不仅需要分发数据库,还需要分发应用程序,Fly.io 能够将所有内容打包至单一平台当中。这类应用就超越了常规数据库,进而推动新的技术变革。人们常将 Railway 视为 Heroku 的继任者,它为平台即服务(PaaS)带来了部署技术堆栈所需要的一切。如果大家希望将服务链上移至后端即服务(BaaS),则可通过 Supabase 使用 Firebase 的开源替代方案,获得应用程序 / 数据库托管、身份验证和边缘函数等功能。

四、JavaScript 运行时

一切都始于 Ryan Dahl 在 2009 年一场会议上公布的 Node.js。最初,Node.js 的目标只是将 JavaScript 和浏览器拆分开来,尝试将其运行在服务器端。但后来,JavaScript 成为过去十年间最成功的 Web 开发驱动力。本质上,Ryan Dahl 在无需浏览器本体的情况下,为 Node.js 开发出了名为 V8 的 JavaScript 引擎(由 Chrome 实现)。因此,Chrome 浏览器和 Node.js 使用的是完全相同的 JavaScript 引擎,但二者各自有自己的 JavaScript 运行时(例如浏览器 API 与节点 API)来实现交互。

十年之后,Ryan Dahl 宣布 Deno 成为 Node 的继任者,并承诺为开发人员提供一个更安全、更快捷的环境,其中还将包括浏览器 API、TypeScript 和一个开箱即用的标准库。Deno 同样运行在 V8 引擎之上,但如今的它只是众多 JavaScript 运行时中的一种。

在边缘函数这一竞争领域,各云服务商也在纷纷实现自己的 JavaScript 运行时(例如 Cloudflare Workers,专门针对自家 Cloudflare 基础设施进行了优化)。因此,Deno 的商业模式也开始向云服务商转型,打造出 Deno Deploy 及其即时边缘渲染 SSR 框架(最初仅为概念验证)Deno Fresh。此外,像 Bun(以运行在 JavaScriptCore 引擎上,却依托于 Zig 实现而闻名)这样的独立解决方案,也在这场以速度为比拼要素的 JavaScript 运行时竞赛中获得了一定关注。

面对这么多运行时选项,相信敏锐的读者朋友肯定感受到了技术碎片化的倾向。如果协调不当,那我们又会像当年各种各样的浏览器那样疲于为 JavaScript 提供支持。但好在这次竞争的焦点在于服务器端,而且不同云服务商对于各种 JavaScript 运行时的关注度也大有区别。为了保持江湖地位,Deno、Vercel、Cloudflare 等利益相关方纷纷加入 WinterCG,表示愿意就 JavaScript 运行时间的 API 互操作性开展合作。

五、Monorepo

过去,Monorepo主要用于大型应用程序,其中各项目在单一版本控制仓库中仅包含较小体量。这些较小的项目单元可能是独立应用程序(例如 SPA、MPA),也可能是可复用包(例如函数、组件、服务等)。这种项目拆分再合并的作法可以追溯到 2000 年初,那时候的名称叫共享代码库。

不过,如今的 Monorepos 不仅面向大型应用程序,同时也开始服务于小型企业和开源项目。例如,一家公司可以在 Monorepos 中包含各种包,例如共享 UI 组件、共享设计系统(例如可复用的协作设计)以及不同领域的日常实用工具函数。

这些包可以在各种应用程序中直接导入,使用所有共享包的实际应用程序(例如 app.mywebsite.com 客户端渲染)、仅使用共享设计系统包且考虑 SEO 需求的主页 / 产品 / 登陆页面(例如由服务器端渲染或静态站点生成的 mywebsite.com),以及使用共享 UI 组件和共享设计系统包的技术文档页面(例如 docs.mywebsite.com)。

image.png

现已被 Vercel 收购的 Turborepo,目前就致力于在 JavaScript/TypeScript 中大肆宣传 Monorepo 方法。Turborepo 帮助开发团队在 Monorepo 中为所有应用程序和包创建构建管线。其最大亮点,就是能在本地机器或云端实现跨团队的管线内 build 缓存。

Turborepo 与 npm/yarn/pnpm 工作区(依赖项管理)和变更集(版本控制)等其他重要 Monorepo 工具相结合,共同为这部分开发生态吸引到了全球 Web 社区的目光。Turborepo 的竞争对手包括 Nx、Rush 和 Lerna(一段时间停止维护,后被 Nx 开发商 Nrwl 所收购)。

六、实用工具优先CSS

对这波趋势,喜欢的超喜欢、讨厌的特讨厌。Tailwind CSS 是实用工具优先 CSS 的典型代表。一方面,开发人员讨厌它的存在令 UI 代码显得冗长;但另一方面,开发者又喜欢它出色的开发体验。作为直接受众,开发人员只需要在项目中进行一次配置,即可立即在 HTML 中使用其预定义的 CSS。

但随着近期服务器端渲染(SSR)的兴起,这种关于实用工具优先 CSS 的爱恨割裂有望彻底结束。几年来,像 Styled Components(SC)和 Emotion 这样的 CSS-in-JS 解决方案,一直是现代基于组件的 Web 应用程序样式的主导力量。然而,如果说 SSR 世界始终以性能为至高目标,那 CSS-in-JS 的存在本身就是反性能的:它会让包更加臃肿(SC 为 12.7 kB,Emotion 为 7.9 kB),而且在插入 DOM 前的 CSS 序列化也会带来额外的运行时开销。

因此,我们可能会看到开发人员转向对 SSR 更友好的解决方案,例如将实用工具优先 CSS(例如 Tailwind CSS、UnoCSS)与预定义的 UI 组件(例如 DaisyUI)配对,使用 CSS 模块等其他同样流行的替代方案,或者选择零运行时 / 编译时 CSS-in-JS 类方案(例如 vanilla-extract、linaria、astroturf、complied 等)。

七、TypeScript类型安全

从 JavaScript 到 TypeScript 的演变已经势不可挡。在这场席卷整个 Web 开发世界的大迁移中,全栈应用的端到端类型安全无疑是一大核心驱力。这个概念的实现与通信层(API)密切相关,因为通信层需要将类型化的实体(例如 type User、type BlogPost 等)从服务器桥接至客户端应用程序。

在涉及客户端 -0 服务器通信的 Web 开发中,常见的选项是 REST 和 GraphQL。二者能与 OpenAPI for REST 和 GraphQL Code Generator for GraphQL 配合使用,为前端应用程序生成类型化的 schema 文件。

除此之外,还有一个名为 tRPC 的类型安全 API 的后起之秀,它已经证明自己完全有能力成为 REST/GraphQL 的替代方案。如果您已经使用了前端和后端共享代码的 TypeScript Monorepo,tRPC 允许大家将所有类型从后端导出至前端应用程序,过程中无需生成任何类型化 schema。之后,前端只须在后台通过 HTTP 连接的类型化函数即可调用后端 API,实现客户端 - 服务器间通信。未来,全栈应用程序的总体趋势一定会转向这种类型安全解决方案。当然,作为其中的典型代表,tRPC、Zod、PrismatTanStack Router 都能在应用程序边缘提供类型安全保障。

八、构建工具

在 React-land 中,create-react-app(CRA)曾多年占据主导。这在当时掀起了一场小小的革命,因为初学者获得了一个随时可用的 React 入门项目,不再需要使用 React 配置自定义 Webpack,不过过去短短一年之间,Webpack 却在迅速变的过时,随之兴起的是Vite。

image.png

Vite 虽然是单页应用程序(SPA)领域的新秀,但却能跟所有流行框架(例如 React.js)配合构建入门项目。作为 Vue.js 缔造者尤雨溪的又一力作,Vite 的定位是下一代前端工具。在引擎盖之下,它从 esbuild 处继承了强大的功能;而且跟其他 JavaScript 打包器相比,它是用 GO 编写的,因此打包依赖项的速度能达到竞争对手(例如 Webpack)的 10 到 100 倍。

Vite 的生态系统是伴随着 Vitest(Jest 的测试替代方案)等新增功能而蓬勃发展,同时 Vercel 的 Turbopack 等同类竞争方案近期也开始涌现。Turbopack 被称为 Webpack 的继任者,因为它是由 Webpack 的缔造者 Tobias Koppers 牵头开发完成。由于 Next.js 既是 Webpack 的现用户,一边又是 Turbopack 的开发商,所以预计 Next.js 和 Turbopack 在后续将成为紧密关联的一对 Web 组合。

九、AI 驱动开发

AI 最终会消灭开发者的工作岗位吗?这个问题还没有答案,但 AI 驱动开发确实在 2022 年内成为了现实。随着 GitHub Copilot 的发布,开发者们能够在自己喜爱的各种 IDE 中与 AI 助手结对。其使用过程与常规编码或者注释编写没什么区别,GitHub Copilot 会自动补全细节以尽量提升代码质量。

还不止于此:OpenAI 的 ChatGPT 是一套高度通用的语言模型,而且在编程领域也有不俗表现。没错,ChatGPT 既能回答形式多样的自由提问,也能生成颇为靠谱的开发成果。不少开发者不知不觉减少了对 Stack Overflow 的访问,转而跟 ChatGPT 讨论技术问题。在多数情况下,ChatGPT 都能以搜索引擎替代品的姿态提供非常有用的答案(虽然还称不上完美)。相较于存在大量 SEO 垃圾、甚至跟开发毫无关联的广告内容,ChatGPT 的使用感受相较于传统搜索引擎提升了一大截。

不过需要注意的是,这种短期收益也许会带来深远的危害。宏观来讲,AI 创建的内容可能、甚至可以说一定会危害整个互联网。以往手动创建的 SEO 宣传内容已经是个大难题,未来没人拦得住 ChatGPT 以人类无法比拟的效率自动生成更多 SEO 垃圾。如果 ChatGPT 自己在训练中也继续使用这些垃圾内容,后果将不堪设想。

还有一些我觉得很重要,但未被列入Web开发的重要趋势。首先,Tauri 作为 Electron 的替代品开始进入 JavaScript/CSS/HTML 实现的桌面应用程序;Playwright 正成为 Cypress 的 E2E 测试替代品;Warp 与 Fig 有望成为下一代终端;CSS 容器查询则作为 CSS 媒体查询的响应式设计替代方案;最后,htmx 作为富 HTML 格式,能够不借助 JavaScript 创建出交互式用户界面。总之,以上只是我的个人整理,感兴趣的朋友不妨自行探究更多细节。

参考文档:https://www.robinwieruch.de/web-development-trends/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/28380.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RHCE shell 作业一

1. 设置邮箱 [rootserver ~]# yum install s-nail -y [rootserver ~]# vim /etc/s-nail.rc 编写脚本 [rootserver ~]# vim homework1.sh 设置定时任务 [rootserver ~]# vim /etc/crontab 2. [rootserver ~]# vim homework2.sh 测试: 3. [rootserve…

一文让你了解appium自动化的工作原理

目录 前言: 一、Appium加载的过程图解 二、初步认识appium工作过程 三、bootstrap介绍 四、所使用的技术 五、Capabilities 六、自我理解的工作原理 前言: Appium是一个流行的开源自动化测试框架,支持移动应用程序的自动化测试。 一…

进程管道:父进程和子进程

在接下来的对pipe调用的研究中,我们将学习如何在子进程中运行一个与其父进程完全不同的另外一个程序,而不是仅仅运行一个相同程序。我们用exec调用来完成这一工作。这里的一个难点是,通过exec调用的进程需要知道应该访问哪个文件描述符。在前…

MMPretrain

title: mmpretrain实战 date: 2023-06-07 16:04:01 tags: [image classification,mmlab] mmpretrain实战 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ccTl9bOl-1686129437336)(null)] 主要讲解了安装,还有使用教程.安装教程直接参考官网.下面讲…

pikachu靶场-../../(目录遍历)

目录遍历, 也叫路径遍历, 由于web服务器或者web应用程序对用户输入的文件名称的安全性验证不足而导致的一种安全漏洞,使得攻击者通过利用一些特殊字符就可以绕过服务器的安全限制,访问任意的文件 (可以是web根目录以外的文件),甚至…

pytorch深度学习框架—torch.nn模块(二)

pytorch深度学习框架—torch.nn模块(二) 激活函数 pytorch中提供了十几种激活函数,常见的激活函数通常为S形激活函数(Sigmoid)双曲正切激活函数(Tanh) 和线性修正单元(ReLu)激活函数等 层对应的…

Linux笔记

版本用的是CentOS7最min版 安装JDK:安装上传工具包:自动安装 yum install lrzsz -y 上传本地文件: rz -be 解压jdk: tar -zxvf jdk-8u371-linux-x64.tar.gz -z 用gzip来压缩/解压缩文件,加上该选项后可以将档案…

关于 vue2 后台管理系统构建 vue2+mock.js 的经典案例

一,初识 Mock.js 1.什么是 mock.js: 主要是模拟数据生成器,可以生成随机数据,拦截器 Ajax 请求 2.为什么要使用 mock.js 由于很多学生在学习过程中,后端还没有做好接口,写好接口文档,有了mock.js 前端就…

如何识别二叉树的“亲戚”?——探秘判断子树的奥妙

本篇博客会讲解力扣“572. 另一棵树的子树”的解题思路,这是题目链接。先来审题: 本题的思路是:使用递归,把大问题化作小问题。 先来思考:如何判断q是不是p的子树呢? q是p的子树有3种情况,分别…

MyBatis操作数据库(查询功能)

目录 一、MyBatis的概念 二、配置MyBits环境 三、 MyBatis连接数据库查询操作(示例) 创建MySQL数据库表 配置MyBatis 配置连接数据库和MyBatis xml文件 ​编辑 四、添加业务代码 实体类entity 数据持久层mapper 创建接口类 创建xml文件 服务层…

Spring Security--会话管理

就像登录qq一样,一个手机登录会将另外一个手机挤下线,这个就叫会话管理。 这个东西非常简单,在默认情况下可以登录n多次,一旦开启,就不允许登录多个。 什么是一个会话。 我们简单理解就是一个浏览器的同一个用户算一…

汉明码(Hamming Code)底层原理

汉明码(Hamming Code)底层原理 3Blue1Brown:Hamming Code【Part1】 3Blue1Brown:Hamming Code【Part2】 Hamming Code如何检查错误和定位错误? 检查错误通过奇校验或偶校验确定是否发生错误 定位错误通过依次对行和列…

将递归函数转成非递归函数的通用方法

看到过一道非常不错的面试题:不支持递归的程序语言如何实现递归程序? 之所以说这道题好,是因为: 首先,它不是纯粹考概念和死记硬背,求职者在回答问题之前需要进行一定的思考; 其次&#xff0c…

Debezium系列之:记录一次生产环境SQLServer数据库删除日志文件造成debezium connector数据不采集的解决方法

Debezium系列之:记录一次生产环境SQLServer数据库删除日志文件造成debezium connector数据不采集的解决方法 一、背景二、快速定位问题三、详细的解决步骤四、确认debezium connector恢复对数据库的数据采集五、经验总结一、背景 SQLServer数据库的日志把磁盘打满了,需要删除…

JAVA 实现 Redis 发布订阅

Redis 发布订阅 发布订阅:消息发布者发布消息 和 消息订阅者接收消息,两者之间通过某种媒介联系起来 例如订杂志,当自己订阅了爱格杂志,每个月会发刊一本。到发布的时候派送员将杂志送到自己手上就能看到杂志内容。只有我们订阅了…

C语言之结构体讲解

目录 结构体类型的声明 结构体初始化 结构体成员访问 结构体传参 对于上期指针初阶(2)我们后期还会讲数组指针是什么?大家可以先思考一下,后期我们会讲 1.结构体的声明 结构是一些值的集合,这些值被称为成员变量&am…

第二类曲线积分

文章目录 第二类曲线积分一、向量场是什么?二、向量场可视化三、计算1. 计算方式一2. 计算方式二 第二类曲线积分 因为之前学习第二类曲线的时候,不是很理解;所以最近看了mit的多元微积分课程,做一些课程笔记。 一、向量场是什么…

字符集和java的编码与解码

一、ASCII和GBK字符集 计算机存储一个英文字符需要一个字节。 ASCII字符集,包括128(0000000B~1111111B)个数据,存储英文字母和字符,对于欧美国家够用。 例如,存储字符’a’,查询ASCII得到为97&a…

C语言中的基本数据类型

C语言中的基本数据类型分别为以下几种 整型、浮点型、字符类型 整型又分为整型int、短整型short、长整型long 浮点型分为单精度浮点型float、双精度浮点型double 1、短整型short 2.整型 3.长整型 短整型、长整型、整形都是表示整形的,并且输出结果也都为10&…

【大数据之Hive】十一、Hive-HQL查询之基本查询

基础语法 select [all | distinct] select_expr,select_expr, ...from table)name --从什么表查[where where_condition] --过滤[group by col_list] --分组查询[having col_list] --分组后过滤[order by col_list] --排序[cluster by col_list | …