单页应用程序 SEO 和无限滚动 AngularJS

2023-12-22

我们有一个网站,其提要类似于 pinterest,并计划将 jquery soup 重构为更结构化的内容。最有可能的两个候选者是 AngularJS 和 Backbone+Marionette。该网站是用户生成的,主要以消费为导向(典型的 90/9/1 规则),用户可以对帖子进行点赞、添加书签和评论。从提要中,我们打开一个灯箱来查看有关帖子的更多详细信息,包括评论、相关帖子,类似于 pinterest。

我们偶尔使用过主干,并且熟悉这个想法,但被样板所推迟。我认为 Marionette 会对此有很大帮助,但如果从长远来看有帮助的话,我们愿意更彻底地改变方向(例如 Angular)。

要求:

  • 出于 SEO 原因,初始页面必须静态。重要的是,该框架能够从现有内容开始,最好不要有什么冲突。
  • 我们希望灯箱所需的数据已经加载到提要中,以便转换速度更快。一些数据已经存在(标题、描述、照片、点赞数/书签数、评论数),但还会为详细视图加载其他数据 - 评论、类似帖子、谁喜欢这个等。
  • 在提要或详细信息灯箱中发生的帖子更改应该会在其他灯箱中反映出来,只需很少的工作(例如,如果我从提要中喜欢它,如果我转到灯箱,我应该看到喜欢和新的喜欢计数 - 或者相反。)
  • 我们希望迁移我们的移动网站(目前在 Sencha Touch),以便对常见部分也使用相同的代码库,这样我们就可以在移动网站和主网站之间拥有更接近的功能对等性。

这些要求与我对 Angular 的担忧相关:

1)在通过模板附加页面渲染时,初始页面加载是否可能/有问题?

2)页面的不同部分有多个数据源是否有问题 - 例如,主要帖子部分来自嵌入的 json 数据和提要中的“查看更多”,而其他详细信息将来自不同的 ajax 调用。

3)虽然双向绑定很酷 - 但我担心在我们的例子中它可能会带来负面影响,因为渲染的项目数量较多。我们需要双向绑定的元素数量相对较少。帖子如:

  • https://stackoverflow.com/a/7654856/214545 https://stackoverflow.com/a/7654856/214545
  • Angular JS ng-repeat 消耗更多浏览器内存 https://stackoverflow.com/questions/14065050/angular-js-consumes-more-browser-memory

请关注我们的用例。我们可以轻松地拥有数百个帖子,每个帖子都有 1-2 打细节。如果我知道我知道不会更改的字段/元素,是否可以“禁用”双向绑定?

将视口之外的元素卸载到同一内存是否正常/可能?这也与移动方向有关,因为内存在移动方向上更受关注。

AngularJS 在我们的用例中工作/表现良好吗?有什么技巧/技巧可以帮助这里吗?


有不同的“无限滚动”方法或按您的说法提供。用户的需求和可接受的响应有效负载的大小将决定您选择哪一种。

在这里,您似乎在满足性能的同时牺牲了可用性。

1. 追加资产 http://binarymuse.github.io/ngInfiniteScroll/

此方法是传统的追加到底部方法,如果用户到达当前滚动高度的底部,将进行另一个 API 调用以“堆叠更多”内容。这样做的好处是,它是处理跨设备警告的最有效解决方案。

正如您所提到的,该解决方案的缺点是当用户不小心滚动内容时,大量有效负载会淹没内存。没有油门。

<div infinite-scroll='getMore()' infinite-scroll-distance='0'>
  <ul>
    <li ng-repeate="item in items">
      {{item}}
    </li>
  </ul>
</div>

var page = 1;
$scope.getMore() = function(){ 
 $scope.items.push(API.returnData(i));
 page++;
}

2.添加带有节流阀的资源

在这里,我们建议用户可以继续在无限追加的提要中显示更多结果,但必须限制它们或“手动”调用更多数据。相对于用户将滚动浏览的返回内容的大小,这变得很麻烦。

如果每个有效负载返回大量内容,则用户将不得不更少地单击“获取更多”按钮。当然,这是以返回更大的有效负载为代价的。

<div>
  <ul>
    <li ng-repeate="item in items">
      {{item}}
    </li>
  </ul>
</div>
<div ng-click='getMore()'>
  Get More!
</div>

var page = 1;
$scope.getMore() = function(){
  $scope.items.push(API.returnData(i));
  page++;
}

3. 虚拟卷轴 http://blog.stackfull.com/2013/02/angularjs-virtual-scrolling-part-1/

