Sharepoint - SharePoint 2013 CSOM: Is it better to pass a Context object around or a Url?

Do:

  • Pass around ClientContext.
  • Call .ExecuteQuery() as few times as possible, bundle/batch up with .Load().
    • Once is usually enough, only in a very few cases do you need more.

Do not:

  • Do not pass around Web.
    • You need to reference other members from ClientContext, such as Site.
  • Do not pass around an URL (either as String or Uri).
    • Initialization method of ClientContext can alternate, e.g., provider hosted apps use this: SharePointContextProvider.Current.GetSharePointContext(HttpContext).CreateUserC‌​lientContextForSPHost().

Also:
I usually make "Repository" classes, which work on ClientContext without actually calling .ExecuteQuery(), so I bundle up (batch) .Load commands and fire them on the "outside", then come back to the Repository.

public class ListAndViewRepository
{
    private readonly ListCollection _lists;
    public List<List> Lists { get; set; }
    public List<View> Views { get; set; }

    public ListAndViewRepository(ClientContext clientContext)
    {
        _lists = clientContext.Web.Lists;
        clientContext.Load(_lists,
            collection =>
                collection.Include(l => l.Id, l => l.Title,
                    l => l.Views.Include(v => v.Id, v => v.Title, v => v.ViewFields, v => v.ViewQuery)));
    }

    public void Execute()
    {
        Lists = _lists.ToList();
        Views = Lists.SelectMany(list => list.Views.ToList()).ToList();
    }
}

Used something like this:

var listAndViewRepository = new ListAndViewRepository(clientContext);
// ... do a lot of other "repositories"
clientContext.ExecuteQuery();
// ... call "Execute" on other "repositories"
listAndViewRepository .Execute();
var lists = listAndViewRepository.Lists;
var views = listAndViewRepository.Views; 

Objects like Web, ClientContext are passed by reference, that is they are not copied. So there is no need to worry about performance. However, as mentioned by @eirikb, pasing ClientContext between methods make more sense as you can then load whatever objects you want from it inside the method.