0

我正在尝试使用应用程序缓存和本地存储等技术编写一个可以在线和离线工作的应用程序。我正在使用 jQuery mobile 和 jqm 自动完成解决方案,可以在这里找到http://andymatthews.net/code/autocomplete/

这个想法是,如果应用程序在线,那么我将通过 ajax 调用一个远程访问函数,该函数将设置数据。发出的 ajax 调用会带回事件、国家和医院的数据。一旦返回数据,我将在 localStorage 中设置数据。

如果数据已经存在于 localStorage 中,那么我可以在离线时继续,因为我不必依赖 ajax 调用。

在 iPad/移动设备上运行时,我遇到了此代码的性能问题。就医院数据而言。有大量的医院数据被返回,请参阅下面的医院数据 JSON 示例。它在桌面上可能有点慢,但几乎没有那么糟糕。

任何人都可以看到我下面的代码的任何改进以提高性能。

JSON 医院数据示例

{ "hospitals" : { 
  "1" : { "country" : "AD",
      "label" : "CAIXA ANDORRANA SEGURETAT SOCIAL"
    },
  "10" : { "country" : "AE",
      "label" : "Advance Intl Pharmaceuticals"
    },
  "100" : { "country" : "AT",
      "label" : "BIO-KLIMA"
    },
  "1000" : { "country" : "BE",
      "label" : "Seulin Nicolas SPRL"
    },
  "10000" : { "country" : "ES",
      "label" : "Dental 3"
    },
  "10001" : { "country" : "ES",
      "label" : "PROTESIS DENTAL MACHUCA PULIDO"
    },
  "10002" : { "country" : "ES",
      "label" : "JUST IMPLANTS, S.L."
    },
  "10003" : { "country" : "ES",
      "label" : "CTRO DENTAL AGRIC ONUBENSE DR.DAMIA"
    },
  "10004" : { "country" : "ES",
      "label" : "HTAL. VIRGEN DE ALTAGRACIA"
    },
  "10005" : { "country" : "ES",
      "label" : "HOSPITAL INFANTA CRISTINA"
    }....


/*global document,localStorage,alert,navigator: false, console: false, $: false */

$(document).ready(function () {
//ECMAScript 5 - It catches some common coding bloopers, throwing exceptions. http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
//It prevents, or throws errors, when relatively "unsafe" actions are taken (such as gaining access to the global object).
//It prevents, or throws errors, when relatively "unsafe" actions are taken (such as gaining access to the global object).
"use strict";

//initialise online/offline workflow variables
var continueWorkingOnline, continueWorkingOffline, availableEvents, availableHospitals, availableCountries, availableCities;
continueWorkingOnline = navigator.onLine;

var getLocalItems = function () {

    var localItems = [];    
    availableEvents = localStorage.getItem('eventData');
    availableHospitals = localStorage.getItem('hospitalData');
    availableCountries = localStorage.getItem('countryData');

    if (availableEvents) {
        //only create the array if availableEvents exists
        localItems[0] = [];
        localItems[0].push(availableEvents);
    }
    if (availableCountries) {
        //only create the array if availableCountries exists
        localItems[1] = [];
        localItems[1].push(availableCountries);
    }
    if (availableHospitals) {
        //only create the array if availableHospitals exists
        localItems[2] = [];
        localItems[2].push(availableHospitals);
    }
    if (availableCities) {
        //only create the array if availableHospitals exists
        localItems[3] = [];
        localItems[3].push(availableCities);
    }
    return localItems;              
};


//Check to see if there are 3 local items. Events, Countries, Cities. If true we know we can still run page off line
continueWorkingOffline = getLocalItems().length === 3  ? true: false; 

//Does what is says on the tin
var populateEventsDropDown = function (data) {      
    var eventsDropDown = $('#eventSelection');

    var item = data.events;
    $.each(item, function (i) {
        eventsDropDown.append($('<option></option>').val(item[i].id).html(item[i].name));
    });
};

//Called once getData's success call back is fired
var setFormData = function setData(data, storageName) {
    //localStorage.setItem(storageName, data);
    localStorage.setItem(storageName, data);
};

//This function is only called if continueWorkingOnline === true
var getRemoteFormData = function getData(ajaxURL, storageName) {
    $.ajax({
        url: ajaxURL,
        type: "POST",
        data: '',
        success: function (data) {
            setFormData(data, storageName);             
        }           
    });
};

//Function for autoComplete on Hospital data
var autoCompleteDataHospitals = function (sourceData) {

    var domID = '#hospitalSearchField';
    var country = $('#hiddenCountryID').val();

    var items = $.map(sourceData, function (obj) { 
        if (obj.country === country) {
            return obj;
        } 
    });     

    $(domID).autocomplete({
        target: $('#hospitalSuggestions'),
        source: items,
        callback: function (e) {
            var $a = $(e.currentTarget);
            $(domID).val($a.data('autocomplete').label);                                        
            $(domID).autocomplete('clear');
        }
    });
};  

//Function for autoComplete on Country data
var autoCompleteDataCountries = function (sourceData) {

    var domID = '#countrySearchField';
    var domHiddenID = '#hiddenCountryID';

    var items = $.map(sourceData, function (obj) { 
        return obj; 
    }); 

    $(domID).autocomplete({
        target: $('#countrySuggestions'),
        source: items,
        callback: function (e) {

            var $a = $(e.currentTarget);
            $(domID).val($a.data('autocomplete').label);                                        
            $(domID).autocomplete('clear');
            $(domHiddenID).val($a.data('autocomplete').value);

            //enable field to enter Hospital
            $('#hospitalSearchField').textinput('enable');

            //Call to autoComplete function for Hospitals
            autoCompleteDataHospitals(availableHospitals.hospitals);
        }
    });     
};

if (continueWorkingOnline === false && continueWorkingOffline === false) {
    alert("For best results this form should be initiated online. You can still use this but auto complete features will be disabled");
}

if (continueWorkingOnline === true && continueWorkingOffline === false) {               
    getRemoteFormData('templates/cfc/Events.cfc?method=getEventsArray', 'eventData');       
    getRemoteFormData('templates/cfc/Countries.cfc?method=getCountriesArray', 'countryData');
    getRemoteFormData('templates/cfc/Hospitals.cfc?method=getHospitalsArray', 'hospitalData');

    $(document).ajaxStop(function () {
        //set the variables once localStorage has been set

        availableEvents = JSON.parse(localStorage.getItem("eventData"));
        availableHospitals = JSON.parse(localStorage.getItem('hospitalData'));
        availableCountries = JSON.parse(localStorage.getItem('countryData'));

        //Inserts data into the events drop down
        populateEventsDropDown(availableEvents);

        autoCompleteDataCountries(availableCountries.countries);            
    });
}

if (continueWorkingOnline === true && continueWorkingOffline === true) {                
    //get the localStorage which we know exists because of continueWorkingOffline is true

    availableEvents = JSON.parse(localStorage.getItem('eventData'));
    availableHospitals = JSON.parse(localStorage.getItem('hospitalData'));
    availableCountries = JSON.parse(localStorage.getItem('countryData'));

    //Inserts data into the events drop down
    populateEventsDropDown(availableEvents);

    autoCompleteDataCountries(availableCountries.countries);        
}       
});
4

1 回答 1

1

如果您的瓶颈是下载大量的 json 文件,那么减少瓶颈的唯一方法是使其更小或发送更少的数据。例如,您可以按国家/地区对医院进行排序并存储数组而不是带有键的对象,以使 json 更小,而不是一遍又一遍地重复键。

{
    "AD":[
        "CAIXA ANDORRANA SEGURETAT SOCIAL"
    ],
    "AE":[
        "Advance Intl Pharmaceuticals"
    ],
    ...
    "ES":[
        "Dental 3",
        "Dental 4",
        "Dental 5"
    ]
}

如果 id 字段很重要,请使用

    ...
    "ES":[
        ["10000","Dental 3"],
        ["10001","Dental 4"],
        ["10002","Dental 5"]
    ]

您当然需要更新其余代码以使用此 json 格式而不是您以前的格式。

于 2012-10-29T20:08:11.297 回答