这是无限滚动的最后也是最有趣的方式。这个想法是,您仅将一系列结果的渲染版本存储在浏览器内存中。也就是说,复杂的 DOM 操作仅作用于配置中指定的当前范围。然而,这有其自身的缺陷。

最大的就是跨设备兼容性。

如果您的手持设备有一个虚拟滚动窗口,其宽度达到设备的宽度,那么最好小于页面的总高度,因为您将永远无法使用其自己的滚动条滚动经过此“提要”。您将被“卡在”中间页面,因为您的滚动将始终作用于虚拟滚动提要而不是包含提要的实际页面。

接下来是可靠性。如果用户手动将滚动条从低索引拖动到极高索引,您将强制浏览器非常非常快地运行这些指令,这在测试中导致我的浏览器崩溃。这可以通过隐藏滚动条来解决,但是当然用户可以通过非常非常快地滚动来调用相同的场景。

这是演示 http://demo.stackfull.com/virtual-scroll/#/comparison

来源 https://github.com/stackfull/angular-virtual-scroll

"Initial page must static for SEO reasons. It's important that the framework be able to start with existing content, preferable with little fight."

那么您的意思是您希望页面在提供内容之前在服务器端进行预渲染?这种方法在早期的几千年中效果很好,但大多数人都在放弃这种方法并转向单页应用程序风格。有充分的理由:

  • 您发送给用户的初始种子充当获取 API 数据的引导程序,因此您的服务器所做的工作要少得多。

  • 延迟加载资源和异步 Web 服务调用使得感知加载时间比传统的“首先渲染服务器上的所有内容,然后将其返回给用户的方法”快得多。

  • 您可以通过使用页面预渲染/缓存引擎来保留您的搜索引擎优化,该引擎位于您的网络服务器前面,仅使用您的“完全渲染版本”响应网络爬虫。这个概念很好解释here http://theothersideofcode.com/what-is-stopping-google-from-indexing-single-page-javascript-applications.

we would prefer to have the data needed for the lightbox loaded already in feed so that the transition can be faster. Some of the data is already there (title, description, photos, num likes/ num bookmarks,num comments) but there is additional data that would be loaded for the detail view - comments, similar posts, who likes this, etc.

如果您的 feed 的初始有效负载不包含每个“feed id”的子数据点,并且需要使用额外的 API 请求将它们加载到您的灯箱中 --- 您的做法是正确的。这完全是一个合法的用例。您可能会认为单个 API 调用需要 50-100 毫秒,这对于您的最终用户来说是无法察觉的延迟。如果您绝对需要通过 Feed 发送额外的有效负载,那么您并没有赢得太多。

Changes to the post that happen in the feed or detail lightbox should be reflected in the other with little work (eg, if I like it from the feed, I should see that like and new like count number if I go to the lightbox - or the opposite.)

你在这里混合了技术 --- Like 按钮是对 facebook 的 API 调用。这些更改是否会传播到同一页面上 facebook 类似按钮的其他实例取决于 facebook 如何处理它,我相信快速谷歌会帮助你。

然而,特定于您网站的数据——有几个不同的用例:

  • 假设我更改了灯箱中的标题,并且还希望将更改传播到当前显示的提要。如果您的“保存编辑操作”POST 到服务器,则成功回调可能会触发使用 Websocket 更新新值。此更改不仅会传播到您的屏幕,还会传播到其他所有人的屏幕。

  • 您还可以讨论双向数据绑定(AngularJS 在这方面很擅长)。通过双向数据绑定,您的“模型”或从 Web 服务返回的数据可以绑定到视图中的多个位置。这样,当您编辑共享同一模型的页面的一部分时,另一部分将随之实时更新。这发生在任何 HTTP 请求之前,因此是完全不同的用例。

We would like to migrate our mobile site (currently in Sencha Touch) to also use the same code base for the parts that are common so we can have closer feature parity between mobile and main site.

你真的应该看看现代的响应式 CSS 框架,比如引导程序 http://twitter.github.io/bootstrap/ and 基础 http://foundation.zurb.com/。使用响应式网页设计的要点是,您只需构建一次网站即可适应所有不同的屏幕尺寸。

如果你谈论的是功能模块化,AngularJS 更胜一筹。这个想法是,您可以将网站组件导出到可用于另一个项目的模块中。这也可以包括视图。如果您使用响应式框架构建视图,您猜怎么着 — 您现在可以在任何地方使用它。

1) Will it be possible/problematic to have initial page loads be static while rending via the templates additional pages.

