相关文章
一种小拖大的jssdk加载方案
2024-12-01 08:00
一种小拖大的jssdk加载方案 方案

jssdk 是在前端中完成某些业务功能的 Javascript 函数库,通常由 sdk 的开发者开发完毕后,交给业务的页面来引入使用。例如:

在一些特殊的场景(例如联盟广告)下,我们通常需要把一个 jssdk 地址 交付给另外一个团队的页面来引入。对于大型广告联盟商来说,一般是提供自己的联盟广告平台,在平台上,开发者可以申请到广告appid,并按照文档引入广告 sdk 到自己的页面中使用。一切比较顺利。

但在公司内部,我所在的商业化部门并没有形成如此成熟的平台。这时我们采用的是比较原始的办法,我所在的商业化部门要把广告sdk开发完成后,部署到cdn。然后我们部门将 cdn地址如 “http://a.b.c/12345.js” 告知对方业务部门的相关开发,让对方放置我的js到对方的页面当中。每次开发、测试、部署,我们的js资源地址必然会发生变化,结果就是每次都要找对方部门沟通协调部署问题,部署成本巨大。在没有良好的机制协调下,往往会造成开发和测试发布成本上升,效率低端低下。

为了解决该问题,我在现状的基础上,设计了一种“小拖大”的jssdk加载方案,彻底解决对对方部门的依赖。

先看下现状我们的工作模式是怎样的:

一种小拖大的jssdk加载方案

我,作为广告团队的开发,要么是把广告组件做成npm包交给对方;要么是把广告做成js放cdn交给对方。每一种方式都要找对方联调和沟通,npm包的方式对方还要编译到对方业务中,其成本和出错的概率更大。最蛋疼的是,第二种cdn交付方式,每次通知对方后,对方需要去后台配置一下我给他的js地址,然后他下发后,客户端浏览器才会真正的请求最新的js地址。

工作模式画成时序图,如下:

一种小拖大的jssdk加载方案

其缺点比较明显:

  • 架构上: 不符合现在分团队的开发模式
  • 流程上: 多了冗余的沟通,例如找后台同学配置
  • 技术上: jssdk下发方式不够标准,不够原生,不够灵活

如何能够减少依赖,降低沟通成本呢。其实最简单的方法就是让对方引入一个固定的js地址就好了。目标很明确!

即,我期望实现JSSDK,在不依赖页面方的情况下自更新?

我们最容易想到的方案便是:给对方一个固定js地址,每次我们更新的广告代码,我们就在此地址上更新js。但这样的话,有几个问题:

  • 我们的广告组件便没有了版本的概念,回滚时只能回滚git
  • 我们的广告jssdk,彻底没有了缓存。如果我们的jssdk体积增大,那么用户每次打开页面都要下载一个大js
  • 也无法利用cdn就近的优势

基于这种考量,我设计了一种 “小拖大” 的方案,这种方案放弃了20%的缓存能力,但能保留住80%的缓存能力。用20%的缓存放弃,换来开发效率极大的提升,对于广告场景来说是比较适合的,因为广告并不是一个页面中最核心的性能诉求,页面最关键的是基本功能的性能和展示,其次才是广告的正常展示和渲染,因此广告适当少量的延迟并不会有太大的影响。

以下是我对几种方案的对比图:一种小拖大的jssdk加载方案

于是,一个新的更适应我当前场景的jssdk加载方案,其时序图是这样的:

一种小拖大的jssdk加载方案

文字描述一个完整的首次广告请求如下:

  • 首先将我们的 “种子sdk” 地址放入对方业务页面(种子sdk将是一个固定不变的jssdk地址),
  • 对方业务页面被用户打开后,会发起对种子jssdk的请求
  • 种子sdk请求到达我方 sdk server 后,我方 sdkserver实时生成一个 seed.js ,其中会放入当前各个广告组件最新版本的真实cdn地址的一个“资源映射表”
  • 当页面收到服务端返回的 seed.js。页面中可以根据业务广告的需求,随意创建任何类型的广告。例如创建一个文中广告:
  • 此时,seed.js 发现业务要实例化一个 ArticleAd 的广告,则seed.js会查询资源映射表,找到 ArticleAd 的真正cdn地址并完成广告代码加载和初始化渲染

由于cdn上的真正的广告js是强缓存的,因此用户在大部分情况下,都将会使用本地缓存的广告jssdk。唯一的缺点是 seed.js 是需要每次都发起请求的(由于广告不会每小时都在更新,因此这里也可以将 seed.js 设置为强缓存1天或1小时)。

