Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

服务端渲染基础(以Vue.js为例) #43

Open
janeLLLL opened this issue Dec 22, 2020 · 0 comments
Open

服务端渲染基础(以Vue.js为例) #43

janeLLLL opened this issue Dec 22, 2020 · 0 comments

Comments

@janeLLLL
Copy link
Owner

服务端渲染基础

概述

SPA单页面应用

SPA/单页富应用程序:单页Web应用,就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序。

浏览器一开始会加载必需的HTML、CSS和JavaScript,所有的操作都在这张页面上完成,都由JavaScript来控制。

  • 优点

    1. 用户体验好
    2. 渲染性能好
    3. 可维护性高
    4. 开发效率高
  • 缺点

    1. 首屏加载时间过长

      与传统服务端渲染直接获取服务端渲染好的 HTML 不同,单页应用使用 JS在客户端生成 HTML
      来呈现内容,用户需要等待客户端 JS 解析执行完成才能看到页面,这就使得首屏加载时间变长,从而
      影响用户体验

    2. 不利于SEO

      当搜索引擎爬取网站 HTML 文件时,单页应用的 HTML 没有内容,因为他它需要通过客户端 JavaScript
      解析执行才能生成网页内容,而目前的主流的搜索引擎对于这一部分内容的抓取还不是很好。


为了解决这两个缺陷,

  1. 业界借鉴了传统的服务端直出 HTML 方案,提出在服务器端执行前端框架
    (React/Vue/Angular)代码生成网页内容,然后将渲染好的网页内容返回给客户端,客户端只需要负
    责展示就可以了;

  1. 为了获得更好的用户体验,同时会在客户端将来自服务端渲染的内容激活为一个 SPA
    应用,也就是说之后的页面内容交互都是通过客户端渲染处理

同构应用

  • 通过服务端渲染首屏直出,解决首屏渲染慢以及不利于 SEO 问题
  • 通过客户端渲染接管页面内容交互得到更好的用户体验

这种方式我们称之为现代化的**服务端渲染,也叫同构渲染。所谓的同构指的就是服务端构建渲染+客户端构建渲染**。

为什么使用服务端渲染(SSR)

预渲染?

无需使用 web 服务器实时动态编译 HTML,而是使用预渲染方式,在构建时 (build time) 简单地生成针对特定路由的静态 HTML 文件

相关概念

什么是渲染

{
	"message": "hi"
}

<h1>{{message}}</h1>

↓

<h1>hi</h1>

渲染:把【数据 + 模板】拼接到一起

场景:请求后端接口数据,然后将数据通过模板绑定语法绑定到页面中,最终呈现给用户

本质:字符串的解析替换

  • 在哪里渲染?

传统的服务端渲染

Web 页面渲染都是在服务端完成的,即服务端运行过程中将所需的数据结合页面模板渲染为
HTML,响应给客户端浏览器。所以浏览器呈现出来的是直接包含内容的页面。

  • ASP、PHP、JSP

    ASP动态服务器网页(英文:Active Server Pages,简称ASP),是由微软公司开发的服务器端运行的脚本平台。

    PHP:PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。

    JSPJSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTMLXML或其他格式文档的Web网页,然后返回给请求者。

工作流程

使用Node.js模拟传统的服务端渲染模式

# 创建 http 服务
npm i express
# 服务端模板引擎
npm i art-template express-art-template
  1. 模拟后端服务文件:index.js
//模拟后端服务文件
const express = require('express')

const app = express()

app.get('/', (req, res) => {
    res.send('hello')
})

app.listen(3000, () => console.log('running'))
nodemon index.js
  1. 获取页面模板
const fs = require('fs')

const templateStr = fs.readFileSync('./index.html','utf-8')
  1. 获取数据
const data = JSON.parse(fs.readFileSync('./data.json','utf-8'))
  1. 渲染:数据 + 模板 = 最终结果

模板引擎本质:进行字符串的解析替换/但网页越来越复杂的情况下,存在很多不足

#加载第三方模板引擎
npm i art-template
    <ul>
        {{each posts}}
        <li>{{ $value.title }}</li>
        {{ /each }}
    </ul>
  1. 把渲染结果发送给客户端
res.send(templateStr)

缺点

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

客户端渲染(CSR)

  • Ajax使得客户端动态获取数据成为可能

    AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

    AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

  • 服务端渲染 → 客户端渲染

