大前端学习 -- 服务端渲染 学习笔记

服务端渲染

文章内容输出来源:大前端高薪训练营

一、概述

1. 基于客户端渲染的前端框架

  • Angular
  • React
  • Vue

2. SPA单页应用

优点:

  • 用户体验好
  • 开发效率高
  • 渲染性能好
  • 可维护性好

缺点:

  • 首屏渲染时间长
  • 不利于SEO

3. 借鉴传统的服务器渲染

在这里插入图片描述

4. 客户端激活为SPA

在这里插入图片描述

5. 同构应用

  • 通过服务端渲染首屏直出,解决SPA应用首屏渲染慢以及不利于SEO问题
  • 通过客户端渲染结果页面内容交互得到更好的用户体验
  • 这种方式通常称之为现代化的服务端渲染,也叫同构渲染
  • 这种方式构建的应用称之为服务端渲染应用或者是同构应用

6. 相关概念

  • 什么是渲染:把数据和模板拼接在一起。渲染的本质就是字符串的解析替换。
  • 传统的服务端渲染:早期的web页面渲染都是在服务端进行的
  • 客户端渲染
  • 现代化的服务端渲染(同构渲染)

二、传统的服务端渲染(SSR)

1. 案例

在这里插入图片描述

index.js

const express = require('express')
const fs = require('fs')
const template = require('art-template')

const app = express()

app.get('/', (req, res) => {
    
    
  // 1. 获取页面模板
  const templateStr = fs.readFileSync('./index.html', 'utf-8')
  console.log(templateStr)
  // 2. 获取数据
  const data = JSON.parse(fs.readFileSync('./data.json', 'utf-8'))
  console.log(data)
  // 3. 渲染:数据 + 模板 = 最终结果
  const html = template.render(templateStr, data)
  console.log(html)
  // 4. 把渲染结果发送给客户端
  res.send(html)
})