由于 seed.js 核心代码仅仅有不到100行,因此其体积微乎其微,加载时间也非常的快。

下面我们来看整个架构中比较核心的 seed.js 是如何实现的。这里要考虑如下一些问题:

  • seed如何实现异步加载组件和组件注册?
  • 如何保证多次加载时避免重复加载?
  • 组件加载完成后如何通知seed继续执行?
  • seed加载器如何知道js资源最新地址?
  • 组件版本更新后如何第一时间更新页面?
  • 如何方便页面调试?

种子js 并不是一个静态的 js,由于它需要内置一个最新版本的资源映射表。因此他是由 server 端动态来生成的,我们 server 端可以采用 Node.js 配合模板引擎来实现。

webpack 中有个 动态 import 的能力,即可以让我们在代码中书写:

这样的代码。然后浏览器中加载时,会动态远程加载并将abc.js的导出作为本地webpack的一个模块来使用。

这个思路就有点类似于我们本文所述的 seed.js 要完成的功能,因此我们来看看它webpack是如何实现动态 import 的:一种小拖大的jssdk加载方案

其底层逻辑还是比较简单的。

但是我的seed.js并不想实现的那么重,也不需要有 require loader 这样的概念。

  1. webpack 有chunk概念,对我们来说我用不到。
  2. 需要主调模块中写明被调组件名和哈希地址,他是在编译期实现进行代码分割。而我的seed.js希望简化逻辑且不应该存在调用代码,且要支持后端任意动态新增组件。

于是,我在此基础上实现了一个更适用于本场景的简单的版本。其大概逻辑如下:

  1. 我在服务端会将当前的 "广告资源cdn地址映射表" 插入到下图的 RES_MAP 这个对象当中。

一种小拖大的jssdk加载方案

  1. 实现一个generate函数,等待对方业务调用

一种小拖大的jssdk加载方案该函数的功能是:当对方业务调用 generate('ArticleAd') 这样的函数时,则意味是要创建并初始化一个 ArticleAd 的广告,那么seed.js需要去主动加载 ArticleAd 广告的js资源,并完成初始化。其中 _loadModule 函数会去 RES_MAP映射表中寻找资源地址,并完成js资源加载和内存缓存(防止多次调用generate)一种小拖大的jssdk加载方案

有了 seed.js 去负责加载真正的广告js。那么,我们广告开发者的工作只需关注在:如何开发一个真正的可以被 seed.js 加载的 广告sdk即可。

那么,如何能让真正的广告sdk开发更有效率呢? 我的期望是这样的:

一种小拖大的jssdk加载方案

我期望如上图,每一个广告组件是一个标准的目录结构。如上图绿色部分是一个广告组件,红色部分是另外一个广告组件。每个广告组件都有固定的编写模式和规范,包括:

  • index.html 是本地调试的demo页面
  • img存放图片资源
  • jsapi.js 放置工具函数
  • main.js 是你广告sdk的执行入口
  • style.scss是样式代码
  • template.art 是你广告dom的模板

其中main.js 会被webpack编译,并打包成一个 bundle.js。而这个 bundle.js就是你所开发的广告组件的sdk,他将被seed.js加载并执行。

问题来了。我们一个广告组件的 main.js 不可能平白无故就可以被 seed.js加载执行,他需要有一定的配合才可以。就我目前的场景来说,我的广告js中的main.js需要如下的桩代码来完成主动向 seed.js 来注册自己:

可是,总不能让广告组件的开发者每个人都记得在 main.js 底部写上这样一段代码。因此,我使用 webpack 的 loader 来实现自动给 main.js chunk 添加桩代码,loader 的实现如下:

文中开头有提到,我们的 seed.js 每次给用户返回时,都会将一个最新资源映射表放置到 seed.js 中的 RES_MAP 对象上。那么这个资源映射表是怎样形成的呢。

这里,我们可以借助 webpack 插件来将每次开发广告的同学编译或CI出来的最新 sdk 地址记录下来,并最终输出为一份资源映射表。

webpack 插件的实现代码如下:

最终在meta.json中,我们将会看到这样的结果:

所有文件名,广告资源名,都是按照我们广告组件开发的约定自动由webpack生成的。

至此,开发同学只需在接到一个广告开发需求时,打开我们的项目,新建一个对应的文件夹如 “my-ad”。按照约定创建响应的文件,开发过程中使用 预览。开发结束后走 CI,CI执行 生成资源映射表。然后我们将映射表配置到 seed.js server即可。

