开篇
你是否曾经为前端的性能问题而烦恼?
你是否曾经想过如何优化前端渲染速度?
那么,今天我要和大家分享的就是我从“前端”到“前端ssr”的经历,希望能给大家带来一些启示和乐趣。
序言
随着业务场景不断变化,网站越来越复杂,需要更好的性能和用户体验。传统前端应用程序一般是基于
AJAX
技术实现的,常见的框架如AngularJS
、React
和Vue.js
等。这些框架将数据和视图分离,视图由前端框架生成并静态呈现,然后使用AJAX
从服务器获取数据并更改应用程序的状态和UI。然而,由于这种方式需要在前端执行大量的计算和DOM操作,因此它们容易遇到性能瓶颈。由于页面初始加载速度慢,对
SEO
不友好以及SSR
技术的兴起,同构应用程序越来越受欢迎。同构应用程序通过将服务器和客户端合并以提供更好的性能和用户体验。
服务器端渲染(SSR)
是一个重要的技术,能够在服务器端生成初始HTML并将其发送到客户端,以减少初始加载时间和提高SEO
。本文将介绍前端SSR以及如何使用Vue.js
和Nuxt.js
实现它。
什么是前端SSR?
对于传统前端应用程序,是由JavaScript引擎
在客户端执行。这意味着在服务器将HTML
发送到浏览器之前,需要下载并执行一段JavaScript代码。传统的SPA应用程序有一个单页面作为整个应用程序所需的唯一HTML文件,其中所有的数据均在浏览器中完成处理,这样,在加载初始应用程序时,实际上需要下载的只是该单个HTML文件。虽然这种方式易于维护和开发,但这种方式在不同方面存在一些限制。例如:
- SEO问题:由于搜索引擎会按照JavaScript执行方式索引搜索网站,无法判断单个页面是什么,因此不利于SEO。
- 第一次请求时间太长:由于单页面包含大量JavaScript,渲染 HTML需要等待所有JavaScript文件都下载和执行完毕,这会增加加载次数和时间。
- 不利于内容管理:前端开发人员必须了解CMS并能够生成HTML模板,这样,能够很快地将网站上的所有内容与前端集成起来。
- 微笑面对网络环境:由于浏览器只会在我们正在浏览的屏幕之前渲染页面,所以如果应用程序中有大量的子组件、复杂的CSS和JavaScript逻辑等,则网站可能会显示性能问题。
对于这些限制,服务器端渲染(SSR)
是解决方法之一。SSR将初始请求到服务器端时的HTML渲染为字符串并在初始加载时发送
。这样可以解决前端SPA黑白屏和SEO问题,加快加载速度,同时维护前端应用程序的开发性和用户体验
。
有了SSR,前端应用程序在计算初始呈现之前将数据放在服务器上计算。此外,在使用SSR时,可以使用同一代码组件来进行客户端和服务器端呈现。这意味着,客户端和服务器端没有必要呈现不同的HTML代码,而是将它们放入同一代码库中,加快性能和实现HTML复用。
由于SSR只在初始加载期间运行,因此该技术非常适用于网站和应用程序中的静态页面,然而,应用程序中的交互部分应该通过浏览器端JavaScript来处理。
Vue.js以及SSR
Vue.js
是一种先进的JavaScript MVVM
框架。它专注于实现不同层的无缝集成,包括视图、数据和状态
。Vue.js是一个响应式的框架
,当应用程序状态发生变化时,视图将自动更新。Scott Feinberg
, Software Secretary at Dropbox- Backbone.js
与 Vue.js
简单比较:
Vue.js
包含一个SSR
解决方案,叫做 Nuxt.js 。Nuxt.js
使用Vue.js并在此基础上提供具有独特功能的SSR框架。Nuxt.js
允许开发人员轻松地使用WebPack
等自动化工具,并将应用程序渲染为静态文件。这意味着,开发人员可以快速地创建SSR应用程序并依赖于内置的支持,例如静态资源处理、CSS预处理器、模块化框架等。
Nuxt.js基本原理
Nuxt.js的基本工作原理如下:
- Nuxt.js使用
Webpack
和Babel
自动化工具来编译应用程序,并将其转换为应用程序服务器能够使用的有效代码。- 使用Nuxt.js,开发人员可以使用Vue.js组件来控制应用程序的功能。(可以使用公共组件来最大限度地减少重复代码。)
- 开发人员使用
static asyncData()函数
来在异步方式下操作数据(仅在初始加载页面时发生),并生成初始HTML。- 使用
dynamic asyncData()函数
来在应用程序生命周期内仅在需要时操作数据,例如通过ajax调用API,直到页面处于活动状态且需要更新时。- Nuxt.js使用
express.js
或Koa.js
作为服务器。开发人员将使用这些框架的中间件来定义应用程序的请求路由。
使用Nuxt.js创建基本SSR应用程序
在下面的示例中,以最简单的形式创建了一个Nuxt.js应用程序
,并在服务器端呈现了一个页面。应用程序定义了仅包含单个字符串的layouts/default.vue布局。
在layouts/default.vue
文件中定义布局结构:
<template>
<div>
<nuxt />
</div>
</template>
在pages/index.vue
中定义页面内容:
<template>
<h1>{{ title }}</h1>
</template>
<script>
export default {
asyncData() {
return { title: 'Hello world!' }
}
}
</script>
使用Nuxt.js进行数据获取
在Nuxt.js中,前后端代码是共享的
,代码可以在服务器端和客户端之间共享。由于此代码是共享的,因此需要最大限度地减少代码冗余并确保代码具备可重用性
。
在Nuxt.js中,asyncData函数
用于在页面在server
下钩子时获取数据。这个函数在组件实例化之前调用,从而直接设置组件的数据。虽然命名类似,但与vue中的created或mounted生命周期不同之处是,只有在server端渲染时才会调用asyncData,待到页面挂载到DOM上时,就不再执行
。
下面的示例展示了如何在Nuxt.js中获取远程数据。在pages/index.vue
中:
<template>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</template>
<script>
export default {
async asyncData({ $axios }) {
const response = await $axios.get('https://jsonplaceholder.typicode.com/posts')
return { posts: response.data }
}
}
</script>
在Nuxt.js中创建CSS样式
在Nuxt.js中,可以将CSS样式存储在单独的CSS文件中
,以便在服务器端呈现过程中优化应用程序的加载速度。这些CSS文件存储在assets/css
中,然后在nuxt.config.js
文件中定义:
export default {
css: ['~/assets/css/style.css']
}
此外,可以使用SSR技术通过vue-server-renderer
插件直接将CSS嵌入HTML文件中,以便在初始加载时呈现。以下是使用Nuxt.js在HTML中呈现CSS样式的一个示例:
<template>
<div class="about">
<h1 class="title">{{ message }}</h1>
</div>
</template>
<style scoped>
.title {
font-size: 3rem;
margin-bottom: 2rem;
text-align: center;
}
</style>
在Nuxt.js中包含Meta标签
通过使用Nuxt.js的Head标签
插件,可以添加/删除meta标签和组织顺序以便搜索引擎优化。以下是包含meta标签的一个示例:
<template>
<div>
<h1>{{ title }}</h1>
<p>{{ description }}</p>
</div>
</template>
<script>
export default {
head() {
return {
title: this.title,
meta: [
{ hid: 'description', name: 'description', content: this.description }
]
}
},
data() {
return {
title: 'My Page',
description: 'Here is a short description of my page.'
}
}
}
</script>
在Nuxt.js中组合布局
在Nuxt.js中,需要在整个应用程序中多次使用布局时,可以使用布局组件。这些组件使您可以构建具有多个页面的应用程序,并在颜色、类型和通用布局。
Nuxt.js 如何进行前端 SSR
创建Nuxt应用
:使用npx命令创建一个Nuxt应用:
npx create-nuxt-app my-app
配置Nuxt.js的设置
:在Nuxt应用中,可在nuxt.config.js
文件中进行一些必要的配置,如头部信息(meta)的设置、CSS的打包、页面压缩等设置。
export default {
// 设置应用的头部信息
head: {
title: 'My Nuxt App',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'My cool Nuxt.js app!' }
]
},
// 自定义应用的加载样式
loading: { color: '#000' },
// 全局 CSS 样式
css: [
'~/assets/css/main.css'
],
// 构建配置
build: {
// 提取 CSS 到单独的文件
extractCSS: true,
// 最小化 JavaScript 和 CSS
minimize: true,
// 使用 CDN 加载第三方库
publicPath: 'https://cdn.example.com/assets/'
}
}
在上述配置中,head
属性用于设置应用的头部信息,比如title
,meta
标签等。loading
属性用于设置应用的加载样式,css
属性用于定义全局 CSS 样式,build
属性用于配置构建过程。在构建配置中,可以设置extractCSS
参数将 CSS 提取到单独的文件中,可以设置minimize
参数最小化 JavaScript 和 CSS,还可以使用publicPath
参数加载第三方库。
-
创建动态路由
:在Nuxt.js中,使用动态路由可以根据不同的参数展示不同的页面。在
pages
目录下添加一个名称为[_id].vue
的文件即可创建动态路由,其中_id
是参数名,同时该文件夹下必须包含一个index.vue
页面。具体代码示例如下:
<!-- pages/_id/index.vue -->
<template>
<div>
<h1>展示ID为 {{ id }} 的页面</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
asyncData({ params }) {
return { id: params.id, message: 'Hello Nuxt.js!' }
}
}
</script>
以上代码定义了一个名为_id
的动态路由,用于根据不同的id
参数展示不同的页面。在该Vue组件中,使用了asyncData
方法来获取渲染所需的数据,并将其注入到组件的data
中。在模板中,使用{{ id }}
和{{ message }}
来展示数据。
-
对应路由和数据实现SSR
:在Nuxt应用中,Vue组件会被转换成HTML字符串,然后由服务器发送到客户端。因此,在进行前端SSR时,需要在组件中添加一个静态的
asyncData
方法,来获取服务端渲染所需的数据,并将其注入到组件的data
中。如下面的例子展示如何在Vue组件中添加asyncData方法:具体代码示例如下:
<!-- pages/index.vue -->
<template>
<div>
<h1>{{ title }}</h1>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
asyncData() {
return { title: 'Hello Nuxt.js!', message: 'Welcome to my app!' }
}
}
</script>
在上面的代码中,asyncData
方法会在服务器端执行,并将返回的数据注入到组件的data
中。在模板中,使用{{ title }}
和{{ message }}
来展示数据。
需要注意的是,当页面被访问时,asyncData
方法会在服务器端执行,并将返回的数据注入到组件的data
中。在客户端渲染时,asyncData
方法会在组件切换前执行,并且不会重新请求数据。这可以提高应用程序的性能并提高用户体验。
需要注意的事项
数据获取的异步性
:
在编写Vue组件时,需要注意异步数据的获取。在服务端渲染时,需要将异步数据获取的过程放在asyncData
方法中,并将返回的数据注入到组件的data
中。需要注意的是,在客户端渲染时,asyncData
方法会在组件切换前执行,并且不会重新请求数据。
路由参数的使用
:
在使用Nuxt.js的动态路由时,需要注意使用路由参数。可以通过this.$route.params
来获取路由参数。需要注意的是,在Nuxt.js应用程序中,由于使用了服务器端渲染,可能需要在路由参数中添加初始值,以防止服务器端渲染时参数未定义的问题。
SEO的优化
:
由于Nuxt.js使用服务器端渲染,可以帮助提高SEO(搜索引擎优化)的效果。但是需要注意,在使用服务器端渲染时,需要为每个页面添加合适的meta标签,以便搜索引擎能够正确地抓取和显示内容。
应用程序的性能
:
由于Nuxt.js使用了服务器端渲染,因此可以提高应用程序的性能和用户体验。需要注意的是,在客户端渲染时,可以使用Vue.js的异步组件和路由懒加载等技术,来进一步优化应用程序的性能。
引用
Nuxt.js:www.nuxtjs.cn/
express.js:expressjs.jser.us/
Koa.js: koa.bootcss.com/
vue ssr官网文档
如果以上文章中有任何错误之处,请各位大佬不吝赐教,让我学习改正,谢谢啦~
总结
在这个快节奏的时代,前端ssr已经成为了不可或缺的一部分。希望我的经历能够帮助大家更好地理解和应用前端ssr,让我们一起为更好的用户体验而努力!