如上所述,最好放弃这些方法。如果您绝对需要它,模板引擎并不关心您的有效负载是在服务器端还是客户端呈现。部分页面的链接也同样容易访问。

2) is it problematic to have multiple data-sources for different parts of page - eg the main post part comes from embedded json data and from "see more"s in the feed while the additional detail would come from a different ajax call.

同样,这正是该行业正在迈向的方向。您将使用获取所有外部 API 数据的初始静态引导程序来节省“感知”和“实际”加载时间 --- 这也将使您的开发周期更快,因为您正在分离完全独立的部分的关注点。你的 API 不应该关心你的视图,你的视图也不应该关心你的 API。这个想法是,当你将 API 和前端代码分解成更小的部分时,它们都可以变得模块化/可重用。

3) While the two-way binding is cool - I'm concerned it might be a negative in our case because of the number of items being rendered. The number of elements that we need two-way binding is relatively small.

我还将把这个问题与您在下面留下的评论结合起来:

Thanks for the answer! Can you clarify - it seems that 1) and 2) just deal with how you would implement infinite scrolling, not the performance issues that might come from such an implementation. It seems that 3 addresses the problem in a way similar to recent versions of Sencha Touch, which could be a good solution

您将遇到的性能问题完全是主观的。我试图在讨论中概述诸如限制之类的性能注意事项,因为限制可以极大地减少服务器所承受的压力以及用户浏览器对附加到 DOM 中的每个新结果集所做的工作。

一段时间后,无限滚动会耗尽用户的浏览器内存。我可以告诉你的是,这是不可避免的,但只有通过测试你才能知道多少。根据我的经验,我可以告诉您用户浏览器可以处理大量滥用,但同样,每个结果集的有效负载有多大以及您在所有结果上运行的指令完全是主观的。有些解决方案仅在我描述的选项三中的范围数据集上呈现,但也有其局限性。

