前言
前两年了解 nextjs 的时候,在掘金看了看文章:
Nextjs 是 React 服务端渲染的框架,支持多种渲染方式,如 SSR、CSR、SSG 等渲染,提供了全新的路由解决方案等,提升了首屏加载速度...
哦哦,就是在 react 基础上做优化呗,可能是对标 vite 的某种脚手架吧。
这两天又在掘金刷到了 nextjs 文章:
Nextjs 是 React 服务端渲染的框架,支持多种渲染方式,如 SSR、CSR、SSG 等渲染,提供了全新的路由解决方案等,提升了首屏加载速度...
不是哥们,怎么还是这些东西。
但是如果是一个普通框架没道理活这么久啊?不行我非得看看怎么个事。我调研后大惊,几乎不敢相信。
Next.js, 颠覆性的框架
要想知道 Next.js 为什么值得学,我们把时间往前推一下,看看以前的环境
石器时代:三板斧
最初的时代,只能写 html js css,没什么好说的
铁器时代:前端无老虎,后端称大王
jsp 出现,是十年前比较流行的方案,它允许 Java 开发者在 HTML 中嵌入 Java 代码,前端本就不高的地位更是被后端踩了又踩,贴一个简单的 jsp 给大家看看。
html
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*,java.sql.*"%>
<%@ page import="javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<html>
<head>
<title>SELECT 操作</title>
</head>
<body>
<sql:setDataSource var="snapshot" driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/RUNOOB?useUnicode=true&characterEncoding=utf-8"
user="root" password="123456"/>
<sql:query dataSource="${snapshot}" var="result">
SELECT * from websites;
</sql:query>
<h1>JSP 数据库实例 - 菜鸟教程</h1>
<table border="1" width="100%">
<tr>
<th>ID</th>
<th>站点名</th>
<th>站点地址</th>
</tr>
<c:forEach var="row" items="${result.rows}">
<tr>
<td><c:out value="${row.id}"/></td>
<td><c:out value="${row.name}"/></td>
<td><c:out value="${row.url}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
可以看到,耦合性极强 ,把前后端都放在同一个项目中,一个 jsp 中既可以写 html ,还可以调动接口,又可以读写数据库。我们访问网站时访问到的也不是 html 文件,而是直接访问 jsp 文件
很怪吧,不仅是 jsp。同一时期,还有当时号称世上最好的语言 php,也做着与 jsp 类似的事情,我们访问是.php的文件,除此以外还有 .asp .asmx 等五花八门的类型,浏览器的任务就非常重,需要适配、展示各种类型的文件,ie 它慢也有这方面的原因。
这类诡异的混合风格导致前端后端要同时在一个项目中进行开发维护,甚至有时候会出现交集,边界很模糊。
近代:前后端分离!
不过到了 2015 这个节点,es6 正式推出 ,前端功能日渐复杂,工作量逐渐大了起来,前端开发人员也逐渐走向了专业化;另一方面,W3C 在 2012 年将 XMLHttpRequest 进行了标准化,前后端终于有了标准的通信方式。
前后端的分割从此更加明确了,后端提供数据,前端做 ui。接口使用 ajax 进行通信,逐渐演变为了前后端分离的形式,摆脱了各式各样的后缀,前端终于是回到了 html,专注于使用 js 来进行动态网页的设计。
这时候的代表性库就是 jquery,一个提供了各种方便函数的库,哪个项目要是不引入一下,都觉得丢份
现代
现代的故事大家就比较熟了,webpack 横空出世,前端逐渐走向工程化,各种优秀的框架如 vue / react 慢慢被市场接受,前端也是吃上好的了。
值得一提的是,wasm 也在此时登场,不过他目前的影响没那么大
现代?
今天的主角,Next.js 登场了,它是一个全栈框架。 请注意,是全栈框架,这是我之前一直没有意识到的信息。
我们以前说的全栈一般都是:既会后端又会前端,同时做两个东西,方案大多为 springboot 框架 + 前端或者 express 框架 + 前端,本质上是两个项目分头做。
但 Next.js 它是全栈框架,你可以在这一个项目中直接完成前端 + 后端的功能。有的同学听完已经意识到了:
不对呀 imoo,这不是前面说的 jsp 模式吗,前后端混合在一起,怎么开倒车还这么兴奋呢
诶,这你就不对了。首先看 jsp 的问题:
-
前后端不分离,代码混乱
-
访问到的是 jsp 文件,应该是 html 才行
-
前端不成体系,写起来很费劲,也不好使用各类 npm 包,有种做小的感觉,主打一个能用就行。换句话说,就是被后端挤占了空间。
而 Next.js 就很好的解决了这些问题
-
代码可以分离,Next.js 的后端主要服务于页面与组件 ,而非接口。不过如果想用它访问数据库等也是 ok 的
-
访问到的依旧是 html
-
跟 vite create 出的 react 项目区别不大,使用 react 为开发语言,npm 包也无缝使用,写起来毫无痛点
-
前端为主,并且加入一些后端辅助功能
总结一下就是,在正常写 react 的基础上,增加了写后端的能力。
有没有打翻身仗的感觉?过去是写后端的时候顺手把前端写了,现在则是写前端的时候能顺手把后端写了。如果是个人开发者,可以轻松用 Next 一个项目就搞定前后端的东西,部署也极其简便。
更可贵的是,即使你完全不需要后端的能力,也可以用 Next.js 完成正常的 React 项目开发,另外即使在用 Next.js 的时候,也不耽误你调用别的后端服务,可以像正常的前端一样调接口请求。
不过性子急的同学又要问了:
不对啊 imoo,如果我不想要后端能力的话,那岂不是跟正常的 vite 框架没区别吗,我干嘛还要用 Next.js 啊
这就得提到 nextjs 与 react 的对比了。
比起 Vite create React 项目的优势
- 服务端渲染
随着网络的发展,现在网速是越来越快了,因为网络是国家出手去推动建设的。但是老百姓的手机配置却不一定跟得上,还是有一部分人拿着旧手机,本就不多的内存,开个浏览器都可能卡顿。
比如极端情况下,用 iphone4 去访问一个稍微大点的网站,大概率都会卡的动不了,网络虽然不是瓶颈,但客户会被 js 加载阻塞住。这个问题在 spa 应用上格外明显,因为需要 js 频繁的加载处理路由组件等。
这种情况下,我们利用服务端渲染来减轻客户端压力,大致原理是将 js 放在服务端执行,执行完以后直接给用户返回对应的 html 文件即可,这样对于用户来说,只是花点流量就可以大幅提升加载速度。
除此之外,有个很重要的点是,Next 可以只对部分内容进行服务端渲染,而经常变化的部分还是可以作为正常的客户端组件的,它做到了很好的分离与组合能力。
- 良好的 SEO 优化
- 首屏加载速度大幅提升
原因有二:1是通过服务端进行了加载,2是对代码进行了拆分,只加载要访问的组件,有点路由懒加载的意思。
- 更方便的路由处理
这点是开发体验上的优化,我们不需要每开一个项目就写一大堆路由文件了,按照规定的文件目录,它就可以自动生成对应的路由供你访问,非常方便。
- 后端优势
既可以调用api,又可以直接访问数据库等。值得一提的是,通过直接访问服务的方式,在前端是不会出现接口请求的,因为实际上是在后端计算完了页面才返回给你,中间那一步看不到,消除了泄露数据的风险。
- 其他
nextjs 还拥有大量好用的特性,但由于笔者接触的不多,这篇文章的目的也是为了让大家了解 Next.js 是什么东西,所以暂时写到这里。
如果这篇文章让你对 Next 有了更清晰的理解,不妨点个赞吧~