Оптимизируйте рисование TWebBrowser, чтобы уменьшить общую загрузку процессора

У меня есть форма, которая имеет TWebBrower компонент, который загружает документ HTML. Данные в документе HTML обновляются каждые несколько секунд, иногда несколько раз каждую секунду, и я обновляю значение в Delphi, используя:

DOMDocument.getElementById(elementID).innerHTML := someValue;

Проблема в том, что я хочу заблокировать окно / веб-браузер, чтобы предотвратить его рисование / обновление, пока все мои обновления не будут завершены. Есть какой-либо способ сделать это? Был бы звонок

SendMessage(WebBrowser.Handle,WM_SETREDRAW,0,0);

Мне нужна помощь в оптимизации этого кода, чтобы общее использование процессора не было постоянно высоким.

2 ответа

Решение

Поскольку ваша основная проблема - частота обновления, вам нужно уменьшить ее. Для этого вы можете просто сохранить последний раз, когда вы обновляли документ HTML, и при следующем изменении данных проверить, истек ли определенный период с того времени.

Вот код, который показывает, как это сделать. FUpdatePeriod в следующем примере указан период обновления в миллисекундах. Тогда, если вы позвоните UpdateChanges периодически innerHTML (псевдокод здесь) будет обновляться только по истечении не менее 1000 мс с момента его последнего изменения.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MSHTML, OleCtrls, SHDocVw;

type
  TForm1 = class(TForm)
    WebBrowser1: TWebBrowser;
    procedure FormCreate(Sender: TObject);
  private
    FLastUpdate: Cardinal;
    FUpdatePeriod: Cardinal;
    procedure UpdateChanges(const AData: WideString);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FUpdatePeriod := 1000;
end;

procedure TForm1.UpdateChanges(const AData: WideString);
begin
  if (GetTickCount - FLastUpdate > FUpdatePeriod) then
  begin
    (WebBrowser1.Document as IHTMLDocument2).body.innerHTML := AData;
    FLastUpdate := GetTickCount;
  end;
end;

// now remains to call the UpdateChanges periodically

end.

Это боковой ответ; Но когда у нас возникли проблемы с мерцанием в TWebBrowser, мы устранили их, переключившись на использование Google Chrome (DCEF), встроенного в наше приложение.

Хотя я тоже изначально чувствовал, что могу "оптимизировать" TWebBrowser и уменьшить его мерцание, я обнаружил, что проблема только в Internet Explorer. Помимо установки новой версии Internet Explorer или переписывания всего JavaScript, чтобы ваша веб-страница никогда не мерцала, поскольку в макете HTML нет активных элементов (100% javascript free = нет мерцания), единственное исправление - это прекращение использования Internet Explorer. и, таким образом, прекратить использование TWebbrowser.

Во-вторых, мерцание также может быть вызвано, если ваша веб-страница TWebBrowser обращается к нативным методам Delphi в качестве обратных вызовов из javascript. Эти обратные вызовы, если они занимают много времени, также всегда будут вызывать мерцание во встроенном TWebBrowser, даже если единственный выполняемый javascript - это вызов обратного вызова delphi. Техника, о которой я говорю (обратные вызовы), описана здесь.

Другие вопросы по тегам