阅读 2326

我为什么选择 Svelte 来开发我们的官网

起因

这段时间我们公司的官网准备改版。因为需要支持IE9以上的浏览器,之前是我们使用了ejs进行开发,但是发现ejs支持的写法并不多,像一些模版复用起来并不方便, 这次打算重新找一个框架进行开发。于是我的同事给我推荐了Svelte,我了解之后立马就被种草了,非常适合这次场景开发,这次官网开发就决定是它了。

优势

更少的代码量

Svelte中的写法设计的更人性化,相比其他框架可以在开发中只需更少的代码。 在Svelte官网它们中举了个例子,当声明一个组件状态时:

这是React的代码

const [count, setCount] = useState(0);

function increment() {
  setCount(count + 1);
}
复制代码

这是Svelte的代码

let count = 0;

function increment() {
  count += 1;
}
复制代码

相比React简洁了许多,而且感觉就像我们平时写的JavaScript一样,更方便阅读。

无Virtual Dom

我们都知道Vue,React中都使用到了Virtual Dom来对Dom进行更新。Virtual Dom会把页面Dom变为树结构的数据存在内存中,每次修改组件中的状态时,会生成一个新的Virtual Dom与旧的Virtual Dom进行对比生成一个补丁,等到真正修改完毕时在去更新真实的dom节点。当然框架中的Virtual Dom要比我说的实现的复杂的多。

但是Svelte修改更新Dom节点使用了纯JavaScrip实现不依赖任何框架。 Svelte因为不依赖Virtual Dom因此初始化和更新时工作都小了许多,从而使页面启动和运行都会更加迅速。

打包体积更小

像Vue和React是基于运行时的框架,打包出来的代码都会包含它自身的runtime代码。 而Svelte的做法则是在编译时减少运行时的代码,尽量减小打包后代码中包含的runtime代码。而且像上面介绍的他不基于Virtual Dom,因此Svelte打包后的代码体积相比其他框架的小许多。

响应式

Svelte它也为我们实现了像Vue那样的状态响应式,当某个状态修改状态时组件就会进行更新。这可以让我们更好的封装组件。而且写法就和正常声明变量一样,但是Svelte会在编译时为你自动注入响应式代码。

count += 1;
复制代码

Svelte在编译时,当编译时自动加上响应式代码

count += 1; $$invalidate('count', count);
复制代码

为什么使用Svelte

Virtual Dom在复杂的交互与渲染中能带来非常不错的性能提升,能为页面渲染减少重流重绘的次数。

但是通常官网为静态网页,用来向人们来展示公司发展业务。通常不会有一些非常复杂的交互与渲染,更多的是展示图片和文字内容。

而简单交互使用Virtual Dom反而效果不能带来很好的效果,因为简单的交互通过修改Dom节点却要经过Virtual Dom中非常复杂Diff工作才对Dom进行更新其实是没有必要的,所以并不是很需要Virtual Dom。

然后用Svelte打包之后的代码体积也会小许多,这对SEO与用户体验上的都会有很好的提升。

而且我发现Vite也支持Svelte,用Vite开发可以使开发效率又可以提升一倍。

预渲染的实现过程

但是我发现Svelte只支持JS渲染和SSR渲染,因为我们官网纯静态页面每次访问的页面内容都是固定不变的,因此不需要使用SSR,但是也不能是JS渲染,因为官网是很非常注重SEO,网站内容需要被SEO爬虫抓取,当页面是JS渲染的话,SEO爬虫会是看不懂JavaScript导致不会对我们页面进行爬取。

那该怎么办呢,我们需要把页面部署上服务器前先在本地把所有渲染一遍,这也叫预渲染。当用户打开页面时直接展示已经渲染好的HTML内容。

实现是用的Vite打包工具,但是如果用Rollup或者Webpack其实思路也是一样的。

流程图

流程图.jpg

  • 第一步 vite build

编译JS渲染版本,是为了得到编译后的页面和所需资源,我让它们会导出到dist文件夹, pageA和pageB分别是两个页面,assets是打包后页面中的所需引用资源文件夹。

WeChatbb5b6f74126fe703a07de376713ec4d1.png

  • 第二步 vite build --ssr

打包得到页面SSR的代码,编译后我让它们导出到.ssr文件夹,里面得到可以得到每个页面render函数的js文件,其实pageA.js和pageB.js是这分别这两个页面的可以在服务端用的render函数js,当调用render函数就可以获得页面渲染的html字符串

image.png

  • 第三步 执行执行 /script/generate.js

这个是我自己写的js脚本,其实流程也是很简单

首先提前要说的是,我会在步骤一前每个页面的html的body中写上这样一个注释,用来替换调用render函数完成后的html字符串。

<body>
    <div id="app">
       <!-- 要被渲染后的html替换的暂位符 -->
      <!-- ssr-body -->
    </div>
<body> 
复制代码

这是这段脚本执行的流程

流程图 (2).jpg

  • 第四步 使用gulp对html进行压缩

  • 编译完成 最终结果都在 /dist文件夹中

GitHub

这是我这次开发使用的项目模版。

感兴趣的同学也可以直接到GitHub项目上看实现代码,实现其实很简单的。

github.com/Feng3737121…

总结

还记得尤雨溪大大在一次知乎Live中提过不提场景对比框架就是耍流氓。

Svelte在开发一些静态页面的或者没有很多复杂交互的场景还是很值得尝试的。

但如果像中大型项目也许还是Vue、React这些框架优势比较大。

希望大家可以项目中选择最适合使用的框架。

文章分类
前端
文章标签