app.listen(8081, () => {
    
    
  console.log('running......')
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>传统的服务端渲染示例</title>
</head>
<body>
  <h1>
    传统的服务端渲染示例
  </h1>
  <h2>{
   
   {title}}</h2>
  <ul>
    {
   
   { each data }}
    <li>{
   
   {$value.name}}</li>
    {
   
   { /each }}
  </ul>
</body>
</html>

data.json

{
    
    
  "data": [
    {
    
    
      "id": 1,
      "name": "jal"
    },
    {
    
    
      "id": 2,
      "name": "wyb"
    }
  ],
  "title": "王一博0805生日快乐"
}

2. 缺点

  • 前后端代码完全耦合在一起,不利于开发和维护
  • 前端没有足够发挥空间
  • 服务端压力大
  • 用户体验一般

三、客户端渲染(CSR)

之前服务端渲染的缺点,随着客户端Ajax技术的普及得到了有效的解决,Ajax使得客户端动态获取数据成为可能,因此,服务端渲染的工作来到了客户端。

以Vue.js项目为例系统了解客户端渲染流程。

  • 后端负责处理数据接口
  • 前端负责将接口数据渲染到页面中

前端更为独立,不再受限于后端。

但客户端渲染也存在一些明显的不足:

  • 首屏渲染慢:因为客户端渲染至少发起Http请求三次,第一次是请求页面,第二次是请求页面里的JS脚本,第三次是动态数据请求。

  • 不利于SEO:因为客户端渲染的内容都是由JS生成的,而搜索引擎只会请求网络路径的html,不会去将html里的JS脚本再去请求做解析处理,因此搜索引擎获取到的首屏是空的,单页应用SEO几乎为0。

    // 搜索引擎是怎么获取网页内容的?
    const http = require('http')
    
    http.get('http://localhost:8080', res => {
          
          
      let data = ''
      res.on('data', chunk => {
          
          
        data += chunk
      })
      res.on('end', () => {
          
          
        console.log(data)
      })
    })
    
    /*
    打印结果:
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="/favicon.ico">
        <title>vuex-cart-demo-template</title>
      <link href="/js/about.js" rel="prefetch"><link href="/js/app.js" rel="preload" as="script"><link href="/js/chunk-vendors.js" rel="preload" as="script"></head>
      <body>
        <noscript>
          <strong>We're sorry but vuex-cart-demo-template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      <script type="text/javascript" src="/js/chunk-vendors.js"></script><script type="text/javascript" src="/js/app.js"></script></body>
    </html>
    */
    

四、现代化的服务端渲染(同构渲染)

1. 同构渲染 = 后端渲染 + 前端渲染

  • 基于React、Vue等框架,客户端渲染和服务端渲染的结合
    • 在客户端执行一次,用户实现服务器端渲染(首屏直出)
    • 在客户端再执行一次,用于接管页面交互
  • 核心解决SEO和首屏渲染慢的问题
  • 拥有传统服务端渲染的优点,也有客户端渲染的优点。

2. 如何实现同构渲染?

  • 使用Vue、React等框架的官方解决方案
    • 优点:有助于理解原理
    • 缺点:需要搭建环境
  • 使用第三方解决方案
    • React生态的Next.js
    • Vue生态的Nuxt.js

3. 以Vue生态的Nuxt.js为例演示同构渲染应用

  1. 创建一个文件夹,然后进入文件夹执行yarn init生成包管理器

  2. 然后执行yarn add nuxt安装Nuxt

  3. 在package.json增加scripts脚本命令"dev": "nuxt"

  4. 创建pages文件夹,在这个文件夹中创建index.vue文件和about.vue文件,nuxt会根据pages路径自动生成路由。

    // index.vue
    <template>
      <div>
        <h1>首页</h1>
      </div>
    </template>
    
    <script>
    export default {
           
           
    
    }
    </script>
    
    <style scoped>
    
    </style>
    
    // about.vue
    <template>
      <div>
        <h1>About</h1>
      </div>
    </template>
    
    <script>
    export default {
           
           
    
    }
    </script>
    
    <style scoped>
    
    </style>
    
    
  5. 执行yarn dev运行这个Nuxt项目,打开localhost:3000端口,默认是pages/index.vue页面,然后访问localhost:3000/about访问的是pages/about.vue页面

  6. 在pages/index.vue页面中通过asyncData方法获取json数据,静态的json数据文件是放在static目录下的。Nuxt中提供的钩子函数asyncData(),专门用于获取服务端渲染的数据。axios不要忘了安装:yarn add axios

    // pages/index.vue
    <template>
      <div id="app">
        <h2>{
         
         { title }}</h2>
        <ul>
          <li
            v-for="item in data"
            :key="item.id"
          >{
         
         { item.name }}</li>
        </ul>
      </div>
    </template>
    
    <script>
    import axios from 'axios'
    
    export default {
           
           
      name: 'Home',
      components: {
           
           },
      // Nuxt中提供一个钩子函数`asyncData()`,专门用于获取服务端渲染的数据。
      async asyncData () {
           
           
        const {
           
            data } = await axios({
           
           
          method: 'GET',
          // 注意此处的URL要指定当前端口,否则默认会去服务端的80端口去查找。
          url: 'http://localhost:3000/data.json'
        })
        // 这里返回的数据会和data () {} 中的数据合并到一起给页面使用
        return data
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
    

    static/data.json

    {
          
          
      "data": [
        {
          
          
          "id": 1,
          "name": "jal"
        },
        {
          
          
          "id": 2,
          "name": "wyb"
        }
      ],
      "title": "王一博0805生日快乐"
    }
    
  7. 一次请求就拿到了完整页面,Nuxt的服务端渲染方案解决了首屏渲染慢的问题和SEO的问题

在这里插入图片描述

  1. Nuxt生成的是SPA单页应用,可以通过增加路由导航看出来,Home和About两个组件切换时页面没有刷新。创建一个文件夹layouts,然后在这个文件夹中创建一个default.vue文件,这个文件名是固定要求的,不能随意取

    <template>
    <div>
    <!-- 路由出口 -->
      <ul>
        <li>
          <!-- 类似于 router-link,用于单页面应用导航 -->
          <nuxt-link to="/">Home</nuxt-link>
        </li>
        <li>
          <!-- 类似于 router-link,用于单页面应用导航 -->
          <nuxt-link to="/about">About</nuxt-link>
        </li>
      </ul>
    <!-- 子页面出口 -->
      <nuxt />
    </div>
    </template>
    
    <script>
    export default {
           
           
    
    }
    </script>
    
    <style scoped>
    
    </style>
    
    

4. 同构渲染应用的问题

  • 开发条件有限

    • 浏览器特定的代码只能在某些生命周期钩子函数中使用
    • 一些外部扩展库可能需要特殊处理才能在服务端渲染应用中运行
    • 不能再服务端渲染期间操作DOM
    • 某些代码操作需要区分运行环境
  • 涉及构建设置和部署的更多要求

    客户端渲染 同构渲染
    构建 仅构建客户端应用即可 需要构建两个端
    部署 可以部署在任意web服务器中 只能部署在Node.js Server中
  • 更多的服务器端负载

    • 在Node中渲染完整的应用程序,相比仅仅提供静态文件服务器,需要大量占用CPU资源
    • 如果应用在高流量环境下使用,需要准备相应的服务器负载
    • 需要更多的服务端渲染优化工作处理

5. 服务端渲染使用建议

  • 首屏渲染速度是否真的重要
  • 是否真的需要SEO

猜你喜欢

转载自blog.csdn.net/jal517486222/article/details/107809945