返回的 API 数据大小不应超过 1-2kbs,并且返回查询只需要大约 50-200 毫秒。如果您没有达到这些速度,也许是时候重新评估您的查询或通过使用子 ID 查询其他端点以了解具体信息来减少返回的结果集的大小。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单页应用程序 SEO 和无限滚动 AngularJS 的相关文章

  • JS如何获取多维数组的最大深度?

    我有一个多维数组 我想知道它的最大深度 我发现了这个灵魂 但它不适用于对象数组 const getArrayDepth arr gt return Array isArray arr 1 Math max arr map getArrayD
  • 全局 JavaScript 变量作用域:为什么这不起作用?

    所以我在玩 JavaScript 时遇到了我认为奇怪的事情 有谁能解释一下以下内容吗 我已将警报值作为评论包含在内 为什么 foo 中的第一个警报 msg 返回不明确的并不是outside var msg outside function
  • 使用shinyjs通过javascript在闪亮的应用程序中操作现有的Leaflet地图

    我有一个闪亮的应用程序 其中包含现有的传单地图 我希望能够在渲染后使用自定义 javascript 通过shinyjs包裹 一个最小的例子如下 app R packages library dplyr library leaflet lib
  • 从 Angular 6 服务中绑定图像

    我有一个端点 它根据某些参数为我提供图像 这不是一个图像网址 而是一个普通图像 因此 当我到达邮递员中的端点时 作为响应 我收到一张图像 JPG 我是否可以在变量中接收该图像并将其绑定到 HTML 标签中 所有问题都有将图像 url 映射到
  • 画布图像遮罩/重叠

    在我的项目中 我必须使用画布在另一个相同尺寸和图案图像上实现一个不同的颜色图像 并且图像不是圆形或矩形形状 所有这些都是波浪形状的 它将应用于单个主背景图像 以便在每个主背景图像上显示多个图形onclick功能 重叠的图像应更改为另一种选定
  • TypeScript 中类和命名空间的区别

    到底有什么区别classes and namespaces在打字稿中 我知道 如果您创建一个带有静态方法的类 您可以在不实例化该类的情况下访问它们 这正是我猜想的命名空间的要点之一 我还知道你可以创建多个同名的命名空间 并且它们的方法在编译
  • Angular 7 Guard 重定向仅适用于双击

    问题是我已经实现了一个 Guard 旨在处理特定的目录 如果当前用户名的角色等于 2 它应该返回 true 如果没有 那么它不应该重定向 这是我的 app routing module ts 文件 问题出在 userlist 路径中 我们是
  • React.js this.props.data.map() 不是一个函数

    我正在搞乱反应并尝试解析和渲染 json 对象 现在 我只是使用硬编码对象设置它以进行测试 而不是从 ajax 调用中获取它
  • 在社交媒体 Ruby On Rails 上共享链接时的小预览

    我正在开发一个前端位于的网站angularjs和后端ROR Same ROR API用于android app还 现在我这里有一个情况 我需要在社交媒体上分享我的网站帖子 例如facebook twitter and google plus
  • JQuery _renderItem 没有被调用

    我正在尝试使用 renderItem 函数创建自定义 ui menu item 元素 但经过可能尝试后 我什至无法调用该函数 自动完成功能正在工作 但就像 renderItem 函数不存在一样 这是我的脚本部分
  • Outlook Rest 调用表单 angularjs

    使用 Outlook 我正在尝试创建事件 当我使用 POSTMAN 发送请求时 它工作正常 但 Angularjs 中的相同代码却不起作用 代码有什么问题 请帮忙 scope createEvents function var url ht
  • (angularjs-google-maps) ng-click 内部标记

    这个问题是关于angularjs google maps https github com allenhwkim angularjs google maps https github com allenhwkim angularjs goo
  • 为什么 LinkedList 通常比 List 慢?

    我开始在我的一些 C 算法中使用一些 LinkedList 而不是列表 希望能够加快速度 然而 我注意到他们只是感觉更慢 像任何优秀的开发人员一样 我认为我应该尽职调查并验证我的感受 所以我决定对一些简单的循环进行基准测试 我认为用一些随机
  • 为什么在 vue 组件上输入另一个输入时,输入文件的值丢失了?

    我有两个组件 我的第一个组件 父组件 如下所示
  • .NET 程序集大小会影响性能吗?

    net 程序集的大小是否会影响性能 您的 Windows 窗体 Web 窗体项目中的程序集数量如何 来自微软的模式和实践提高 NET 应用程序性能和可扩展性 http msdn microsoft com en us library ms9
  • Niceedit本地上传图片失败

    我是这样称呼编辑的 new nicEditor buttonList bold italic underline upload iconsPath img nicedit png uploadURI http server com inte
  • NodeJS 中的缩进多行日志记录

    我要打印JSON stringify d 反对控制台 将上下文作为 Mocha 测试套件输出的一部分 当测试缩进时 我希望对象日志行向右缩进足够远 例如 3 4 个制表符空格 以便它们可以识别地位于右侧describe group 我怎样才
  • IEnumerable.比带中断的 for 循环更快吗?

    我们的代码打开表单时遇到了一些缓慢的情况 这可能是由于for循环与break这需要很长时间才能执行 我把它切换到IEnumerable Any 并看到表格很快打开 我现在试图弄清楚是否单独进行此更改会提高性能 或者是否正在访问Product
  • 如何在没有脚本 (PHP) 或服务器配置 (Nginx) 的情况下检测移动设备(和/或移动 cookie)?

    我们很快就会推出网站的移动版本 我们的完整网站和移动网站仅在主题上有所不同 即网址相同 唯一的区别在于前端 当用户访问我们的网站时 我们需要能够执行以下操作 1 检查 cookie 移动 true 或 false 以确定是否已定义完整与移动
  • JavaScript 比较中应使用哪个等于运算符(== 与 ===)?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我在用着JSLint http en wikipedia org wiki JSLint

