`
ayue222
  • 浏览: 49637 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

话说browser的脚本并行下载

阅读更多
    在讨论这次的主题之前,我们现在看一下脚本优化的另一个问题,就是“优化难度”。在这里我所说的“优化难度”是指优化一张页面时的修改难度。例如在前一片文章中,使用document.write来引入脚本的话,其“优化难度”会非常的低——没有任何副作用,不用修改其它任何代码。不过它的效果似乎还不太理想,因为仅仅优化了IE下的体验,在FireFox里却没有任何作用。

  很可惜,我回想了几乎所有的优化方式,再也没有找到优化难度如此低的做法了。对于其它的方式,我们都必须在页面的别处进行修改,优化效果越好,修改量越大。对于这些优化方式,我们就必须编写合适的组件,将一些逻辑封装起来。这样可以在一定程度上方便使用,降低优化难度。

  比较document.write与defer

  那么这又何document.write或者defer有什么关系?且听我慢慢道来。

  <script />的defer属性在标准里的定义是这样的:

  When set, this boolean attribute provides a hint to the user agent that the script is not going to generate any document content (e.g., no "document.write" in javascript) and thus, the user agent can continue parsing and rendering.

  我们当时遇到JS无法并行下载的原因就是浏览器认为在脚本中可能会输出HTML内容。defer属性的作用就是告诉浏览器,脚本里不会输出任何信息。果然,当我们在IE里使用defer属性时,脚本没有被阻塞,其效果和document.write一样。不过在FireFox里依旧不行,这样的实现实在让人费解。
都说FireFox标准,看来在细节上也不尽然。

  那么为什么我们在之前使用了document.write而不是defer属性呢?两者效果相同,但是明显使用defer属性更加直观啊。

  defer属性使用起来的确直观和方便。不过,效果真的相同吗?我们可以通过以下的例子试试看。

  document.write

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>Untitled Page</title>
  <script type="text/javascript" language="javascript">
    document.write(
      '<script type="text/javascript" language="javascript"' +
      ' src="Scripts.ashx?a"><' + '/script>');
    document.write(
      '<script type="text/javascript" language="javascript"' +
      ' src="Scripts.ashx?b"><' + '/script>');
    document.write(
      '<script type="text/javascript" language="javascript"' +
      ' src="Scripts.ashx?c"><' + '/script>');
  </script>
</head>
<body>
  <input type="button" value="Click" />
  <script type="text/javascript" language="javascript" src="Scripts.ashx?a">
    alert('Hello World');
  </script>
</body>
</html>


  然后再使用<script defer="defer"></script>的方式引入一下。打开两个页面进行比较就会发现,如果使用document.write的话,在脚本加载完毕之前按钮不会显示,也不会出现提示框;而如果使用defer属性的话,按钮就立即出现了,也会马上出现提示。

 这可麻烦了。如果页面上的元素过早出现,用户在脚本加载完之前进行操作是否会有问题?如果页面里存在直接执行的脚本(如上例的alert调用),在脚本文件加载完之前是否能够执行?如果上面两个问题的答案有任何一个是肯定的话,那么恭喜您,使用defer属性就会造成错误了。而且这个问题的解决方案实在不太容易找到,这大大增加了“优化难度”。

  而且更为关键的是,FireFox同样不支持defer属性的效果。这直接导致了defer属性全面落后于使用document.write的优化方式。既然这样,我们为什么要用它?事实上defer属性用的实在不多,这是个非常典型的的“鸡肋”特性。

  那么,哪里有使用defer属性的应用呢?我想应该是有的吧,虽然我不知道。

  突破两个连接的限制

  在上一片文章里我们可以看到,虽然document.write方法可以让脚本文件并行加载,但是它依旧受到浏览器的限制。根据HTTP协议的标准,对于同一个Domain,只能同时存在两个连接。在这点上,亲爱的浏览器们都乖乖的实现了。我们如果想要突破这种限制,就要增加域名。不过其实浏览器判断域名的方式是非常严格的,同一域名下的子域名,同一域名不同端口,都不算相同。一般来说,使用子域名来增加并行加载的连接数是比较常用的做法。

  应该已经有不少朋友知道这个方法,它的应用实在太普遍了。不过请注意,请求任意资源时都会建立连接,浏览器对于某一域名的连接并不区分其作用。因此,无论下载图片,CSS文件,JavaScript文件,或者是XMLHttpRequest对象建立的AJAX连接,都属于“两个连接”之内,在优化时往往需要注意这一点。另外,一个浏览器里同时建立的连接数也不是越多越好,根据实验资料显示,浏览器可以同时建立6到7连接最为合适。因此,我们使用3到4个子域名是比较妥当的。

 我们现在就来看一下使用效果。在开发时要出现这个效果,我们可以修改C:WINDOWS\system32\drivers\etc\hosts文件来设置本地的DNS映射。如下:

  在Hosts文件里添加如下映射

127.0.0.1 www.test.com
127.0.0.1 sub0.test.com
127.0.0.1 sub1.test.com
127.0.0.1 sub2.test.com
127.0.0.1 sub3.test.com
127.0.0.1 sub4.test.com
127.0.0.1 sub5.test.com


  我们可以多加一些子域名,方便以后使用。

  接下来我们就可以在页面里从多个不同的子域名加载脚本文件,如下:

  从不同子域名加载脚本文件

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>Untitled Page</title>
  <script type="text/javascript" language="javascript">
    document.write('<script type="text/javascript" language="javascript"' +
      ' src="http://sub0.test.com/Scripts.ashx?a"><' + '/script>');
    document.write('<script type="text/javascript" language="javascript"' +
      ' src="http://sub0.test.com/Scripts.ashx?b"><' + '/script>');
    document.write('<script type="text/javascript" language="javascript"' +
      ' src="http://sub1.test.com/Scripts.ashx?c"><' + '/script>');
    document.write('<script type="text/javascript" language="javascript"' +
      ' src="http://sub1.test.com/Scripts.ashx?d"><' + '/script>');
    document.write('<script type="text/javascript" language="javascript"' +
      ' src="http://sub2.test.com/Scripts.ashx?e"><' + '/script>');
  </script>
</head>
<body>
  ...
</body>
</html>


 在浏览器打开页面试试看?还记得当初我们加载页面用了多少时间吗?8秒多!而现在已经能够在不到2秒内加载完毕了(如图)
  • 大小: 9.7 KB
分享到:
评论

相关推荐

    Android Browser 源码

    7. **多窗口管理**:Android Browser支持多个标签页同时打开,源码中会有窗口管理和切换的实现,这对于实现多任务并行的Android应用开发有一定指导意义。 8. **手势和触摸事件处理**:Android Browser的源码展示了...

    前端开源库-browser-test-runner.zip

    为了提高测试效率,Browser Test Runner往往支持并行测试,这意味着可以在多个浏览器实例或设备上同时运行测试。这显著减少了整体测试时间,特别是在大型项目中。 五、模拟和Mocking 在测试过程中,有时需要模拟...

    Python库 | robotframework-browser-10.0.1.tar.gz

    3. **异步支持**:Robotframework-Browser库支持异步操作,这意味着测试可以并行执行,提高测试效率。例如,你可以在一个步骤中加载页面,同时执行其他任务,这在处理复杂的Web应用时特别有用。 4. **断言和验证**...

    Web Browser Programming in Python

    4. **Selenium Grid**:这个组件允许并行运行测试,可以在不同的机器和浏览器上分布式执行,大大提高了测试效率。 在Python中使用Selenium,首先需要安装`selenium`库,通常使用pip命令: ``` pip install selenium...

    前端开源库-browser-test-runner

    2. **并行测试**:为了提高测试速度,该库可以并行运行测试,充分利用硬件资源。 3. **断言库集成**:它可以与流行断言库如Jest、Mocha、Chai等无缝集成,提供丰富的断言方法。 4. **实时反馈**:测试结果会实时展示...

    Python-极简SeleniumWebDriver封装器用于同时使用在任意数量的网站速度限制之内并行处理友好

    3. **易用性**: 通过封装Selenium的常用功能,该库提供了简洁的API接口,使得开发者可以快速上手,减少编写和维护测试脚本的工作量。 4. **可扩展性**: 由于其模块化的设计,用户可以根据需求自定义扩展,添加新的...

    gpujs在浏览器中实现GPU加速的JavaScript

    GPUJS 是一个强大的JavaScript库,它允许开发者在浏览器环境中利用GPU的并行计算能力来提升代码性能,尤其适合处理大规模数据运算和图形渲染任务。在JavaScript开发中,尤其是在WebGL和WebAssembly等技术的支持下,...

    ruby watir介绍文档

    - **并行测试执行**:支持并行执行测试用例,有效提高测试效率。 - **错误处理**:内置了异常处理机制,能够更好地捕捉和处理错误,确保测试过程稳定可靠。 #### 三、安装与配置 ##### 3.1 安装Ruby环境 - 在开始...

    Python库 | sahi-0.3.0-py3-none-any.whl

    6. **并行测试**:Sahi允许并行运行多个测试用例,从而大大提高了测试效率,特别是在持续集成和持续交付流程中。 7. **报告与日志**:Sahi提供了详细的测试报告和日志,方便开发者分析测试结果,快速定位问题。 8....

    使用期总结

    - 并行执行测试用例以提高效率。 4. **测试覆盖度问题**: - 定期审查测试用例,确保它们涵盖了所有关键功能。 - 引入代码覆盖率工具来评估测试的质量。 #### 六、总结 通过上述介绍可以看出,使用Ruby与Watir...

    httpwatch植入型探针

    二是创建一个新的LR脚本,专门用于运行VBS脚本,与负载脚本并行执行。这里采用第二种方法,使用`SYSTEM()`函数调用VBS脚本,代码如下: ```vb Action() { int sysStatus; lr_think_time(30); sysStatus = system...

    Selenium-Java-3.141.59 安装包

    3. **Browser Support**: Selenium 3.141.59 支持所有主流浏览器,如Chrome、Firefox、Internet Explorer和Edge,以及对应的多个版本。这意味着你的测试脚本可以在不同浏览器环境中进行验证。 4. **API 更新**: 每...

    selenium-java-2.33.0.zip

    2. **Browser Drivers**:WebDriver 需要对应浏览器的驱动程序(如 ChromeDriver, GeckoDriver, IEDriverServer)才能与浏览器通信。2.33.0 版本可能包含或需要下载这些驱动,以便在不同浏览器上运行测试。 3. **...

    robotframework-selenium2library-1.5.0

    3. 并行测试:Robot Framework 支持多线程并行执行测试用例,这对于大型项目的测试效率提升非常有帮助。通过合理安排测试资源,可以同时在多个浏览器或多个操作系统上运行测试,确保测试覆盖的全面性。 4. 报告与...

    Python库 | arsenic-1.0.0.dev1.tar.gz

    利用Python的asyncio库,Arsenic支持并发执行多个浏览器会话,提高了爬虫的效率,尤其是在需要处理大量网页或需要并行登录多个账户的情况下。这意味着开发者可以编写出高性能的爬虫程序,而无需担心阻塞问题。 安装...

    multi-mechanize-master

    在"multi-mechanize-master"项目中,开发者可能通过创建多个`mechanize.Browser`实例,并在多线程或进程环境中运行,从而实现并行爬取,提高数据抓取速度。Python的`threading`或`multiprocessing`库可以用来实现这...

    CrossBrowser

    - 并行测试:为了提高测试效率,可能利用多线程或Selenium Grid进行跨浏览器并行测试。 "正在进行的惊喜"可能指的是项目正在扩展其功能,如集成其他测试工具(如TestNG,Cucumber等)、增加对移动浏览器的支持,...

    browsersync-themekit:展示浏览器同步开始的一个小片段,从themekit链接到shopify商店中的预览主题

    笔记: Shopify或Browser-sync不支持此程序... 您可以直接从节点脚本中使用它,我建议运行一个软件包,例如 ,使创建一个脚本并行触发多个任务,例如: npm run dev启动编译,themekit和browsersync。安装与设定安装br

    JavaScript 学习笔记之基础中的基础

    JavaScript是Web开发中不可或缺的一部分,尤其对于前端...- **async**:异步脚本不会阻塞HTML解析,允许脚本并行下载。异步脚本的执行顺序不可预测,因此,如果脚本依赖于DOM或其他脚本,不推荐使用async。 ```html ...

    Selenium3.5完整jar包

    2. **Browser Support**:Selenium 3.5支持多种浏览器,包括Chrome、Firefox、Internet Explorer、Edge以及Safari等,通过相应的WebDriver实现与浏览器的交互。其中,对于Firefox,Selenium 3.5开始支持GeckoDriver...

Global site tag (gtag.js) - Google Analytics