之前我开发了一些工具,每个页面是一个html
文件,整体是个多页面应用。包括这些:
当时,每一个工具都有一个URL,每个页面只有本工具的内容,没有统一的「导航栏」,这对于工具网站是非常不方便的。所以,我需要加一个统一的导航栏,方便用户在多个页面之间跳转。
我做事情很谨慎,一定要罗列多个方案,再做决策。
我把所有可行的方案都罗列到了本文中,并描述了各个方案的优点、缺点。方便大家遇到相同问题时做决定。
罗列方案前,你需要知道:
这里服务端渲染主要包括2种:
他们都可以实现这种的效果:用户请求某个页面的html时,后端动态拼接好一份完整的html,返回给前端。在拼接过程中,把导航栏的html片段加进去。
白屏时间短,SEO好。
综上,如果你的网站本身没有服务端渲染,我不建议你仅仅为了增加导航栏而采用该方案。
前端增加编译环节,源代码不写导航栏,编译后,自动在特定位置插入导航栏的html片段。
如果不想使用Webpack,也可以像我一样,手写编译脚本(基于NodeJS):
首先是build.js
,它遍历src
文件夹下的html文件,针对每个html文件,跑一遍函数addNavigation
,把结果写入build
文件夹。
// build.js
const fs = require('fs');
const addNavigation = require('./navigation');
fs.readdirSync('../src').forEach(filename => {
if (!filename.endsWith('.html')) return;
const html = fs.readFileSync('../src/' + filename, 'utf-8');
const newHtml = addNavigation(html, filename);
fs.writeFileSync('../build/' + filename, newHtml, 'utf-8');
});
然后是navigation.js
,它就是针对html源代码做修改,返回新的html片段,已经插入了导航栏html片段。
// navigation.js
const config = [
{name: '备忘录', url: 'memo.html'},
// ...
];
const getNavigationHtml = (filename) => {
return '<div>导航栏html片段</div>';
};
const addNavigation = (html, filename) => {
let newHtml = html;
const navigationHtml = getNavigationHtml(filename);
const bodyIndex = newHtml.indexOf('<body>') + 6;
newHtml = newHtml.substr(0, bodyIndex) + navigationHtml + newHtml.substr(bodyIndex);
return newHtml;
};
module.exports = addNavigation;
为什么这么设计呢?因为addNavigation
只是编译的一个环节,之后可以方便的增加addHeader
、addFooter
等等。
我个人就是选择了这种方案,参考: github.com/HullQin/tool-hullqin-cn/tree/main/scripts
通过script动态引入导航js,运行时插入html片段(即UMD方式,Webpack的模块联邦也属于这种方案)。
为什么必须通过script引入?
因为导航栏的一致性和可变性,开发时它一定是只存了一份代码的。因为本方案不在编译时统一插入,而是在运行时动态插入,所以就需要多个页面引入同一份js文件,动态插入一样的导航栏。
解决了方案二的缺点,每次变更导航栏,只需要重新发布script即可,不需要重新发布其他工具的html。
如果可以接受这些缺点,这确实是非常好的方案。适合内部平台使用。
如果页面整体是同一个项目,同一个框架,那么使用组件是最方便的。
这时候基本不需要决策了,直接无脑用组件吧。
微前端的初衷正是为了解决巨石应用,也可以让多个应用放到同一个SPA中,切换更流畅。
微前端方案中,通常分为「主应用」和「子应用」。可以把导航栏放在「主应用」中。
如果你的项目本身不是基于微前端的,没有必要为了加导航栏而引入微前端方案。
你可以看看我的网站 tool.hullqin.cn,它没有采用微前端方案,本身是个多页面应用(非SPA)。但因为浏览器有缓存,所以体验非常丝滑,在多个页面之间切换非常快。
方案 | 框架限制 | 首屏加载速度 | SEO | 可维护性 |
---|---|---|---|---|
服务端渲染(SSR或模板渲染),统一在html特定位置插入导航html片段 | 无 | 较快 | 很好 | 导航html片段在后端项目,需维护好它 |
前端编译时,统一在html特定位置插入导航html片段 | 无 | 最快 | 很好 | 导航html片段在前端项目,需维护好它 |
通过script动态引入导航js,运行时插入html片段 | 无 | 快 | 一般 | 同上 |
基于框架组件(React、Vue等)做导航栏 | 必须统一框架 | 快 | 一般 | 同上 |
基于微前端做导航栏,导航属于主应用,工具页面属于子应用 | 无 | 一般 | 一般 | 同上 |
我个人是选择了方案二,代码参考: github.com/HullQin/tool-hullqin-cn
效果如下: tool.hullqin.cn
我是HullQin,公众号线下聚会游戏的作者(欢迎关注我,交个朋友)。转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费无广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我噢~我有空了会分享做游戏的相关技术,会在这个专栏里分享:《教你做小游戏》。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。