随机推荐

  • 查找 Excel 工作表中的最后一个单元格?

    我正在使用 vb6 并将数据复制到 Excel 工作表 我需要做的是将数据附加到现有工作表 我现在需要找到工作表中最后一个单元格的索引号 只有一张工作表 我尝试了一些方法 例如oBook range cells specialcells x
  • Set-Service:无法停止服务,因为它依赖于其他服务

    当我运行以下命令时 Set Service ComputerName appserver Name MyService Status Stopped 我收到一条错误消息 Set Service Cannot stop service My
  • 将文件中的图像读/写到 BufferedImage 的最快方法?

    在 Java Grails 中将文件中的图像读入 BufferedImage 的最快方法是什么 在 Java Grails 中将 BufferedImage 中的图像写入文件的最快方法是什么 我的变体 阅读 byte imageByteAr
  • 使用或不使用 NI Vision 从二进制缓冲区/文件创建 LabVIEW IMAQ 图像

    假设您有一个表示二维图像的二进制缓冲区或文件 如何使用 LabVIEW 将二进制数据转换为 IMAQ 图像以便进一步处理 借助 NI 视觉 对于 LabVIEW 用户已安装 NI 视觉库的人 有一些 VI 允许从 2D 数组复制 IMAQ
  • execv() 和 fork() 浪费时间

    我目前正在学习fork and execv 我对组合的效率有疑问 我看到了以下标准代码 pid fork if pid lt 0 handle fork error else if pid 0 execv son prog argv son
  • System.WeakReference 的实际使用

    我明白什么系统 弱引用 http msdn microsoft com en us library ms404247 aspx确实如此 但我似乎无法理解它可能有用的实际例子 在我看来 这个课程本身就是一个黑客 在我看来 还有其他更好的方法来
  • Eclipse,在库中定义的开放声明

    在 Eclipse 中 如果我按 F3 或打开某个库中的引用的声明 它会打开代码的只读副本 我一开始认为这非常有用 因为它提醒我它的库代码和更改可能会影响更多项目 但我发现如果我确实想编辑 则必须手动查找 java 文件 这很痛苦 我可以
  • 是否可以在 apache flink CEP 中处理多个流?

    我的问题是 如果我们有两个原始事件流 即Smoke and 温度我们想知道是否有复杂的事件 即Fire通过将运算符应用于原始流已经发生了 我们可以在 Flink 中做到这一点吗 我问这个问题是因为到目前为止我所看到的 Flink CEP 的
  • 当行有子项时复制数据库中的行

    我需要复制表中的行 并复制通过其外键链接到其他表中的所有行 然后复制链接到这些行的所有行 问题是当我复制该行时 密钥将会改变 如何通过表之间的关系传播这些更改 您可以编写一个实现所有复制逻辑的存储过程 本质上 在主表中插入复制行 将新 ID
  • System.IO.DriveInfo 返回错误的磁盘空间值

    更新 这个问题不会出现在我测试过的 Android 设备上 它返回良好的值 非常感谢有关此事的任何指示 我无法从 Mac 台式计算机获取正确的可用空闲空间值 我正在使用 Unity3D C 并使用以下代码 DriveInfo drives
  • 如何为续集更新添加日志记录

    在我的项目中sequelize日志记录已禁用 但我希望在确切的查询中进行主动日志记录 我怎样才能做到这一点 TableModel update counter 0 where id itm i then res gt console log
  • 我可以在同一页面上使用多个版本的 jQuery 吗?

    我正在从事的一个项目需要在客户的网页上使用 jQuery 客户将插入我们将提供的一段代码 其中包括一些
  • 无法在 Meteor 中解码下载的字体

    这是我的CSS font face font family geometria lightlight src url Geometria Light webfont eot src url Geometria Light webfont e
  • PyQt 与 Sqlalchemy 集成

    我正在尝试通过 Sqlalchemy 将使用 PyQt 创建的表单添加到数据库中 但我猜我的代码有问题 我收到此错误 le Users tunji Desktop employee py line 57 in AddEmployee ses
  • java中简单的“检查更新”库

    我正在使用 Eclipse RCP 但是 主要是因为我完全控制了 UI 删除了所有贡献 从头开始进行首选项等 我只是无法接受所包含的更新管理器的复杂性和需求 另外 我不使用插件功能 并且应用程序插件必须被提取 尽管我可以解决最后一个问题 不
  • 如何在 Laravel REST API 中使用 PUT 方法更新图像?

    我正在尝试使用 Laravel 构建一个 REST API 用户需要在其中更新他们的图像 但是 如果我在邮递员中使用 PUT 方法 它不会更新图像或将图像存储在指定文件夹中 如果我使用 POST 它会更新图像并保存在文件夹中 但它不会将文件
  • 更改日期格式化程序的区域设置

    我在我的应用程序中使用日期格式化程序来显示一些日期 但我希望该日期以阿拉伯语显示 所以我尝试更改格式化程序的区域设置 如下所示 var now new DateTime now var formatter DateFormat yMMMd
  • 如何使用 Asp.Net Core 实现基于权限的访问控制

    我正在尝试使用 aspnet core 实现基于权限的访问控制 为了动态管理用户角色和权限 create product delete product 等 它们存储在数据库中 数据模型就像https i stack imgur com CH
  • 如何加载外部文件并确保它首先在 JSFiddle 中运行?

    我有一个 JsFiddlehere http jsfiddle net deeptechtons rEzW5 2 并添加了通过外部 JS 资源部分加载的 Microsoft AJAX 如何判断 AJAX 文件加载完成后我的 JS 代码是否运
  • 单页应用程序 SEO 和无限滚动 AngularJS

    我们有一个网站 其提要类似于 pinterest 并计划将 jquery soup 重构为更结构化的内容 最有可能的两个候选者是 AngularJS 和 Backbone Marionette 该网站是用户生成的 主要以消费为导向 典型的