SPA 应用的基本工作流程

SPA:单页Web应用(single page web application,SPA),就是只有一张Web页面的应用,是加载单个HTML 页面并在用户与应用程序交互时动态更新该页面的Web应用程序

  • 后端:负责处理数据接口
  • 前端:负责将接口数据渲染到页面中
  • 前端更加独立,不受限于后端

Vue.js创建的单页面模拟客户端渲染

缺点

  • 首屏渲染慢因为 HTML 中没有内容,必须等到 JavaScript 加载并执行完成才能呈现页面内容

  • 不利于SEO同样因为 HTML 中没有内容,所以对于目前的搜索引擎爬虫来说,客户端渲染的页面,没有任何有用的信息;内容需要通过解析js,自然无法提取关键词,进行索引了

    搜索引擎怎么获取网页内容的?

    const http = require('http')
    
    //通过程序获取制定的网页内容
    http.get('http://localhost:3000/', res => {
     let data = ''
     res.on('data', chunk => {
         data += chunk
     })
     res.on('end', () => {
         console.log(data)
     })
    })

    SEO:搜索引擎去分析承重,提取内容

现代化的服务端渲染(SSR)

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

工作流程

  1. 客户端发起请求
  2. 服务端渲染首屏内容 + 生成客户端 SPA 相关资源
  3. 服务端将生成的首屏资源发送给客户端
  4. 客户端直接展示服务端渲染好的首屏内容
  5. 首屏中的 SPA 相关资源执行之后会激活客户端 Vue
  6. 之后客户端所有的交互都由客户端 SPA 处理

如何实现?

  • Nuxt.js 是一个基于 Vue.js 生态开发的一个第三方服务端渲染框架,通过它我们可以轻松构建现代化的
    服务端渲染应用

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

现代化服务端渲染\SSR

npm init -y
npm i nuxt
{
    "scripts":{
        "dev": "nuxt"
    }
}
  1. npm run dev后,生成服务端和客户端的脚本

  2. nuxt会根据你的pages目录自动生成路由配置

  3. asyncData:Nuxt中特殊提供的一个钩子函数,专门用于获取页面服务端渲染的数据

    async asyncData(){
        const {data} = await axios({
            method: 'GET',
            url: '/data.json'
        })
        //这里返回的数据会和data(){}的数据合并到一起给页面使用
        return {
            title: data.title,
            posts:data.pposts
        }
    }
  4. 请求数据是在服务端获取的,需要获取当前的本机地址

    url: 'http://localhost:3000/data.json'
  5. 查看页面源代码,能看到结果:服务端渲染好了,客户端没有必要再渲染

同构渲染的SPA应用

  • 首次渲染是服务端,之后交互都是客户端渲染

  • 模拟客户端渲染:创建单页面应用导航现代化服务端渲染\SSR\layouts\default.vue

    <template>
      <div>
        <ul>
          <li>
            <!-- 用于单页面应用导航 -->
            <nuxt-link to="/">Homoe</nuxt-link>
            <nuxt-link to="/about">About</nuxt-link>
          </li>
        </ul>
        <!-- 子页面出口 -->
        <nuxt />
      </div>
    </template>

当切换导航时,就是客户端在渲染

同构渲染的问题

实现原理

相关技术

  • React Next.js / Vue Nuxt.js
  • Angular中的Angular Universal

开发条件有限

  • 浏览器特定的代码只能在**某些生命周期钩子函数(lifecycle hook)**中使用

    服务端生命周期客户端生命周期需要做区分

  • 一些**外部扩展库(external library)**可能需要特殊处理才能在服务端渲染应用中运行

  • 不能在服务端渲染期间操作DOM

  • 某些代码操作需要区分运行环境

涉及构建设置和部署的更多要求

客户端渲染 同构渲染
构建 仅构建客户端应用即可 需要构建两个端
部署 可以部署在任意Web服务器中 只能部署在Node.js Serve

更多服务器负载

  • 在Node中渲染完整的应用程序,相比仅仅提供静态文件的服务器,需要大量占用CPU资源

  • 如果应用在高流量环境下使用,需要准备相应的服务器负载,并采用缓存策略

  • 需要更多的服务端渲染优化工作处理

服务端渲染使用建议

  • 首屏渲染速度是否真的需要?
  • 是否真的需求SEO?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant