看看最简单的SSR服务端渲染

687 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

概述

现在主流的单应用开发,前端开发构建打包成静态资源文件,然后上传部署到 nginx,或者 tomcat。当用户访问的网站的时候,首先会加载html模板文件,然后再去加载js文件,由js进行主要的执行渲染,这类称为“浏览器渲染”,简称“CSR”。它的弊端主要是,不利于SEO优化、首页渲染白屏时间等。相对而言,服务端渲染(SSR),则直接返回的是html文件进行渲染,白屏时间更短,也利于SEO,但是它增加了服务器的负担。

两种渲染方式,放到指标上进行衡量的话,是这样的: CSR无法提前FMP时间,即使它能够通过骨架屏、甚至一个loading来提前FP、FCP时间而减少白屏时间。而SSR直接将FMP提前到js加载前,毕竟它返回的是渲染好的html文件,不需等待加载js进行主要内容的渲染解析。

知识点:

  • FP:首帧绘制的时间
  • FCP:首次内容绘制时间
  • FMP:首次有效绘制,网站最有意义的那块内容,比如,相对于电商网站,可能就是商品内容。

所以,三个指标触发的时间顺序是:FP -> FCP - > FMP。

知道了SSR的必要性,那下面看个最简单的SSR渲染。

模板渲染例子

用node实现一个渲染json文件数据的index模板网页。例子简单,直接上代码:

// json数据文件:  data.json

['小张', '小明', '小红']
<!-- 模板文件 index.html -->

<!doctype html>
<html>
  <head></head>
  <body>
    <h1>我的朋友</h1>
     <!-- %:会被替换的内容 -->
    <ul><li>%</li></ul>
  </body>
</html>
// node服务,进行ssr

const http = require('http')
const fs = require('fs')

const getTemplate = (data, res) => {
  // 读取模板文件
  fs.readFile('./index.html', (err, data) => {
    if(err) return res.end('server error')
    const temp = data.toString()
    // 替换模板数据
    const html = temp.replace('%', data.join('</li><li>'))
    // 写响应头,返回数据
    res.writeHead(200, {'Content-Type': 'text/html'})
    res.end(html)
  })
}

const renderTemplate = (res) => {
  // 读取json数据
  fs.readFile('./data.json', (err, data) => {
     if(err) return res.end('server error')
     getTemplate(JSON.parse(data.toString()), res)
  })
}

// 创建node服务
const server = http.createServer(function(req, res){
   renderTemplate(res)
}).listen(80, '127.0.0.1')

这就是最简单的SSR服务端渲染了,本质上都是如此,进行模板字符串替换。只是当你更复杂时,需要定义一套自己的模板渲染规则,而不能进行简单的替换。

总结

服务端模板引擎很多,比如Pug、EJS、Mustache等,当然如果技术栈是Vue,则可以使用Nuxt.js,它是一个基于Vue生态更高层的框架用于处理服务端渲染,方便服务端和浏览器端共用一套组件。当然如果是react技术栈,可以采用next.js框架。