zoukankan      html  css  js  c++  java
  • 做一名合格的前端开发工程师(12篇)——第一篇 Javascript加载执行问题探索

       楼主做前端开发一年多了,对前端的见解还是多多少少有一点的,今天特拿出来跟大家分享分享。

    做前端开发少不了各种利器。比如我习惯用的还是Google浏览器和重型武器Fiddller。

    一: 原始情况

    首先大家看看如下的代码:

     1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JsLoad.Default" %>
    2
    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4 <html xmlns="http://www.w3.org/1999/xhtml">
    5 <head id="head">
    6 <title></title>
    7 <link href="Styles/Site.css" rel="stylesheet" type="text/css" />
    8 <script src="jquery/jquery-1.4.1.js" type="text/javascript"></script>
    9 <script src="js/hello.js" type="text/javascript"></script>
    10 <script src="js/world.js" type="text/javascript"></script>
    11 </head>
    12 <body>
    13 <img src="1.jpg" width="200" height="300" />
    14 </body>
    15 </html>

    估计90%的程序员都会把js文件放在head中,但是大家有没有深究过呢?很多浏览器都会使用单一的线程来做“界面UI的更新”和“JS脚本的处理“,

    也就是当执行引擎遇到”<script>“的时候,此时页面的下载和渲染都必须等待<script>执行完毕。那么对用户而言就悲哀了,看着锁住的页面,

    此时用户很可能就会给你关掉。

    从上面的瀑布图中我们可以看出二点:

       第一:

                  三个js文件并行下载,但是按我上面的理论中js应该是一个接一个的执行。然而在IE8,Firefox3.5和Chrome2都实现了js的并行下载,

               这是相当不错的,但是他还是会阻碍一些其他资源的下载,比如说图片。

       第二:

                图片1.jpg的下载是在js执行完成后触发的,这也验证了上面所说的情况,阻止了image的加载。

    二:第一步优化

           既然js阻止了UI渲染,那么我们可以考虑将js放在</body>前,这样就可以让<script>前的html完美的呈现,不会让用户看到页面空白等待

        而苦恼的情况,自然就提高了友好性。

     1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JsLoad.Default" %>
    2
    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4 <html xmlns="http://www.w3.org/1999/xhtml">
    5 <head id="head">
    6 <title></title>
    7 <link href="Styles/Site.css" rel="stylesheet" type="text/css" />
    8 </head>
    9 <body>
    10 <img src="1.jpg" width="200" height="300" />
    11 <script src="jquery/jquery-1.4.1.js" type="text/javascript"></script>
    12 <script src="js/hello.js" type="text/javascript"></script>
    13 <script src="js/world.js" type="text/javascript"></script>
    14 </body>
    15 </html>

         下面的图也展示了1.jpg和三个js几乎并行下载和执行。时间由上面的“469ms+”缩小到“326ms”。

    三:第二步优化

            看上面的“瀑布图”,估计大家也看出来了,三个js文件进行了三次“Get”请求,大家都知道Get请求是需要带http头的,

       所以说需要耗费时间,那么我们采取的方案自然就是减少Get请求。通常有两种方案。

       第一:合并js文件,比如将上面的“hello.js"和“world.js“合并掉。

       第二:利用第三方工具,比如php中的Minify。

       

       关于第二种做法,taobao用的还是比较多的,看一下其中的一个script,应用了三个js文件。由3个Get请求变为了1个。

    四:第三步优化

         不管是把js文件放在脚尾,还是三个合并一个,其本质都是”阻塞模式“,就是说锁死浏览器,当web页面越来越复杂,js文件越来越多,还是

     让我们头疼的,此时我们就提倡一种“无阻塞模式“加载js脚本,也就是页面全部呈现完再追加js,也就对应着window.onload事件触发后,我们才

     追加js,这就是所谓的“无阻塞“,但是其中有一个非常要注意的地方就是我们对js的要求是否有严格的顺序。

       

        第一:无顺序要求,比如我对”hello.js“和”world.js"没有顺序要求,那么我们完全可以用jquery来动态追加实现。

     1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JsLoad.Default" %>
    2
    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4 <html xmlns="http://www.w3.org/1999/xhtml">
    5 <head id="head">
    6 <title></title>
    7 <link href="Styles/Site.css" rel="stylesheet" type="text/css" />
    8 </head>
    9 <body>
    10 <img src="1.jpg" width="200" height="300" />
    11 <script src="jquery/jquery-1.4.1.js" type="text/javascript"></script>
    12 <script type="text/javascript">
    13 window.onload = function () {
    14 $("#head").append("<script src='js/hello.js' type='text/javascript'><\/script>")
    15 $("#head").append("<script src='js/world.js' type='text/javascript'><\/script>");
    16 }
    17 </script>
    18 </body>
    19 </html>

    从图中可以看出,"hello.js"和“world.js"出现在蓝色线以后,也就说明这两个js是在DomContentLoad结束后再进行触发加载的,这样就不会造成页面的锁定

    等待。

    第二:有顺序要求

             为什么一定要有顺序要求这个概念呢?对于上面的那个动态追加的“两个js”文件,在IE系列中,你不能保证hello.js一定会在world.js前执行,

        他只会按照服务器端返回的顺序执行代码。

     1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="JsLoad.Default" %>
    2
    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4 <html xmlns="http://www.w3.org/1999/xhtml">
    5 <head id="head">
    6 <title></title>
    7 <link href="Styles/Site.css" rel="stylesheet" type="text/css" />
    8 </head>
    9 <body>
    10 <img src="1.jpg" width="200" height="300" />
    11 <script type="text/javascript">
    12 function loadScript(url, callback) {
    13 var script = document.createElement("script");
    14 script.type = "text/javascript";
    15
    16 //IE
    17 if (script.readyState) {
    18 script.onreadystatechange = function () {
    19 if (script.readyState == "loaded" || script.readyState == "complete") {
    20 script.onreadystatechange = null;
    21 callback();
    22 }
    23 }
    24 } else {
    25 //非IE
    26 script.onload = function () {
    27 callback();
    28 }
    29 }
    30 script.src = url;
    31 document.getElementById("head").appendChild(script);
    32 }
    33 //第一步加载jquery类库
    34 loadScript("jquery/jquery-1.4.1.js", function () {
    35 //第二步加载hello.js
    36 loadScript("js/hello.js", function () {
    37 //第三步加载world.js
    38 loadScript("js/world.js", function () {
    39
    40 });
    41 });
    42 });
    43 </script>
    44 </body>
    45 </html>

    大家也能看到,页面完全Load的时间其实也就310ms左右,大大提高了网页的下载呈现和友好型。

    同样也可以看看腾讯网,他也是这么干的。

  • 相关阅读:
    io学习
    asp.net文件上传进度条研究
    asp.net页面中的Console.WriteLine结果如何查看
    谨慎跟随初始目的不被关联问题带偏
    android 按钮特效 波纹 Android button effects ripple
    安卓工作室 日志设置
    安卓工作室 文件浏览器 android studio File browser
    一个新的Android Studio 2.3.3可以在稳定的频道中使用。A new Android Studio 2.3.3 is available in the stable channel.
    新巴巴运动网上商城 项目 快速搭建 教程 The new babar sports online mall project quickly builds a tutorial
    码云,git使用 教程-便签
  • 原文地址:https://www.cnblogs.com/huangxincheng/p/2275988.html
Copyright © 2011-2022 走看看