配合上 CI 流水线的话,就会更加简便了:

一种小拖大的jssdk加载方案

最后我们再来思考下广告jssdk交给对方页面引用时,最好是用何种方式引用呢?

我们可以这样思考:对于业务来说,页面的核心诉求是保证基本功能的使用。其次才是统计和广告等附加需求。

因此,在业界统计和广告jssdk通常尽量采用异步的方式来加载,例如百度提供的异步加载方式:

这种方式类似于script标签的 async 属性的功能,可以让js脚本的加载和执行不阻塞当前脚本所在位置的html dom树构造和渲染。

    以上就是本篇文章【一种小拖大的jssdk加载方案】的全部内容了,欢迎阅览 ! 文章地址:http://gzhdwind.xhstdz.com/news/9462.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 物流园资讯移动站 http://gzhdwind.xhstdz.com/mobile/ , 查看更多   
最新文章
适合中老年游戏活动的项目有哪些?
引言:为何中老年游戏活动尤为重要 随着社会的不断发展和生活水平的提升,中老年人的生活方式也随之改变。对于他们来说,健康和快乐成为了生活的重要组成部分。而游戏活动,不仅能够增加社交互动,还能锻炼身体与思维。因此,选择适合中老
上海旅游攻略:探访繁华之都的风情韵味
引言:开启上海的奇妙之旅 上海,这座迷人的城市,拥有着深厚的文化底蕴与现代化的繁华景象,无论是初次造访还是再次归来,都会让人惊叹于它独特的风情韵味。在这里,历史与现代交融,传统与创新并存,等待着你去探索这座繁华之都的每个角
高新企业网站优化方法大揭秘!
高新企业网站的重要性 随着互联网的快速发展,企业网站已经成为企业宣传、推广和营销的重要渠道。对于高新技术企业来说,网站更是展示企业形象、产品技术、行业影响力的窗口。因此,如何优化企业网站,提升网站的曝光率和用户体验成为了高
探索旅游景区的独特魅力:人文、自然与体验的完美结合”
引言:旅游景区的魅力所在 在如今快节奏的生活中,越来越多的人选择通过旅行来放松身心,寻找内心的宁静。在旅游的过程中,景区的选择则显得尤为重要。一个优质的旅游景区不仅仅是壮丽的自然风光,还有深厚的人文底蕴和丰富的体验活动。本
提升健康与活力:探索运动健身的多样化内容与方法
引言:健身的时代已来临 随着人们生活水平的提高,越来越多的人开始关注自身的健康与活力。运动健身不再是一种单一的方式,而是发展出了多样化的内容与方法。无论是为了减肥、塑形,还是增强体质,运动健身都成为了许多人的日常习惯和生活
80岁老人旅游规定的常见问题及注意事项解析
引言:老年人的旅游热潮 随着社会的发展和生活水平的提升,越来越多的老年人开始积极参与到旅游活动中。他们用实际行动证明,年龄并不是旅途的限制,反而是丰富人生经验的体现。虽然老年游客在旅途中享有更多的自由和乐趣,但在旅游规定及
AI写作论文是否会被检测?解密检测机制!
引言:AI写作的崛起 近年来,人工智能(AI)技术的发展迅猛,尤其是在写作领域。AI写作工具不仅能生成高质量的文章,还能满足不同用户的需求,成为内容创作的得力助手。然而,伴随着AI写作的普及,一个新的问题也逐渐显现出来:AI写作论文
几月份去兰州旅游最宜?
探索兰州的四季魅力 兰州,作为甘肃省的省会,坐落于黄河之畔,是一座历史悠久的城市,兼具独特的自然风貌与深厚的人文底蕴。每个季节,兰州展现出不同的面貌,吸引着四面八方的游客前来探索。那到底几月份去兰州旅游最为宜人呢?接下来,
探索中国旅游标志的原型与文化内涵的深度解读
探索中国旅游标志的原型与文化内涵 中国作为一个拥有悠久历史和丰富文化的国家,其旅游标志更是象征着一种独特的文化内涵。中国旅游标志的原型多取材于中国传统艺术元素,加之对中国文化的理解与诠释,形成了独具魅力的形象。 中国国徽与中
轻松搞定!服务器配置RAID:提高性能数据安全双保险!
轻松搞定!服务器配置RAID:提高性能数据安全双保险! 随着信息技术的不断发展,服务器在企业中扮演着至关重要的角色。为了提高性能和数据安全,服务器配置RAID已经成为了一种常见的选择。RAID(Redundant Array of Independent Disks)即
相关文章