標籤:

原生JS前後端同構

原生JS前後端同構

來自專欄 hpoenixf的前端探索

什麼是前後端同構

明確三個概念:「後端渲染」指傳統的 ASP、Java 或 PHP 的渲染機制;「前端渲染」指使用 JS 來渲染頁面大部分內容,代表是現在流行的 SPA 單頁面應用;「同構渲染」指前後端共用 JS,首次渲染時使用 Node.js 來直出 HTML。一般來說同構渲染是介於前後端中的共有部分。

感覺前端的確是折騰,之前還在流行前後端分離,現在怎麼又要做前後端同構了?

原因是現在流行的SPA前端單頁面應用比較沉重,首次訪問需要載入文件較多,第一次載入過慢,用戶需要等待前端進行渲染頁面。而且不利於SEO及緩存,並且有一定的開發門檻。

前後端同構通過復用模板和JS文件,讓一份代碼可以同時跑在伺服器和瀏覽器,首次渲染使用nodejs渲染頁面,之後使用SPA路由跳轉。可以有效減少用戶首次訪問的等待時間,並且對SEO比較友好,也便於緩存。

項目簡介

本前後端同構項目主要分為兩個部分,一個是基於koa2的渲染伺服器,另一個是基於原生JS和zepto的前端SPA。

項目的特點是不使用vue和react等框架,門檻低,開發速度快,便於上手,比較輕巧,核心的router部分只有一百行左右的代碼。適用於頁面交互較少,變化不頻繁的場景下,同時支持代碼分割,可以有效的提升性能和載入速度。

前端部分

前端部分的核心是路由部分,具體實現可以基於history API或是hash,網上有很多實現,這次主要講下架構

前端部分採用MVC分層結構。

router層做的主要是創建路由示例,調用路由的get方法,給特定頁面綁定來自control層的函數。

形式如:

import control from ../control//路由的構造函數支持傳入渲染函數,路由的全局名稱,路由跳轉前調用的鉤子router = new Router(render,ROUTER,beforeFn)router.get(/page/a, control.pageA)

control層主要做的是載入跟後端共有的渲染模板和渲染數據,渲染出頁面後運行頁面函數

形式如:

let control = { pageA(req,res) { //webpack的動態載入,代碼分割功能 import(/* webpackChunkName: "pageA" */script/pageA).then(module=> { // 檢測該頁面是否已有伺服器渲染好,是的話直接運行module.default //否則載入模板和數據進行渲染,最後再調用頁面函數 if(this.needRender(module.default)) { //載入數據時訪問的地址就是當前準備渲染的頁面地址,只是加上了json=1的參數 loadData(pageA).then(data => res.render(xtpl,data,module.default)) } }}// 捕捉webpack熱更新,讓他只進行相當於頁面跳轉的操作而不是刷新頁面if(module.hot) { module.hot.accept([script/pageA], () => { control[ROUTER.req.currentControl].call(ROUTER,null,ROUTER.res) })}

view層即模板,這裡使用的是xtpl模板,沒有限定具體模版,只要在伺服器環境和前端環境下都支持渲染頁面就可以了。

頁面函數的形式

頁面函數要求使用es6的模塊寫法,配合webpack的按需載入功能

export default () => { window.addEventListener(scroll, fn)//頁面函數支持返回一個卸載函數,在頁面離開的時候會被調用//主要用於內存的釋放,定時器的清除,事件監聽的移除等等 return function () { window.removeEventListener(scroll, fn) }}

後端部分

使用koa2搭建的一個渲染伺服器,在收到前端傳來的頁面請求時,會向API伺服器請求數據,並識別頁面請求是否帶有json=1的參數,如果帶有,則為前端路由跳轉時的請求,直接返回數據即可,如果沒有帶json參數,載入跟前端共用的模板,配合數據進行渲染,發送到瀏覽器。

提升空間和一些遺漏的點

後端可以使用bigpipe或是骨架屏來加快首屏時間。

該項目主要應用於移動端,自適應是一個比較重要的點

推薦一個移動端響應式布局的方案?

hpoenixf.com圖標

前端如果DOM操作頻繁的話,可以引入虛擬dom的技術,首先將渲染完成的html轉成vnode虛擬dom樹,在數據變動時,令其生成新的vnode,接著進行diff和patch,可以有效減少dom的操作,我之前寫了一個比較基礎的,虛擬dom實現

一個簡單的virtual-dom實現?

hpoenixf.com圖標
推薦閱讀:

面試必考之http狀態碼有哪些
11. Redux
從process.versions了解Node.js的構成
如何優雅的自學前端
html無序列表ul標籤和有序列表ol標籤的用法

TAG:前端開發 |