【达生科技】突破浏览器域名并发限制的解决方案

背景

拿Chrome浏览器来说,同域名下资源加载的最大并发连接数为6,当资源文件大于6时,多于6个的文件就会进入待定,等第一批加载完才会加载第二批的6个图片资源,这样就增加了等待时间。无形中就增加用户加载网页等待的时间。

waiting.jpeg

思考

对于这种并发限制,可以有什么方法来解决这种问题呢?
既然最大并发数为6,那我们就把N个资源URL替换成N/6个不同域名,这样就有N/6个最大并发可以同时发生了。
先来看看我们处理前后的比对情况吧。

效果展示

本文拿图片加载来举例【具体的资源加载时间因不同设备不同网速而不同,仅供参考】


处理前

当一个网页的图片资源在同一个域名情况下加载,如图,30个图片总用时【1.11s】

waitFinish.jpeg

最后一个图片资源连接开始后的停转时间(即图片资源加载的等待响应时间)【357ms】

waitTime.png


处理后

同样的运行环境,同样的资源在多个域名(同一个ip)情况下加载,如图,30个图片总用时【424ms】

noWait.jpeg

最后一个图片资源连接开始后的停转时间【0.64ms】

noWaitTime.png


对比结果:在本示例中,同样的资源,同一个IP,处理资源加载域名限制后,速度可以优化【60%】。用最后一张加载的图片对比,连接开始后的停转时间优化比也达到【99.8%】


实现方法

  • 实现思路

    • 在DNS服务商中申请多个域名,指向同一个 IP 服务。
    • 对后台返回的数据进行域名处理,对图片链接,进行域名替换。
    • 域名替换完成后,通过 localStorage 进行 key / value 保存。以使得相同图片在下一次展示时,能使用浏览器缓存,而非重复加载。
  • 代码实现【本方法仅用在ajax回调中】 =》 示例代码如下:

        // 替换域名
        function replaceDomain(data) {
          let imgUrlObj = localStorage.getItem('imgUrlObj') || {} // 获取本地保存的图片链接,能正常使用缓存
          if (typeof(imgUrlObj) === 'string') { // 判断是否为JSON对象,不是则转换
            imgUrlObj = JSON.parse(imgUrlObj)
          }
          let index = Math.floor(Math.random() * 4.99) // 随机0-4的下标
          try {
            data = JSON.stringify(data)
            data = data.replace(/www\.baidu\.com\/image(.*?)(jpg|png|jpeg)/g, (...params) => { // 查找图片的url并对其进行操作
              let sourceUrl = params[1] + params[2] // 图片资源名称,未包含域名。如:整条图片链接为:www.baidu.com/image/123.png; 现保存为:/image/123.png
              if (!imgUrlObj[sourceUrl]) { // 未保存在本地,则新产生域名
                let imgUrl = `node${[1, 2, 3, 4, 5][index % 5]}.baidu.com/image/${sourceUrl}` // 域名替换,如:从 www.baidu.com 替换到 node1.baidu.com,node2.baidu.com
                imgUrlObj[sourceUrl] = imgUrl // 同时保存好新的域名,在这就体现了使用JSON对象的好处,图片资源路径名当key值,图片完整链接当value值
                localStorage.setItem('imgUrlObj', JSON.stringify(imgUrlObj))
                index++
                return imgUrl
              } else { // 保存到了本地,则直接使用localStorage的url
                return imgUrlObj[sourceUrl]
              }
            })
            data = JSON.parse(data)
          } catch (e) {
            console.log('replaceDomain error')
            console.log(e)
          }
          return data
        }
  • 另外,为了加快DNS解析,可以进行DNS预加载

    <!-- 配置 Mate 进行域名预加载 -->
    <!-- dns预加载 -->
    <link rel="dns-prefetch" href="//node1.baidu.com" />
    <link rel="dns-prefetch" href="//node2.baidu.com" />

完结,撒花

shuai.jpeg


原创小文章
专注中小团队开发。 前端技术,效率工具分享与探讨。
44 声望
1 粉丝
0 条评论
推荐阅读
单文件组件下的vue,可以擦出怎样的火花
与时俱进吧,看着 vue3 和 vite,虽然不会用,但还是心痒痒,然后就把原先基于 vue@2 的实现做了重构。不周之处,大家见谅!下面关于过期的内容,我就用删除线标记了。

leftstick65阅读 45.2k评论 18

从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木150阅读 12.4k评论 10

正则表达式实例
收集在业务中经常使用的正则表达式实例,方便以后进行查找,减少工作量。常用正则表达式实例1. 校验基本日期格式 {代码...} {代码...} 2. 校验密码强度密码的强度必须是包含大小写字母和数字的组合,不能使用特殊...

寒青56阅读 7.9k评论 11

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy46阅读 6.1k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木66阅读 6.2k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs40阅读 6.4k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木44阅读 7.5k评论 6

44 声望
1 粉丝
宣传栏