0

アプリケーションキャッシュやローカルストレージなどのテクノロジーを使用して、オンラインとオフラインで動作するアプリを作成しようとしています。私はjQuerymobileと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 に答える