客户端装饰器和 DOM

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

之前写过关于网页装饰器的文章 ,以及它们是在拉取还是推送的基础上工作。那篇文章仅限于以文本形式处理 html 标记的装饰器。这些是隐含的服务器端技术。回顾一下,我们谈论的一项技术是传奇的 sitemesh(“site-mesh”——Siri 发音为“sit-e-mesh”,叹气),由 joe walnes 开发。

我还简要地写了一篇关于 谷歌如何在多个应用程序之间进行一致的顶级导航的文章 。那是在同一领域的关注,虽然不完全是装饰。事实证明,谷歌也在服务器端进行了网站体验拼接。

sitemesh 拼接网站体验的经典方式

站点网 ervlet 过滤器获取任何预期的应用程序页面,并在将其整体发送到浏览器之前对其进行装饰。它也适用于静态内容。应用程序本身通常位于同一网络服务器中,但我展示的是 sitemesh 支持的不同网络服务器。它支持不同的技术,如 perl 或 php。





就像谷歌对多个应用程序的网站体验所做的那样?

每个应用程序都是自己的服务器,但网站片段被注入到页面的特定部分。之前,我真的只研究了顶部导航,但页面的多个可注入部分的设计是相同的。我在上面展示了“网站体验”是通过 http 请求被引入到一个横向网络服务器的,但我真的不知道。它 可能很容易成为一个库函数 ,这意味着该技术在构建时被有效地链接了-time. 服务器端每个用户的智能缓存矩形使其无论哪种方式都更快。

在dom中装饰

不过,也许您不习惯每天(每个用户)多次打开主窗口。如今,我们应该考虑在客户端使用装饰器来实现此类站点体验:

应用程序的主页加载,然后根据需要拉入尽可能多的“站点”矩形。浏览器处理矩形的缓存,因此应谨慎选择超时。这可能是用页面注入空的 div。它也可以是利用 iframe 的设计。

要使装饰器在浏览器中工作,它必须精通 dom。这是如何运作的假设:



  1. 浏览器正常检索​​页面 (get)
  2. 确定需要站点“装修”,然后应用。
  3. 重复 #2 直到没有更多的装饰器可以应用
  4. 向最终用户展示页面——呸!

不可能的是您可以在页面装饰之前阻止页面的首次显示。或者也许您可以阻止它,但这并不容易或顺利。肯定没有 w3c 以这种方式参与页面加载周期的方式。然而,至少。取而代之的是,像 angularjs 这样的框架使用隐藏技术 来到达那里。

sitemesh.js 怎么样?

2001 年,joe walnes(他在这篇博文中扮演了很多角色)在一家使用微软旧的 asp 技术的公司工作,他想做一些 sitemesh 风格的分离。当时的技术不支持,于是joe尝试用javascript来做。这是他回忆的内容(我从他的电子邮件中复制/粘贴给我,这不是完全有效的代码):

示例页面·html:


 <html>
  <body>
     <script src="sitemesh.js"></script>
     some vanilla html here
  </body>
</html>

装饰器·html:


 <html>
  <body>
     <script src="sitemesh.js"></script>
     some vanilla html here
  </body>
</html>

站点网·js:


 <html>
  <body>
     <script src="sitemesh.js"></script>
     some vanilla html here
  </body>
</html>

沿着记忆之路走累了,乔最后说:“我敢肯定有很多小怪癖需要解决,但这是基本要点”

这并不完美,经验丰富的 dom 开发人员会指出与 iframe 之间古老的爱/恨关系是该缺陷的中心。由于焦点问题,它在使用中感觉不太正确。内部 iframe 和外部非 iframe 也不共享相同的 url。稍后会详细介绍。

乔今天会做什么?

也许它仍然是客户端 iframe 解决方案,他说。具有一套严格的用户界面标准。我引用 joe 的另一封电子邮件,他概述了 iframe 在生产中的使用,并且在原则上与上述类似:

优点缺点

优点:

  • 易于编写页面:集成点是一个 url(每个都可以从不同的服务器运行)
  • 分割性强:css、js函数等不能外泄
  • 易于独立开发 iframe 内容(没有容器页面)
  • 可以使用 window.postmessage() 在框架之间建立基于消息的通信
  • 允许在框架内完全选择技术堆栈

缺点:

  • 以这种方式组装页面可能看起来像一个大杂烩:您需要强大的用户界面指南,并且在许多情况下您可能会选择共享依赖于技术堆栈的小部件的 css
  • 有些事情可能很尴尬。例如,如果 iframe 具有焦点,它将从主页获取键盘事件。全局加载处理程序很难。我建议在所有框架之间共享一个通用的 js 库以帮助协调事情

他对其他解决方案的看法:

  • sitemesh 仅适用于静态服务器呈现的站点。我将它用于以内容为中心的网站,而不是以应用程序为中心的东西
  • 官方的网络组件规范可能是未来的方向,但目前我发现它仍然很笨拙,而且我已经被规范的变化困扰了几次
  • 或者采用 javascript 框架并使用清晰的包和边界进行标准化,以防止出现单体应用。问题是你会终生受困。
  • 在关闭

    (又是我——不是引用乔的话)

    该网站体验的客户端装饰不会取悦谷歌搜索爬虫或他们的搜索预览机器人。

    如果你朝那个方向前进,你必须真正担心延迟和脆弱性。需要实施阻塞/隐藏,至少在它成为 w3c 标准之前,除非您的整个生产设置如此之快没有人注意到。如果您的社区是登录用户,而不是点击 reddit 的访客,那么他们可能对体验更宽容,也更有可能利用缓存的元素。

    然后是焦点和 url 问题,这些问题根据您选择的客户端解决方案而变大或变小。