Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the way we translate our website result in performance issues?

Background

Our site is a press site and is viewed by many people around the globe. Obviously this means that we will be localising the site in as many languages as possible. A professional translator will be hired for each language.

How our site works currently

The way we have planned to do this is by storing a translation for each element of the page in the database linked by a Guid. So when the page loads the strings are pulled out of the database using the Guid and the language preferences of the user.

We have several documents in our project that contain english translations. Such as this:

public class StandardButtonToken : LocalisationToken
{
    protected StandardButtonToken(string defaultText, Guid key) : base(defaultText, key)
    {
    }

    public static readonly LocalisationToken Update = new StandardButtonToken("Update", Guid.Parse("8a999f5b-7ca1-466d-93ca-377321e6de00"));
    public static readonly LocalisationToken Go = new StandardButtonToken("Go", Guid.Parse("7a013ecc-0772-4f87-9f1f-da6a878a3c99"));
    public static readonly LocalisationToken Edit = new StandardButtonToken("Edit", Guid.Parse("c31be427-5016-475d-997a-96fa5ff8b51f"));
    public static readonly LocalisationToken New = new StandardButtonToken("New", Guid.Parse("f72d365c-b18f-4f01-a6e4-b0cd930dc730"));
    public static readonly LocalisationToken More = new StandardButtonToken("More", Guid.Parse("bd4da7df-afd2-481e-b6b6-b4a989324758"));
    public static readonly LocalisationToken Delete = new StandardButtonToken("Delete", Guid.Parse("ab00ec14-4414-4cda-a8e2-4f03c9e7c5a8"));
    public static readonly LocalisationToken Add = new StandardButtonToken("Add", Guid.Parse("01e44600-a556-4a07-8a2a-e69a1ea79629"));
    public static readonly LocalisationToken Confirm = new StandardButtonToken("Confirm", Guid.Parse("4c50e91e-3e2f-42fa-97aa-9f1f6f077f09"));
    public static readonly LocalisationToken Send = new StandardButtonToken("Send", Guid.Parse("24121766-f424-4d73-ac58-76f90d58b95c"));
    public static readonly LocalisationToken Continue = new StandardButtonToken("Continue", Guid.Parse("dd2ca0e5-8a35-4128-b2e8-db68a64a6fe5"));
    public static readonly LocalisationToken OK = new StandardButtonToken("OK", Guid.Parse("9a359f93-7c23-44ad-b863-e53c5eadce90"));
    public static readonly LocalisationToken Accept = new StandardButtonToken("Accept", Guid.Parse("3206a76b-1cd7-4dc3-9fff-61dfb0992c75"));
    public static readonly LocalisationToken Reject = new StandardButtonToken("Reject", Guid.Parse("f99c6a9c-6a55-4f55-ac4b-9581e56d18d3"));
    public static readonly LocalisationToken RequestMoreInfo = new StandardButtonToken("Request more info", Guid.Parse("19f3d76b-dafa-47ae-8416-b7d61546b03d"));
    public static readonly LocalisationToken Cancel = new StandardButtonToken("Cancel", Guid.Parse("75617287-5418-466b-9373-cc36f8298859"));
    public static readonly LocalisationToken Publish = new StandardButtonToken("Publish", Guid.Parse("efd87fd4-e7f1-4071-9d26-a622320c366b"));
    public static readonly LocalisationToken Remove = new StandardButtonToken("Remove", Guid.Parse("f7db5d81-5af8-42bf-990f-778df609948e"));
}

Everytime we create a page we make sure the buttons use these Tokens instead of manually writing the text. So if we decide we need a new button we will add a new token in the file below and when the site is run for the first time it will check if it exists in the database and if not it will be created.

So when it comes to the translating we will send these tokens off to the translators and they will change the text only. This will then be added into the site in the relevant language and the page will call the correct translation dependant on the language selected.

Problem/Question

Our translation tokens have the default text as strings, but I'm concerned that the server has to load all of these text strings into memory at start up. They're actually only ever used to store the translation in the db and never otherwise used in code, so I believe it might be a bit wasteful. Instead I believe we could call these translations separately when required, perhaps from some kind of look-up table that's not in-memory.

So the question is. Is the way we are currently doing this going to cause performance issues?

If so can anyone suggest any better solutions?

In total there are 1000's of these tokens in our site.

Google has not been very helpful to me on this occasion so any advice would be much appreciated. I have tried as hard as i can to word this so that it makes sense. Its not an easy one to explain.

Thanks in advance for any help people can provide.

like image 751
Gaz Winter Avatar asked Jul 12 '12 10:07

Gaz Winter


2 Answers

I'm currently working with a team on a project in which we had a similar situation. Our project is a client/server based application. The database with our translations rests on the server and all our controls have default English values. Originally when any new window was opened we read the database and pulled any necessary translations down and translated the controls. This way only the values we needed translated where in memory and only as long as that window needed them. When the window was closed the memory would be reclaimed using garbage collection.

What we discovered was even with all the translations for every button, label, column header, etc... for the entire system was loaded into memory we where only dealing with a couple hundred K. In the end what we did was:

  1. the user logs on:
    • if they default to another language besides English a data table is set up in memory and populated with the translations from all user controls in our system from the server.
    • This data table is given a primary key to help improve queries against it. As long as the app is open this data table exists.
    • Any time a user control is instantiated a method runs that looks up the translation and applies it.

The time it took to log in the user did increase but only by a few milliseconds on average.

Having said all this I wonder if you could use a similar design. This idea would keep the server from having to track translations per session. It would just feed the page to the user.

  1. User logs in:
    • a datatable object is populated with all the translations for the site
    • WriteXML() is called
    • the resulting XML is sent to the client
  2. When the user navigates to a new page:
    • a client side script is called that uses the XML to translate the page on the client machine.

You could add some caching so that the XML is only replaced when your site is updated or you could just have each user download the XML every time at log on. Either way it takes the load off of the server.

like image 111
Chris Avatar answered Sep 19 '22 16:09

Chris


Ignoring other implementations and focusing on the setup you're using, the answer is "yes" and "no".

Yes, there can be performance issues with the method you're following if the number of incoming requests grows and especially as the number of tokens increases. This relationship can be easily explained as "the more requests that come in, the more work the server has to do. the more tokens that exist, the more work the server has to do. If both requests and tokens increase, you're exploding the amount of work the server has to do."

The "no" could be accomplished by adding on to your current solution. You can add a cache to your setup that will save translated pages so that the server would not need to query the database or translate each page per-request. For instance, if you have one page mypage.aspx that contains 20 translatable tokens - let the server translate it the first time and then save the translated file as, say, /localized/mypage.EN.html and all future requests (if the original page hasn't been modified or new tokens haven't been added) will just be sent the cached page instead of re-translating each time.

Additionally, you could have the server generate all translations when the page is updated or tokens are updated instead of waiting for a client-request to come in.

like image 38
newfurniturey Avatar answered Sep 21 '22 16:09

newfurniturey