JSP: Function call inside loop becomes very slow. Help me optimize - performance

In my JSP, I loop through an object containing a list of employees and display it.
For each employee row, I also provide a link so that the user can view the employee's details. The link calls a Javascript function where the employee ID is passed.
The problem I am having is that the response time dramatically increases with the number of rows in my object. When my object contains over a thousand records, it takes at least 30 secs to render the page. Here's the code:
function getDetail(empID){
//AJAX call to get employee details}
}
.
.
<table>
<c_rt:forEach var="emp" items="${employeeListObj}">
<tr>
<td>
<c:out value="${emp.lastName}" />
</td>
</tr>
</c_rt:forEach>
</table>
I have narrowed down the culprit to the employee ID parameter being dynamic or being evaluated at runtime. I intially thought is it was a JSTL c:out issue, but I also tried changing to an ordinary JSP variable (i.e. getDetail('<%=ctr%>'), and the response time is still slow.
But when I changed it to a static string (i.e. getDetail('some static string')), the response time becomes fine.
I also tried passing it as a function (i.e. onClick="getDetail(function () {return ''})") but response time still didn't improve.
Is there a better (more optimized) way of doing this that will result in a better response time?

Thanks for the replies but I have figured out a simple solution. Not the most elegant, but it's a simple change and it serves my end user's needs (they dont want pagination, just a scrollable DIV area).
Instead of using this statement inside the loop:
<a href="#" onClick="getData('<c:out value="${emp.id}"/>')">
I used the employee ID as the ID of the anchor tag and passed that one instead:
<a id='<c:out value="${emp.id}"/>' href="#" onClick="getData(this.id)">
I don't know why, but the difference was night and day in terms of page rendering time. It now renders for just less than 5 secs compared to over a minute when passing the c:out value directly. I was dealing with 10,000 records btw.

If the problem is in the browser, you could replace the click handlers with attributes containing the number and a single click handler added through Javascript (eg, jQuery)
EDIT: For example:
$('table.SomeClass a').click(function() {
getDetail($(this).attr('data-employeeId'));
return false;
});

Related

ImportXML function in Google Dynamic XML path

I am trying to import the headlines and landing page URL's from "New + Updated" section of this page:
https://www.nytimes.com/wirecutter/
The issue is that the class "_988f698c" keeps changing as the headline is being replaced with a new headline/topic.
I need a workaround to use IMPORTXML function which will dynamically capture the class of that object in that position. The current formula is:
=IMPORTXML(https://www.nytimes.com/wirecutter/,"//*[#class='_988f698c']")
Here is the html tag for example. The class "_988f698c" refreshes every hour or so with new headlines coming in.
<li class="e9a6bea7">
<a class="_988f698c" href="https://www.nytimes.com/wirecutter/reviews/gir-spatula-review/">Why We Love GIR Spatulas</a>
<p class="_9d1f22a9">today
</p>
</li>
Is there a way I can do this?
Come back a little and look for an alternative path without forcing the use of random numbers.
For the title, use:
=IMPORTXML(
"https://www.nytimes.com/wirecutter/",
"//ul[#data-testid='new-and-updated']/li/a"
)
For the URL attached to the title:
=IMPORTXML(
"https://www.nytimes.com/wirecutter/",
"//ul[#data-testid='new-and-updated']/li/a/#href"
)
For the text indicating the day of publication:
=IMPORTXML(
"https://www.nytimes.com/wirecutter/",
"//ul[#data-testid='new-and-updated']/li/p"
)
If you want to collect everything together, use | to split the paths:
=IMPORTXML(
"https://www.nytimes.com/wirecutter/",
"//ul[#data-testid='new-and-updated']/li/a |
//ul[#data-testid='new-and-updated']/li/a/#href |
//ul[#data-testid='new-and-updated']/li/p"
)
only use it if you are absolutely sure that the values will always exist, because if they don't, you will have problems with the position in the sheet rows if you define formulas that depend on fixed values in each of the cells.

Web2py URL callback hidden when clicked and loading ajax

I have been developing an application using web2py. I have a page with a callback link which sends information to another function, this loads the results via ajax in the right sidebar of the page. When the link is clicked, the link itself disappears but the results are loaded correctly. I have to refresh the page for the links to come back. I have been looking at this for ages but can't figure it out, I am relatively new to web2py so probably missed something obvious.
Here is some code:
The view (With the link):
{{if hosts == "Please select a category":}}
{{response.write("Please select a category")}}
{{else:}}
<ol>
{{for i in hosts:}}
<li>{{=A(i['HostName'], callback=URL('selection','getResults.load', vars=dict(clicked=i['HostName'])), target="monitoredDevice")}}</li>
{{pass}}
</ol>
{{pass}}
{{end}}
{{block right_sidebar}}
<div id="monitoredDevice">
</div>
{{end}}
The controller action:
def getResults():
hostName = request.vars.clicked
# hostName = request.vars.hostNameSelected
print(hostName)
try:
task_status = scheduler.task_status(db.scheduler_task.task_name==hostName, output=True)
result = task_status.result
# create_compare_graph()
except(AttributeError): # Error is because there is no scheduler and therefore no status, need to set the values to 0
result = emptyTaskStatusResultsToZero()
try:
return dict(result)
except(TypeError): # There is a task scheduled however there is no run data as it has not been run before. Causes an error.
return emptyTaskStatusResultsToZero()
I think there is something wrong with the =A link in the view?
Thank you!
The method just prevents the view from getting an error if nothing is returned so I set all the values to zero so the view has something to render.
def emptyTaskStatusResultsToZero():
return {'percent_diff_in': 0, 'percent_diff_out':0, 'now_avg_30mins_in': 0
, 'now_avg_30mins_out':0, 'prev_week_avg_30mins_in':0, 'prev_week_avg_30mins_out':0,
'percent_more':0,'percent_less':0, 'count':0}

accessing the text value of last nested <tr> element with no id or class hooks

I need to access the value of the 10th <td> element in the last row of a table. I can't use an ID as a hook because only the table has an ID. I've managed to make it work using the code below. Unfortunately, its static. I know I will always need the 10th <td> element, but I won't ever know which row it needs to be. I just know it needs to be the last row in the table. How would I replace "tr[6]" with the actual last <tr> dynamically? (this is probably really easy, but this is literally my first time doing anything with ruby).
page = Nokogiri::HTML(open(url))
test = page.css("tr[6]").map { |row|
row.css("td[10]").text}
puts test
You want to do:
page.at("tr:last td:eq(10)")
If you do not need to do anything else with the page you can actually make this a single line with
test = Nokogiri::HTML(open(url)).search("tr").last.search("td")[10].text
Otherwise (this will work):
page = Nokogiri::HTML(open(url))
test = page.search("tr").last.search("td")[10].text
puts test
Example:(Used a large table from another question on StackOverflow)
Nokogiri::HTML(open("http://en.wikipedia.org/wiki/Richard_Dreyfuss")).search('table')[1].search('tr').last.search('td').children.map{|c| c.text}.join(" ")
#=> "2013 Paranoia Francis Cassidy"
Is there a particular reason you want an Array with 1 element? My example will return a string but you could easily modify it to return an Array.
You can use CSS pseudo class selectors for this:
page.css("table#the-table-id tr:last-of-type td:nth-of-type(10)")
This first selects the <table> with the appropriate id, then selects the last <tr> child of that table, and then selects the 10th <td> of that <tr>. The result is an array of all matching elements, if youexpect there to be only one you could use at_css instead.
If you prefer XPath, you could use this:
page.xpath("//table[#id='the-table-id']/tr[last()]/td[10]")

Find dynamic words through patterns in LINQ

Here is how the html starts
BUSINESS DOCUMENTATION
<p>Some company</p>
<p>
<p>DEPARTMENT: Legal Process</p>
<p>FUNCTION: Computer Department</p>
<p>PROCESS: Process Server</p>
<p>PROCEDURE: ABC Process Server</p>
<p>OWNER: Some User</p>
<p>REVISION DATE: 06/10/2013</p>
<p>
<p>OBJECTIVE: To ensure that the process server receive their invoices the following day.</p>
<p>
<p>WHEN TO PERFORM: Daily</p>
<p>
<p>WHO WILL PERFORM? Computer Team</p>
<p>
<p>TIME TO COMPLETE: 5 minutes</p>
<p>
<p>TECHNOLOGY REQUIREMENT(S): </p>
<p>
<p>SOURCE DOCUMENT(S): N/A</p>
<p>
<p>CODES AND DEFINITIONS: N/A</p>
<p>
<table border="1">
<tr>
<td>
<p>KPI’s: </p>
</td>
</tr>
</table>
<p>
<table border="1">
<tr>
<td>
<p>RISKS: </p>
</td>
</tr>
</table>
After this there is a whole bunch of text. What I need to do is from the above I need to parse out specific data.
I need to parse out the Department, Function, Process, Procedure. Objective, When to Perform, Who Will Perform, Time To Complete, Technology Requirements, Source Documents, Codes and Definitions, Risks.
I then need to delete this information from the Html column while leaving everything else in-tact. Is this possible in LINQ?
Here is the LINQ query I am using:
var result = (from d in IPACS_Documents
join dp in IPACS_ProcedureDocs on d.DocumentID equals dp.DocumentID
join p in IPACS_Procedures on dp.ProcedureID equals p.ProcedureID
where d.DocumentID == 4
&& d.DateDeleted == null
select d.Html);
Console.WriteLine(result);
This regex worked just fine for me on your input data
(DEPARTMENT|FUNCTION|OBJECTIVE):\s*(?<value>.+)\<
The result is multiple Matches with 2 groups each - the first the key and the second the value. I have only handled two cases, but you can add the rest easily enough.
To remove the information thus parsed, you can do a Regex.Replace with this regex
(?\(DEPARTMENT|FUNCTION|OBJECTIVE):\s*)(?.+)(?\)
and replacement string as
${start}${end}
leaving out value.
In code, this looks kinda like this (quickly typed this out in Notepad++ - may have minor errors).
private static readonly ParseDocRegex = new Regex(#"(?<start>\<p\>(?<name>DEPARTMENT|FUNCTION|OBJECTIVE):\s*)(?<value>.+)(?<end>\</p\>)", RegexOptions.ExplicitCaptured | RegexOptions.Compiled);
...
from html in result
let matches = findValuesRegex.Match(html)
where matches.Success
select new
{
namesAndValues = from m in matches.AsType<Match>()
select new KeyValuePair<string, string>(m.Groups["name"].Value, m.Groups["value"].Value),
strippedHtml = ParseDocRegex.Replace(html, "${start}${end}")
};
This ought to give you the desired output.
It can be done with many LINQ statements but using regular expressions you need only a few lines of code.
For HTML, you need an HTML parser. Try HTML Agility Pack or CsQuery.
Regular expressions can handle simple matches against HTML but are not sufficient for hierarchical structures and queries would be less precise.
Any HTML extraction is going to be fragile as the structure of the HTML charges. HTML is a presentation format and creators seldom care about machine interpretation. At least with a parser, you'll get an accurate model for the presentation markup (assuming it is valid HTML). You'll also get translation of entities into characters and the ability to extract all the descendant text of an element without internal markup elements like bold or italics.
You can use arbitrary assemblies in LINQPad simply by adding a reference, and for expression-based script, you can import designated namespaces automatically.

How to read id value of a DIV element using Selenium WebDriver?

<div id="ctl00_ContentHolder_vs_ValidationSummary" class="errorblock">
<p><strong>The following errors were found:</strong></p>
<ul><input type="hidden" Name="SummaryErrorCmsIds" Value="E024|E012|E014" />
<li>Please select a title.</li>
<li>Please key in your first name.</li>
<li>Please key in your last name.</li>
</ul>
</div>
here is my snippet for example. i want to get the value of ID i.e., ct100_contentHolder_vs_ValidationSummary. using selenium web driver. h
You can try this :
String id=driver.findElementByXpath("//div[#class='errorblock']").getAttribute("id"));
But in this case the class of this division should be unique.
Use following code to extract id of first div:
WebElement div = driver.findElement(By.tagName("div"));
div.getAttribute("id");
This is the code for all div available on the page:
List<WebElement> div = driver.findElements(By.tagName("div"));
for ( WebElement e : div ) {
div.getAttribute("id");
}
I know this answer is really late but I wanted to put this here for those who come later. Searching by XPath should be avoided unless absolutely necessary because it is more complicated, more error prone, and slower. In this case you can easily do what the accepted answer did without having to use XPaths:
String id = driver.findElement(By.cssSelector("div.errorblock")).getAttribute("id");
Some explanation... this line finds the first element (.findElement vs .findElements) using a CSS Selector. The CSS Selector, div.errorblock, locates all div elements with the class (symbolized by the period .) errorblock. Once it is located, we get the ID using .getAttribute().
CSS Selectors are a great tool that all automators should have in their toolbox. There's a great CSS Selector reference here: http://www.w3.org/TR/selectors/#selectors.

Resources