前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何给多个页面,添加统一的导航栏?我罗列对比了 5 个方案

如何给多个页面,添加统一的导航栏?我罗列对比了 5 个方案

原创
作者头像
HullQin
发布2022-12-27 08:53:16
8K0
发布2022-12-27 08:53:16
举报
文章被收录于专栏:教你做小游戏

背景

之前我开发了一些工具,每个页面是一个html文件,整体是个多页面应用。包括这些:

当时,每一个工具都有一个URL,每个页面只有本工具的内容,没有统一的「导航栏」,这对于工具网站是非常不方便的。所以,我需要加一个统一的导航栏,方便用户在多个页面之间跳转。

我做事情很谨慎,一定要罗列多个方案,再做决策。

我把所有可行的方案都罗列到了本文中,并描述了各个方案的优点、缺点。方便大家遇到相同问题时做决定。

导航栏特点

罗列方案前,你需要知道:

  1. 导航栏是可变的,每当你新做一个页面、修改某页面的标题或URL,都需要更新导航栏。
  2. 所有页面的导航栏,应该具有一致性,更新时要统一更新(否则用户会比较困惑)。

方案一:服务端渲染

这里服务端渲染主要包括2种:

  1. 基于NodeJS框架做的SSR。
  2. 基于其它后端框架模版做的动态渲染。

他们都可以实现这种的效果:用户请求某个页面的html时,后端动态拼接好一份完整的html,返回给前端。在拼接过程中,把导航栏的html片段加进去。

优点

白屏时间短,SEO好。

缺点

  1. 服务端渲染是需要耗费服务端资源的,即使渲染结果可以缓存,我依然不建议浪费这些计算、存储资源。
  2. 服务端需要维护好导航html片段。而服务端代码和前端代码通常不在一个仓库,如果开发者手动更新导航html片段,效率低,容易忘记。即使你做了自动化方式同步,这也涉及到跨仓库同步,不是很方便。
  3. 开发过程中,为了达到跟线上一样的效果,可能还需要启动后端服务,导致本地开发测试不方便。

综上,如果你的网站本身没有服务端渲染,我不建议你仅仅为了增加导航栏而采用该方案。

方案二:前端编译时插入

前端增加编译环节,源代码不写导航栏,编译后,自动在特定位置插入导航栏的html片段。

优点

  • 白屏时间短,SEO好。
  • 可以放在CDN。

特点

  • 需要增加编译环节,可以借助Webpack等工具。

如果不想使用Webpack,也可以像我一样,手写编译脚本(基于NodeJS):

首先是build.js,它遍历src文件夹下的html文件,针对每个html文件,跑一遍函数addNavigation,把结果写入build文件夹。

代码语言:javascript
复制
// 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片段。

代码语言:javascript
复制
// 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只是编译的一个环节,之后可以方便的增加addHeaderaddFooter等等。

缺点

  • 每次更新导航栏,需要重新编译所有项目,并重新发布所有页面的html文件。(但它是可接受的,全部重新编译、全部重新发布,完全可以自动化实现,且成本很低)

我个人就是选择了这种方案,参考: github.com/HullQin/tool-hullqin-cn/tree/main/scripts

方案三:前端运行时插入(UMD、模块联邦)

通过script动态引入导航js,运行时插入html片段(即UMD方式,Webpack的模块联邦也属于这种方案)。

为什么必须通过script引入?

因为导航栏的一致性和可变性,开发时它一定是只存了一份代码的。因为本方案不在编译时统一插入,而是在运行时动态插入,所以就需要多个页面引入同一份js文件,动态插入一样的导航栏。

优点

解决了方案二的缺点,每次变更导航栏,只需要重新发布script即可,不需要重新发布其他工具的html。

缺点

  1. 加载速度较慢,可能存在导航栏闪动问题(因为script是异步加载的,展示页面内容时,可能还没下载好导航栏对应script)。
  2. SEO不好。
  3. JS缓存时间不能太久。如果缓存太久导致无法及时自动更新、如果缓存太短导致经常加载速度慢。

如果可以接受这些缺点,这确实是非常好的方案。适合内部平台使用。

方案四:基于框架组件

如果页面整体是同一个项目,同一个框架,那么使用组件是最方便的。

这时候基本不需要决策了,直接无脑用组件吧。

方案五:基于微前端

微前端的初衷正是为了解决巨石应用,也可以让多个应用放到同一个SPA中,切换更流畅。

微前端方案中,通常分为「主应用」和「子应用」。可以把导航栏放在「主应用」中。

优点

  • 框架不受限制。
  • 可以让多页面应用(MPA)体验像单页面应用(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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 导航栏特点
  • 方案一:服务端渲染
    • 优点
      • 缺点
      • 方案二:前端编译时插入
        • 优点
          • 特点
            • 缺点
            • 方案三:前端运行时插入(UMD、模块联邦)
              • 优点
                • 缺点
                • 方案四:基于框架组件
                • 方案五:基于微前端
                  • 优点
                    • 缺点
                    • 方案汇总
                    • 写在最后
                    相关产品与服务
                    内容分发网络 CDN
                    内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档