Big apps run slow in IE/Edge/Firefox but not Chrome


#1

I’ve tested running some of my apps in Chrome, IE/Edge/Firefox and I’ve noticed certain routines take a really long time in IE/Edge/Firefox but run at acceptable speed in Chrome. Is there a general reason why and is there a way I can make my Apps work quickly across all browsers?

I was using shinyapps.io free user account for testing.

Thanks,
Geoff


#2

Hi, I am running big app on IE too! When I deploy it to shinyapps.io , it tuns very slowly in IE11 but not in Chrome! Did you figure out the reason behind that? It takes few seconds to load the page initially!!!
If you have any suggestions please reply!

Thanks,
Karni


#3

Hi Karni,

Yes I did figure out what the issue was. For me it was due to using a long list (~14000 items) in a SelectizeInput() widget. For some reason, Chrome could handle it quite quickly whereas the other browsers could not. As a work around, I created a word filter textInput widget, that prefiltered the list, and then I used updateSelectizeInput(...) to update the much smaller list. This significantly sped things up across all browsers.

If your issue is similar to mine I could show you my code snippets that may help you implement such a solution.

If your issue is elsewhere, I recommend using the browser() function to go through your code line by line (deploy locally in the slow browser) and figure out what code chunk/widget is making things really slow.

Best,
Geoff


#4

Hi!

Thank you for replying back. My problem is I have a huge file (82000 rows) that needs to be uploaded and later to be displayed. I do the displaying using renderTable, which takes a lot of time in IE11 to display the uploaded file. Do you have any idea how can I solve that?

Thank you again for your support!
Best Regards,
Karni


#5

And this thing happens only when I deploy it to the shinyapps.io, but locally it works well.


#6

So locally it works well when using both browsers?

That is indeed a huge table. I would recommend pre-filtering the table before rendering it based on user input.

How can the table be categorized into smaller chunks? User those categories for the user to select from a drop down menu or use a text input box to filter based on what text the user enters.


#7

Hi!

I am still facing the same issue, and my problem is very similar to yours. I have a selectinput where the choices are very long list. That's why it takes time in IE11 to load. Please can you show me your code, than I can have a general idea of it?

I need to note that the choices of my selectinput are read from google cloud, as an example:
choices = read.delim(file ="https://storage.googleapis.com/gencode_ch_data/mouse/mouse_searchNames.txt",header=FALSE,stringsAsFactors = FALSE, sep="\t")

Thank you for your support!

Best Regards,
Karni


#8

Hey Karni,

I can show you a snippet of code, that I hope will allow to adjust to your needs. Basically using textInput the user enters key words. For you I'd set up a list of all from each row of your table that you expect useful to the user to enter to filter the table. Maybe it's just a code from each row. Paste all key elements (columns) of your table into a big list. Then the keywords entered will be compared to your big list. The indexes will be determined. From there you can either create a selectizeInput widget to list the filtered big list or you could immediately produce a table based on the filtered list. I recommend the former to avoid potential delays if the filtered list is quite large. Using selectizeInput the user can select an exact row from the table that they desire based on their key words. The row can be displayed with a DT::dataTableOutput widget or perhaps you plan to display a map point instead and you do not want a table as an output. For me I wanted a table output.

Here's the code:

Server side code

values <- reactiveValues() #you'll need this to update a value reactively though it is an option (see below)

proc_name = PRO3_3df$proc_detail #this is my list of detailed names where basically each name has the key 
                                                            #words from the table of interest. For you maybe just a code
proc_name = as.character(proc_name)
  
  values[["ecoinventFinds"]] = 0 # a reactive value that determines how many names found given the user's 
                                                  #textInput; this variable will be used to display number of filtered rows
  
#the following observes a textInput to see what the user enters
  observeEvent(input$ecoinventWordlookup,{  
    
    if(input$ecoinventWordlookup == ""){
      
    }else{
      ids_ecoinventlookup=0 
    input = input$ecoinventWordlookup 
    if(length(input) == 0){}
    else{
    test = ""
    splitInput = strsplit(input, " ") #split textInput by spaces
    names = proc_name #detailed names of list representing the table
    for(i in 1:length(splitInput[[1]])){ #loop through entered words
      if(length(names) == 0){
        
      }else{
          test = mapply(grepl,splitInput[[1]][[i]],names,ignore.case=TRUE) #finds places where entered text 
                                                                                                                #matches text in the detailed names list
          
          idx = which(test == TRUE)  #convert to indexes
          if(ids_ecoinventlookup[1]>0){
            idx = ids_ecoinventlookup[idx]  
          }
          
          names =PRO3_3df$proc_detail[idx] #select detailed names from list that match text
          ids_ecoinventlookup = PRO3_3df$mat_id[idx]
      }
      
        
    }
    
    values[["ecoinventFinds"]] = length(names) #number of names found
    
    
    updateSelectizeInput(session = session, inputId = 'e3_3', choices = names, server = TRUE) #update 
                                                                                                            #selectize list that user can choose from
    }
    }
  })
  

#an output to say your key words found n entries
  output$ecoinventFinds = renderUI({
          HTML(paste("<h5>",values[["ecoinventFinds"]]," processes found with your key words. Select from below:", "</h5>"))
    
  })
  
#create your table based on what user selects from the selectizeInput ('e3_3'). For me this requred extracting #values from a matrix; for you it might be as simple as returning the table row;
 #load the selected process recipe into tables
  processInput = reactive({
    
    if(is.null(input$e3_3)){Proc_in = data.frame("","","","")
    }else if(input$e3_3 == ""){
      Proc_in = data.frame("","","","")
    }else{ 
    process_name = input$e3_3
    idx = which(PRO3_3df$proc_detail == process_name,arr.ind = T)
    
    inputs_idx = which(A3_3[,idx] !=0, arr.ind = T)
    input_val = A3_3[inputs_idx,idx]
    pro_id = PRO3_3df[inputs_idx,1]
    proc_names = PRO3_3df[inputs_idx,2]
    pro_units = as.character(PRO3_3df[inputs_idx,12])
    
    
    Proc_in = data.frame(pro_id =pro_id, pro_name = proc_names, pro_values = input_val,pro_units = pro_units)
    }
    colnames(Proc_in) = c("ID","Process name","Value","Unit")
    Proc_in
  })
  
  
#render the table
  
  output$inputsTable = DT::renderDataTable({
    processInput()
    
  })

UI side code

fluidRow(
              column(1),
              column(10,align="left",
                     textInput("ecoinventWordlookup","Enter key words to filter processes (separate words with space):",NULL),
                     uiOutput("ecoinventFinds"),
                     selectInput('e3_3', 'Filter ecoinvent further based on your key words (for speed ensure that processes filtered are less than a 1000):', choices = NULL,width = '900px'),
                     br(),
                     downloadButton("export_process","Export to csv"),
                     br(),hr()
              )),
           fluidRow(
            column(1),
            column(10,align="left",
                   h3("Inputs from technosphere:"),
                   br(),
                   
                   div(DT::dataTableOutput("inputsTable"),style = "font-size:80%")
            )