zoukankan      html  css  js  c++  java
  • web页面优化之动态加载js和文件

    关于按需加载js,从而提高页面加载性能:

    以京东商品详情页面为例:

    首次打开时,会加载一部分js,当下拉滚动条时,会促发事件,从而以jsponp形式异步加载一些js文件,如评论调用的js文件:

    http://club.360buy.com/clubservice/newproductcomment-681391-3-0.html?callback=fetchJSON_CommentList(这个链接会被调用,从而加载对应的json数据,再配合实现先好的jsonp处理函数去处理,把结果赋值到对应的位置:

    如下是fetchJSON_CommentList实现写好的回调函数

    $(".btn-comment").livequery("click",
    function() {
        var a = $(this).attr("href");
        $.extend(jdModelCallCenter.settings, {
            clstag1: 0,
            clstag2: 0,
            fn: function() {
                jdModelCallCenter.autoLocation(a)
            }
        });
        jdModelCallCenter.settings.fn();
        return false
    });
    var CommentList = {
        getData: function(b, c, d) {
            var f = this,
            b = b || 0,
            c = c || 0,
            d = d,
            a = "http://club.360buy.com/clubservice/newproductcomment-" + G.sku + "-" + b + "-" + c + ".html";
            if (b == 1) {
                b = 3
            } else {
                if (b == 3) {
                    b = 1
                }
            }
            window.fetchJSON_CommentList = function(g) {
                if (!$("#comment .mc").hasClass("loaded")) {
                    if (parseInt(g.CommentSummary.CommentCount) !== 0) {
                        $("#comment").show();
                        $("#comment .mc").addClass("loaded").html(commentRate_TPL.process(g))
                    } else {
                        $("#comment").attr("nodata", "true").hide()
                    }
                    $("#comments-list .tab li").each(function() {
                        var j = $("#comments-list .tab li").index($(this)),
                        h = $(this).find("em");
                        switch (j) {
                        case 0:
                            h.html("(" + g.CommentSummary.CommentCount + ")");
                            break;
                        case 1:
                            h.html("(" + g.CommentSummary.GoodCount + ")");
                            break;
                        case 2:
                            h.html("(" + g.CommentSummary.GeneralCount + ")");
                            break;
                        case 3:
                            h.html("(" + g.CommentSummary.PoorCount + ")");
                            break;
                        case 4:
                            h.html("(" + g.CommentSummary.ShowCount + ")");
                            break
                        }
                    })
                }
                f.setItem(d, g, b, c)
            };
            $.getJSONP("http://club.360buy.com/clubservice/newproductcomment-" + G.sku + "-" + b + "-" + c + ".html?callback=fetchJSON_CommentList")
        },
        setItem: function(f, d, a, c) {
            var j = this,
            b = f,
            a = a || 0,
            c = c || 0,
            h = f.attr("id"),
            g = "";
            f.html(commentList_TPL.process(d));
            switch (h) {
            case "comment-0":
                g = "CommentCount";
                break;
            case "comment-1":
                g = "GoodCount";
                break;
            case "comment-2":
                g = "GeneralCount";
                break;
            case "comment-3":
                g = "PoorCount";
                break;
            case "comment-4":
                g = "ShowCount";
                break;
            default:
                g = "CommentCount"
            }
            $("#commentsPage" + d.Score).pagination(d.CommentSummary[g], {
                items_per_page: 7,
                num_display_entries: 5,
                current_page: c,
                num_edge_entries: 2,
                link_to: "#comments-list",
                prev_text: "\u4e0a\u4e00\u9875",
                next_text: "\u4e0b\u4e00\u9875",
                ellipse_text: "...",
                prev_show_always: false,
                next_show_always: false,
                callback: function(k, l) {
                    if (a == 1) {
                        a = 3
                    } else {
                        if (a == 3) {
                            a = 1
                        }
                    }
                    j.getData(a, k, b)
                }
            })
        }
    };

     以下参考:

    http://www.aichengxu.com/article/Javascript/610_7.html

    s无非就是script标签引入页面,但当项目越来越大的时候,单页面引入N个js显然不行,合并为单个文件减少了请求数,但请求的文件体积却很大。
    这时候最好的做法就是按需引入,动态引入组件js和样式,文件load完成后调用callback,运行js。代码还是很简便的
    1. 判断文件load完成。加载状态ie为onreadystatechange,其他为onload、onerror
    
    if(isie){
    Res.onreadystatechange = function(){
    if(Res.readyState == 'complete' || Res.readyState == 'loaded'){
    Res.onreadystatechange = null;
    callback();
    _self.loadedUi[modelName] = true;
    }
    }
    }else{
    Res.onload = function(){
    Res.onload = null;
    callback();
    _self.loadedUi[modelName] = true;
    }
    Res.onerror = function(){
    throw new Error('res error:' + modelName+'.js');
    }
    }
    2. 所有组件的命名最好保持一致,callback调用也比较方便。还可以根据需要增加参数比如: requires,依赖于那些文件;style,true || false,是否加载样式,等等。
    3. 移除操作也可以有,移除script、style标签、delete组件
    
    (function(window,undefined){
    if(!window.ui) {
    window.ui = {};
    }
    //动态加载ui的js
    window.bus = {
    config : {
    version : window.config.version,
    cssPath : window.config.resServer + '/css/v3/ui',
    jsPath : window.config.resServer + '/js/v2/ui'
    },
    loadedUi : {},
    readyStateChange : function(){
    var ua = navigator.userAgent.toLowerCase();
    return ua.indexOf('msie') >= 0;
    },
    loadRes : function(modelName,prames,callback){
    var _self = this;
    var Res = document.createElement(prames.tagName);
    for(var k in prames){
    if(k != 'tagName'){
    Res.setAttribute(k,prames[k],0);
    }
    }
    document.getElementsByTagName('head')[0].appendChild(Res);
    if(this.readyStateChange()){
    Res.onreadystatechange = function(){
    if(Res.readyState == 'complete' || Res.readyState == 'loaded'){
    Res.onreadystatechange = null;
    callback();
    _self.loadedUi[modelName] = true;
    }
    }
    }else{
    Res.onload = function(){
    Res.onload = null;
    callback();
    _self.loadedUi[modelName] = true;
    }
    Res.onerror = function(){
    throw new Error('res error:' + modelName+'.js');
    }
    }
    },
    removeUi : function(modelName){
    if(!modelName){
    return true
    };
    this.loadedUi[modelName] = false;
    var head = document.getElementsByTagName('head')[0];
    var model_js = document.getElementById('J_model_'+modelName + '_js');
    var model_css = document.getElementById('J_model_'+modelName + '_css');
    if(model_js && model_css){
    delete window.ui[modelName];
    head.removeChild(model_js);
    head.removeChild(model_css);
    return true;
    }else{
    return false;
    }
    },
    loadUi : function(modelName,callback,setting){
    if(!modelName){
    return true
    };
    callback = callback || function(){};
    if(this.loadedUi[modelName] == true){
    callback();
    return true
    }
    var deafult_setting = {
    style : true,
    js : true,
    requires : []
    }
    for(var key in setting){
    deafult_setting[key] = setting[key];
    }
    deafult_setting['style'] === true && this.loadRes(modelName,{
    id : 'J_model_'+modelName + '_css',
    name : modelName,
    tagName : 'link',
    type : 'text/css',
    rel : 'stylesheet',
    href : this.config.cssPath + '/' + modelName + '.css?v=' + this.config.version
    });
    deafult_setting['js'] === true && this.loadRes(modelName,{
    id : 'J_model_'+modelName + '_js',
    name : modelName,
    tagName : 'script',
    type : 'text/javascript',
    src : this.config.jsPath + '/' + modelName + '.js?v=' + this.config.version
    },callback);
    if(deafult_setting.requires.length > 0){
    for(var i=0,len = deafult_setting.requires.length;i<len;i++){
    this.loadUi(deafult_setting.requires[i]);
    }
    }
    }
    }
    })(window)
    
    使用方法
    
    // load comment for feed
    window.bus.loadUi('new_comment_feed', function(){
    window.ui.new_comment_feed($("#J_newsList"));
    },{
    style : false,
    requires:['emoticon','addFriend']
    });
    // load new yy ui
    window.bus.loadUi('yy', function(){
    window.ui.yy(options);
    },{
    style:false,
    requires:['emoticon']
    });
    // load photoLightbox
    window.bus.loadUi('photoLightbox', function(){
    window.ui.photoLightbox(options.urlAjaxGetFriendPhoto, options.urlCommentOtherPhoto,$("#J_newsList"),options.myUid,options.myName);
    }); 
  • 相关阅读:
    ubuntu11.04更改默认JDK
    10个实用的jQuery交互/通信插件和教程
    jquery 使用方法
    在没有安装 ASP.NET MVC3 的服务器上运行 MVC3
    固定 vs. 流动 vs. 弹性:哪种布局更适合你?[SM]
    提升设计品质的8种布局方案[SM]
    Ubuntu 手动安装JDK
    十个简单好用的设计技巧[SM]
    jQuery VSDoc下载地址
    Ubuntu 配置Apache+PHP+MySQL
  • 原文地址:https://www.cnblogs.com/Alight/p/2890903.html
Copyright © 2011-2022 走看看