gRPC code-first pro Blazor WebAssembly front-end

gRPC je fenomén dnešní doby. Moderní a výkonově efektivní protokol se rychle rozšiřuje a my si dnes ukážeme, jak ho použít pro komunikaci mez Blazor WebAssembly front-endem a ASP.NET Core backendem (hostem):

  1. Efektivně využijeme možnosti sdílení kódu mezi serverovou a klientskou částí. Použijeme uspořádání code-first a „contract“ (interface pro volanou službu a definice datových objektů) dáme do assembly sdílené serverovou i klientskou částí solution.
  2. Pro překonání omezení browserů použijeme gRPC-Web rozšíření.

Celou implementaci si ukážeme na jednoduché příkladu – použijeme výchozí šablonu Blazor WebAssembly App z Visual Studia (ASP.NET Core hosted, verze šablony .NET7) a připravenou ukázku Fetch data, která v této šabloně používá REST API, předěláme na gRPC-Web volání s použitím code-first.

Pojďme na to, bude to jen pár kroků:

1. MyBlazorSolution.Server – Příprava ASP.NET Core host

Nejprve si na straně serveru připravíme infrastrukturu pro gRPC. Půjdeme rovnou do varianty s rozšířením gRPC-Web s code-first podporou a nainstalujeme NuGet balíčky

Zaregistrujeme podpůrné služby do dependency-injection ve Startup.cs:

builder.Services.AddCodeFirstGrpc(config => { config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal; });

Přidáme gRPC middleware někam mezi UseRouting() a definici end-pointů (před MapXy() metody):

app.UseGrpcWeb(new GrpcWebOptions() { DefaultEnabled = true });

2. MyBlazorSolution.Shared – Definice contractu služeb (code-first)

Nyní v podobě interface definujeme, jak bude naše služba vypadat. Interface následně využijeme jak na straně serveru (vytvoříme jeho implementaci), tak na straně klienta (necháme si vygenerovat gRPC-klienta, který bude interface implementovat a my ho v našem kódu budeme přímo využívat prostřednictvím dependency injection).

Přidejte do projektu NuGet balíček, který nám umožní interface dekorovat potřebnými atributy

Najděte si ukázkový soubor WeatherForecast.cs z šablony projekty. Obsahuje definici návratové datové zprávy, kterou nám nyní vrací ukázkové REST API. Tuto třídu předěláme do následující podoby:

[DataContract]
public class WeatherForecast
{
	[DataMember(Order = 1)]
	public DateTime Date { get; set; }

	[DataMember(Order = 2)]
	public int TemperatureC { get; set; }

	[DataMember(Order = 3)]
	public string? Summary { get; set; }

	public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
  • Přidali jsme atribut DataContract pro označení třídy, kterou budeme používat jako datovou zprávu gRPC.
  • Přidali jsme atributy DataMember, kterými jsme označili prvky, které se mají přes gRPC přenášet (ostatní se ignorují, zde TemperatureF je počítané a dopočítá se nám z ostatních údajů na klientovi kdykoliv znovu). Každému prvku je potřeba nastavit Order, kterým se definuje pevný layout pro používanou protobuf serializaci.
  • Původní typ DateOnly jsme vyměnili za DateTime. Musíme se držet typů podporovaných použitou protobuf serializací.

Dále potřebujeme vytvořit interface, který bude celou službu popisovat:

[ServiceContract]
public interface IWeatherForecastFacade
{
	Task<List<WeatherForecast>> GetForecastAsync(CancellationToken cancellationToken = default);
}
  • Atribut [ServiceContract] nám označuje použitelnost pro gRPC (lze později využít i pro automatické registrace).
  • Z podstaty síťové komunikace by měl být celý interface asynchronní.
  • Můžeme použít volitelný CancellationToken, který nám může zprostředkovat signál o předčasném ukončení komunikace klientem (nebo přerušení spojení).

3. MyBlazorSolution.Server – Implementace a publikování služby

Nyní zbývá připravený interface implementovat na straně serveru (použijeme lehce modifikovaný kód z ukázkového WeatherForecastController, který můžete nyní smazat):

public class WeatherForecastFacade : IWeatherForecastFacade
{
	private static readonly string[] Summaries = new[]
	{
		"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
	};

	public Task<List<WeatherForecast>> GetForecastAsync(CancellationToken cancellationToken = default)
	{
		return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
		{
			Date = DateTime.Today.AddDays(index),
			TemperatureC = Random.Shared.Next(-20, 55),
			Summary = Summaries[Random.Shared.Next(Summaries.Length)]
		})
		.ToList());
	}
}

Připravenou službu vypublikujeme skrze Startup.cs:

app.MapGrpcService<WeatherForecastFacade>();

MyBlazorSolution.Client – konzumace gRPC služby

Nyní už zbývá jen službu použít v Blazor WebAssembly front-endu. Celou definici máme k dispozici v podobě IWeatherForecastFacade interface s jeho WeatherForecast datovou třídou.

Do projektu přidáme potřebné NuGet balíčky:

V Program.cs zaregistrujeme gRPC-Web infrastrukturu a klienta (ve factory podobě):

builder.Services.AddTransient<GrpcWebHandler>(provider => new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));

builder.Services.AddCodeFirstGrpcClient<IWeatherForecastFacade>((provider, options) =>
	{
		var navigationManager = provider.GetRequiredService<NavigationManager>();
		var backendUrl = navigationManager.BaseUri;

		options.Address = new Uri(backendUrl);
	})
	.ConfigurePrimaryHttpMessageHandler<GrpcWebHandler>();

No a nyní již můžeme IWeatherForecastFacade ve front-endovém projektu kdekoliv použít tak, že si necháme službu nainjectovat pomocí dependency injection. Například tedy upravíme FetchData.razor, aby používalo naší novou gRPC službu namísto původního REST API:

@inject IWeatherForecastFacade WeatherForecastFacade

...

@code {
	private List<WeatherForecast>? forecasts;

	protected override async Task OnInitializedAsync()
	{
		forecasts = await WeatherForecastFacade.GetForecastAsync();
	}
}

Hotovo. Projekt by měl být nyní spustitelný a stránka Fetch data bude nyní komunikovat prostřednictvím gRPC-Web.

Svoje řešení si můžete ověřit vůči vzorové repository

Další rozšíření a pokročilejší techniky

gRPC služba může samozřejmě přijímat i vstup. V takovém případě použijte jeden vstupní parametr pro příchozí zprávu – datovou třídu vytvořenou stejně jako jsme připravili výstupní WeatherForecast. Obvykle se tyto třídy označují jako Data Transfer Object a dostávají tak suffix Dto. Implementace je obvykle jako C# record.

Pokud máme v našem projektu authentizaci a authorizaci, pak můžeme na implementující třídě/metodě použít atribut [Authorize], stejně jako bychom ho použili na controlleru/action.

Na publikovaný gRPC endpoint můžeme aplikovat libovolné techniky jako na jakýkoliv jiný namapovaný serverový endpoint (rate limiting, caching, …).

gRPC má v sobě podporu interceptorů jejichž prostřednictvím můžeme gRPC komunikaci dále vylepšovat

  • předávat si ze serveru na klienta výjimky (základní podpora je vestavěna, ale může se vám hodit ji obohatit o specifický handling vlastních scénářů),
  • předávat si z klienta na server požadovanou culture (do jakého jazyka je front-end přepnut),

V pokročilejší variantě uspořádání můžete zajistit i automatickou registraci interface a datových contractů, aniž byste je museli dekorovat atributy [ServiceContract], [DataContract] a [DataMember(Order = ...)]. Vše toto a mnohé další najdete připravené v:

Obojí open-source s MIT licencí, zdarma.

Azure OpenAI chat (Global Azure Keynote) – záznam a demo [Robert Haken, Global Azure Praha 05/2023]

V pátek 12. května jsme společně s Davidem Gešvindrem (WUG) a Tomášem Hercegem (Update Conference) pořádali v pražském Microsoftu lokální běh celosvětové konference Global Azure.

Záznam z keynote, kde jsem v podstatě celou dobu mluvil o Azure OpenAI a vytváření chatbota v ChatGPT.

Chatbota si můžete vyzkoušet na chat.havit.cz.

Demo samotné najdete tradičně na GitHub: github.com/havit/HavitOpenAIChatPOC

Pokud máte zájem o něco podobného, ať už od nás naprogramovat, nebo jako pomoc vašemu IT týmu, ozvěte se nám havit.cz/kontakty.

Blazor WASM: Nepodporované připojení k AAD pomocí standardní auth-knihovny (Microsoft.AspNetCore.Components.WebAssembly.Authentication)

Pokud jste si (podobně jako já) slibovali, že „snadno“ vytvoříte Blazor aplikaci, která bude napojitelná na obecného OIDC identity-providera pomocí knihovny Microsoft.AspNetCore.Components.WebAssembly.Authentication, přičemž budete zároveň touto cestou podporovat i napojení na Azure Active Directory (AAD), zklamu vás.

Myšlenka je jednoduchá, AAD přeci podporuje OIDC a tedy nyní důvod, proč by obecný OIDC klient neměl jít připojit i na AAD. Bohužel překážek je více, než byste chtěli překonávat.

Knihovna Microsoft.Authentication.WebAssembly.Msal, která je pro AAD určená, je sice nadstavbou základní Microsoft.AspNetCore.Components.WebAssembly.Authentication knihovny, dělá toho však o dost více, než jenom boilerplate konfiguraci podkladového obecného OIDC.

Základní rozdíl můžete najít například v „interop“ části s podkladovým JavaScriptovým modulem oidc-client.

  • AuthenticationService.ts v Microsoft.AspNetCore.Components.WebAssembly.Authentication,
  • AuthenticationService.ts v Microsoft.Authentication.WebAssembly.Msal.

Projevuje se to například při vyzvedávání access-tokenů. MSAL verze „fixuje“ specifikum AAD, které při dotazech na token endpoint ne vždy vrátí access-token se všemi požadovanými scopes (detaily jsou na širší diskuzi, ale např. nedostanete token, který by v sobě měl User.Read scope společně s custom-scope vašeho API, atp.).

Základní knihovna využívá „cachování“ tokenů v UserManageru oidc-client a spoléhá se na předpoklad: „Pokud token-endpoint vrátil access-token, pak tento token v sobě má všechny požadované scopes.“ (tedy si k získanému tokenu požadované scopes uloží a pak při dalším požadavku na stejné scopes vrací již získaný token).

„Fixovaná“ knihovna MSAL tento nedostatek podkladového oidc-client zná a ví, že tento sice tvrdí, že má token pro nějakou sadu scopes, ale access-token ve skutečnosti tyto scopes mít nemusí. Proto „vypíná“ na této úrovni cachování a získává token vždy znovu.

Základní Azure PaaS služby [Jiří Kanda, Vzdělávací okénko, 29.3.2023]

Záznam ze Vzdělávacího okénka HAVIT, kde Jirka Kanda ukazoval, jak v HAVITu používáme platformní služby Azure pro hosting aplikací.

Slides

Novinky v C# 11, [ASP].NET 7 a Blazor – záznam, slides a dema [Robert Haken, FreshIT Praha 2023]

Záznam z přednášky pro konferenci FreshIT Praha z 30. března 2023, kde jsem povídal o novinkách v platformě .NET v poslední verzi 7.

Dema

Slides

Havit.Blazor – založení projektu z šablony [Robert Haken, Vzdělávací okénko, 22.3.2023]

Záznam ze Vzdělávacího okénka HAVIT z 22.3.2023.
Povídal jsem o založení nového projektu (solution) z šablony https://github.com/havit/NewProjectTemplate-Blazor.

Podrobnosti o Havit.Blazor stacku viz záznam přednášky pro WUG Zlín.

Havit.Blazor stack podrobněji – záznam z WUG Zlín [Robert Haken, 28.2.2023]

Záznam z přednášky pro komunitní setkání WUG Zlín z 28. února 2023. Povídal jsem o uspořádání Havit.Blazor stacku (šablona https://github.com/havit/NewProjectTemplate-Blazor) a proč je uspořádaný, tak jak je.

Slides (PDF):

Havit.Blazor stack – záznam z WUG Days 2023.1

Záznam z přednášky pro konferenci WUG Days 2023.1 v Brně z 30. ledna 2023. Povídal jsem o uspořádání Havit.Blazor stacku (šablona https://github.com/havit/NewProjectTemplate-Blazor) a proč je uspořádaný, tak jak je.

Slides (PDF):

Týden s Lenovo ThinkPad Z16 Gen1

Po dvou týdnech z ThinkPad P16s a týdnu s ThinkPad P1 Gen5 jsem ke své velké radosti dostal možnost vyzkoušet i ThinkPad Z16. Modelová řada Z je úplně nová a charakterem (minimalistické hliníkové šasi, jen USB-C porty, high-end komponenty) nápadně připomíná notebooky Apple nebo Dell XPS.

Přiznám se, že i přes vynikající papírové parametry jsem byl k této novince nedůvěřivý a říkal jsem si, že úplně čerstvá modelová řada bude potřebovat jednu nebo dvě generace, než se vyladí všechny novorozenecké problémy. K mému velkému překvapení však musím uznat, že se jedná o kousek velmi povedený a velmi vážně uvažuji o jeho pořízení, byť jsem byl již rozhodnutý pro dříve testované P16s.

K vyzkoušení jsem dostal preprodukční model 21D5Z9ZVUS:

  • procesor AMD Ryzen 7 PRO 6850H (45W TDP)
  • 16GB RAM
  • 500GB SSD
  • bez dedikované grafické karty, pouze integrovaná AMD Radeon 680M
  • 16″ WUXGA (1920×1200) touch LCD (IPS), 16:10
  • (135W USB-C nabíjení, bez LTE)

První dojmy

Na první pohled se jedná o jiný druh ThinkPadu, který zarytého konzervativce může až vyděsit. Na druhou stranu musím na svém vlastním příkladu připustit, že nemít ten stroj označení ThinkPad, tak bych jej neměl nutkání ani zkoušet a řadil bych ho (neprávem) někam do kategorie IdeaPad (nebo tam někam, moc se v tom nevyznám, prostě B-tým Lenovo). Branding zde nepochybně sehrál svoji roli a přitáhl i moji pozornost.

Každopádně zapomeňte na klasické černé šasi ThinkPad s pogumovaným či jinak nekovovým povrchem. Zde se jedná o čistokrevný celokovový hliník (nikoliv však lesklý) v jeho klasické světle šedé barvě. Naopak po otevření je povrch černý a hladký (docela klouže, budete se zadrhávat jen o černé logo Lenovo pod pravým zápěstím), hrany až ostré.

První, čeho si u tohoto notebooku všimnete, je jeho velikost. První zkoušené P16s mi přišlo větší, než bych čekal, následné P1 Gen5 mi přišlo „asi tak, jak bych čekal“ a Z16 je prostě ještě o další kus subtilnější než P1 a v tomto ohledu „lepší, než bych čekal“. Rámeček okolo 16″ displeje (16:10) je minimální (za cenu hrbu pro kamery a mikrofony), tloušťka je ještě o trochu menší a celé je to najednou takové „tak akorát – super velikost“.

Volba materiálu šasi, kapacity baterie 72 Wh (oproti 52.5 Wh v P16s a 90 Wh v P1) a touch displeje bohužel předurčuje hmotnost 1.9kg. Stroji by samozřejmě mnohem více slušelo číslo někde kolem 1.5kg, ale ve srovnání s 1.8kg u P16s i P1 to není zase takový rozdíl.

Druhá věc, které si ihned po zapnutí všimnete, je zřetelně horší display. Po letech se špičkovými high-res displeji v X1 Carbon a T14 mně najednou „obyčejné“ 1920×1200 „zaslepené“ dotykovou vrstvou praštilo do očí. Naštěstí se však Z16 dodává (kromě další non-touch varianty 1920×1200) i s ultimátním OLED 3840×2400 displejem (s OGS touch), což ani jeden z „konkurentů“ P16s/P1 nenabízí, resp. P1 se s 4K rozlišením dělá v IPS provedení. (Rozhodně nelze předpokládat, že by high-res displeje P16s/P1byly horší, ostatně P-řada se pyšní tovární kalibrací barev a jde o špičkové zobrazovací jednotky pro kreativní práci – OLED má však svůj „zvuk“ a předpokládám, že nikoho nezklame.)

Třetí věc, která mě překvapila (tentokrát velmi příjemně), je thermal management. Velmi mi záleží na tichém provozu a po týdnu s P1 Gen5 a „ohořelými chodníky + ohluchlými chodci“, jsem čekal kvůli TDP 45W i zde podobný zážitek. Ano, AMD Ryzen 6850H má papírové TDP 45W stejné jako Intel i9-12900H v P1 Gen5 a ani náhodou jsem nedoufal, že by relativně málo perforované hliníkové šasi (ve srovnání s P-modely) dávalo prostor pro nějaký kultivovaný zvukový projev chlazení (obzvláště, pokud jsme teprve u první generace této řady), leda by to bylo vykoupeno vysokými teplotami a throttlingem výkonu. Opak je pravdou (!) – chlazení za běžného provozu téměř neslyšíte – přestože na AC napájení ventilátory nikdy nevypínají, notebook si jen lehounce šustí a do žádných vyšších teplot se nevydává. Při provozu na baterii se ventilátory i vypnou, pod zátěží naopak otáček přidává (stále však spíše výjimečně a velmi kultivovaně).

Samozřejmě mě hned napadlo, že to bude draze vykoupeno redukovaným výkonem a tak jsem sáhl po Passmark benchmarku, abych si udělal nějakou základní představu:

Procesorový výkon sice ani zdaleka nedosahuje hodnot P1 Gen5 s Intel i9-12000H (tam bylo CPU score ~31500), ale i tak se jedná o velmi příjemný výsledek a celkové naladění stroje je posazeno o trochu výše než P16s (ten byl osazen AMD Ryzen 6850U s 28W TDP).

Celkově mě překvapilo chování procesoru 6850H s papírovými 45W TDP ve srovnání s 6850U a jeho 28W TDP. Kromě TDP a frekvencí se mi nepodařilo najít parametry, v kterých by se tyto dva procesory lišily, přičemž H-verze zdaleka nevypadá, že by se snažila notebook „uvařit“ nějak zřetelně více než U-verze, kterou jsem měl v testovaném P16s. Rozdíl v naměřeném výkonu je téměř zanedbatelný (CPU score 25111 vs 23603) a spíše bude rozdíl v celkovém naladění modelových řad notebooků (firmware), kdy ThinkPad P16s jako workstation se snaží z procesoru vymáčknout maximum (o P1 Gen5 raději ani nemluvím, to je úplně jiná formule). ThinkPad Z16 naopak vypadá, že ochotně „boostuje“ (nárazové výkonové požadavky), ale jinak jde víceméně o stejnou výkonovou hladinu jako 6850U. Za bezmála dvojnásobnou cenu tak zde hledejte jiné výhody než výrazně vyšší výpočetní výkon (např. tišší provoz, subtilnější šasi).

Celkové dojmy po týdnu produkčního používání

Přeháněl bych, kdybych řekl, že jsem si Z16 po týdnu zamiloval, přesto se mi velmi líbí a kdyby Lenovo doladilo těchto pár parametrů, asi bych jim (nejenom já) za takový stroj „ruce utrhal“:

  • černý carbon místo hliníku + „měkčí“ provedení,
  • alespoň HDMI a 1x USB-A porty,
  • o půl kila méně (klidně s trochu menší baterií),
  • ideálně vrátit zpět klasickou ThinkPad chicklet klávesnici s vyšším zdvihem, PgUp/PgDown klávesami a původním rozložením Ctrl/Fn kláves i šipek, ale čekal jsem větší obtíže s adaptací,
  • (bez touch nebo když už, tak s Yoga překlopitelností pro využitelnost pera)

Vlastně to nejsou žádné zásadní nevýhody, ve skutečnosti má totiž Z16 spoustu kladů, pro mě pak zejména:

  • výborný thermal management s tichým chlazením a velmi mírnými teplotními projevy,
  • velmi slušný výkon pro vývoj (pokud nepotřebujete grafiku, je to ideální naladění),
  • subtilní šasi (menší než P16s i P1 Gen5),
  • velký a kvalitní 16″ display (OLED 3840×2400) – touch s možností využití Lenovo Pen,
  • USB-C docking i napájení (na 65W adaptér si to stěžuje, 90W tomu stačí, i když pro rychlé nabíjení se stroj dodává se 135W adaptérem),
  • solidní výdrž baterie (odhadem kolem 10-12 hodin pro cokoliv kromě Teams-meetingů),
  • klasická vycentrovaná klávesnice bez numerické části,
  • kvalitní high-end zpracování (+servis+záruka),
  • volitelný LTE modul (SIM),
  • slušné vybavení: fingerprint reader, IR camera for Windows Hello, SD reader.

Samozřejmě podstatnou podmínkou je i nabídka kombinace komponent, která naplňuje moje potřeby. Konkrétně v mém případě by to mohla být třeba varianta 21D4001LCK:

  • AMD Ryzen 7 PRO 6850H (8C / 16T, 3.2 / 4.7GHz, 4MB L2 / 16MB L3)
  • Integrated AMD Radeon 680M Graphics
  • 32GB Soldered LPDDR5-6400 (dual channel)
  • 1TB SSD M.2 2280 PCIe 4.0×4 Performance NVMe Opal 2.0
  • 16″ WQUXGA (3840×2400) OLED 400nits Anti-reflection / Anti-smudge, 100% DCI-P3, Dolby Vision, Touch
  • LTE: Quectel EM05-G, 4G LTE CAT4
  • FHD 1080p + IR Discrete with E-shutter
  • 3Y Premier Support

Závěrečné shrnutí a srovnání P16s / P1 Gen5 / Z16

Pohybujeme se zde v kategorii 16″ notebooků ThinkPad s displejem o poměru stran 16:10…

Pokud hledáte ultimátní ultra-mobilní stroj pro grafickou práci, jste ochotni výkonu obětovat vše (zejména pak zvukový/tepelný komfort a výdrž baterie) a máte k dispozici neomezený rozpočet, pak zvolte Lenovo ThinkPad P1 Gen5. Jděte do varianty s nějakou dedikovanou grafickou kartou odpovídající vašim potřebám a užívejte si formule, kterou jen tak někdo další nemá.

Pokud hledáte výkonný stroj, který nějakou tu grafickou úlohu také zvládne, ale rozpočtově se potřebujete pohybovat někde kolem 40 000 Kč + DPH, pak zvolte Lenovo ThinkPad P16s. Pokud preferujete výdrž baterie a tišší provoz, pak rozhodně variantu AMD, pro vývojáře úplně ideální. Pokud naopak potřebujete přitopit více grafického výkonu, pak zřejmě poslouží varianta Intel s dedikovanou grafickou kartou (AMD verze se dělají jen s integrovanou grafikou).

Pokud jste ochotni dát dvojnásobek, někde kolem 80 000 Kč + DPH, nejde vám o workstation parametry (kalibraci barev, ISV certifikace atp.), netrváte na výbavě portů, ale chcete si naopak dopřát kompaktnější provedení, tišší provoz a možná i trochu více subjektivního výkonu pro vývoj, pak doporučuji Lenovo ThinkPad Z16 s OLED displejem (nebo IPS bez touch, pokud chcete ušetřit).

…já se v tuto chvíli nejspíš vydám cestou Z16. Nechte se překvapit a těšte se na pokračování příběhu.

PS: Nakonec jsem měl Z16 půjčené dva týdny a objednávám si ho v konfiguraci 21D4001LCK. P16s si nechávám v hledáčku pro další možnosti.

Týden s Lenovo ThinkPad P1 Gen5

Po více než dvou týdnech s Lenovo ThinkPad P16s AMD Gen1 jsem měl možnost vyzkoušet Lenovo ThinkPad P1 Gen5, konkrétně preprodukční konfiguraci 21DDZA2PUS. ThinkPad P1 jsou workstation-verzí od ThinkPad X1 Extreme, což je větší bratříček od vlajkové lodi X1 Carbon. Pokud pomineme speciální stroje, pohybujeme se zde na úplném vrcholu nabídky Lenovo.

Zapůjčený stroj byl osazen

  • CPU Intel i9-12900H
  • 64 GB RAM (2x 32MB)
  • 4 TB SSD
  • bez dedikované grafické karty, pouze integrovaná grafika Intel Iris Xe

Cílem bylo přímé srovnání s P16s, tedy dojít k závěru, který z obou strojů je pro mě ten pravý. Připomínám své hlavní závěry k P16s, budu zde totiž popisovat hlavně rozdíly:

  • P16s jde krásně za výkonem, procesor AMD Ryzen 7 PRO 6850U s TDP 28W je žravější nástupce 5850U (15W TDP) a celkově je to bohužel znát na thermal-managementu (zřetelně hlučnější chlazení než můj stávající T14 AMD Gen2),
  • P16s je trochu macek; ne úplně obr, ale trochu subtilnější provedení by si zasloužil,
  • P16s má numerickou klávesnici a zaplatil za to drobným zmenšením základní klávesnice,
  • P16s má pohodlný velký 16″ display, který mi velmi vyhovuje.

První dojmy z P1 Gen5 (den 1)

Ihned po vyndání z krabice je zřejmé, že se jedná o kousek vyšší kvalitativní řady než P16s

  • stroj je malinko subtilnější (ve srovnání s X1 Carbon je to pořád obr, ale řekněme, že takovou nějakou velikost bych čekal od P16s při mém přechodu z T14/P14s),
  • touch-pad je příjemnější na omak a je precizně spasován (na P16s mi přišlo, že měl trochu tendenci drnčet, i když jsem na starších ThinkPadech zažil určitě horší),
  • stroj nemá numerickou část klávesnice a základní část je tak nezmenšená (zůstal menší zdvih než předchozí ultimátní Lenovo chicklet klávesnice, rozložení ale sedí a spíše jsem si musel zvyknout na novou vzdálenost kláves od hrany šasi, než že by byl problémem zdvih; klávesnice je naopak trochu tišší, prý jsou klávesy podloženy molitanem),
  • zapůjčený model, přestože nemá dGPU, byl osazen dvěma chladiči, to se může ukázat jako výhoda i nevýhoda, uvidíme později,
  • P16s má vývod chlazení do pravé strany, P1 má mřížku na celé zadní straně (jak účinnost chlazení ovlivňuje fakt, že při otevřeném notebooku se před zadní stranu do dráhy proudícímu vzduchu postaví víko, to si netroufám odhadovat),

Hned první test PassMark ukázal score 4310, tedy o řádný kus níže než P16s s procesorem AMD (~5900). Nenechte se však zmýlit, celé score je shozeno dolů velmi slabou grafickou částí Intel Iris Xe, výkon zbytku je naopak brutální:

  • CPU Mark ~31500 vs. ~23600 (+33%)
  • 2D Graphics Mark ~400 vs. ~800 (-50%)
  • 3D Graphics Mark ~3430 vs. ~5800 (-41%)
  • Memory Mark ~3440 vs ~2260 (+52%)
  • Disk Mark ~31100 vs ~22050 (+41%)

Poznámka: Stroj bez dGPU bylo moje specifické přání, drtivá většina P1 se naopak dodává s dedikovanou grafickou kartou a na výběr je jich hned několik. Já pro vývoj grafický výkon nepotřebuji, a tak hledám konfiguraci, která nebude přidávat další TDP do už tak napnutého thermal-managementu.

Po týdnu používání

I na P1 Gen5 jsem nakonec nainstaloval své pracovní nástroje a používal ho týden pro produkční workload.

Oproti P16s je opravdu příjemně subtilnější, klasické rozložení klávesnice je taky snazší na adaptaci, celý týden jsem však prakticky neřešil nic jiného, než jestli se mi podaří nějak zkrotit chlazení. Postupně jsem naznal, že je to marný boj, a že opravdu sedím u stroje jiné kategorie, pro jinou cílovou skupinu, než jsem já.

U P1 je evidentně vše podřízeno maximálnímu výkonu a o jakékoliv kompromisy se to nepokouší:

  • Procesor Intel i9-12900H je prostě o level jinde. Se svými 45W TDP dokáže stroj kontinuálně zahřívat tak, že se P1 o režim „bez roztočeného ventilátoru“ ani nepokouší. Ventilátory to jsou navíc dva a chlazení tak o sobě prostě dává vědět. Jak by to probíhalo s dedikovanou grafickou kartou si netroufám ani odhadovat. Stejně tak si netroufám doufat, že by stav byl nějak výrazně jiný s přízemnějšími procesory i7-12800H nebo i7-12700H, které by pro mě připadaly v úvahu. Oba mají stejné TDP 45W a nečekám tak výrazný rozdíl.
  • Překvapilo mě, že P1, přestože je osazen velkou 90Wh baterií, vydržel na klíně jen kolem 2-2,5 hod (a to jsem si jen v browseru hledal letenky). Původně jsem to interpretoval jako nekorektní stav a hledal chybu v nastavení/firmware/ovladačích, postupně jsem však na netu našel zkušenosti jiných uživatelů a došlo mi, že to tak prostě je.
  • Podobně mě překvapilo, když jsem každé ráno nacházel na stole rozpálený stroj, který přes noc spal v režimu Modern Standby (S0). Ventilátory nejely, ale produkce tepla zůstala úctyhodná.
  • Stále je potřeba mít na paměti, že zapůjčený kus je preprodukčním modelem. U těch bývá thermal-management obecně problematičtější a u produkčních kusů lze očekávat trochu umírněnější projev. Stejně tak je obvyklé, že u nových modelů i několik měsíců trvá, než si to celé sedne a chlazení najde své optimum (ať už skrze updaty driverů/firmware nebo skrze Intel Dynamic Tuning Technology, která se snaží pomocí AI/ML najít naladění pro každý stroj).

Celkově jsem došel k závěru, že P1 Gen 5 není pro mě. Je to maximalista ve výkonu a musíte být připraveni za takový výkon zaplatit obětováním zvukového komfortu, přijetím značných tepelných projevů a oželením výdrže baterie.

P1 je to taková formule. Řve to, šlehají z toho plameny, výkonu na rozdávání, porazíte každého rozdílem třídy. Já jsem se rozhodl, že mi bude více sedět obyčejný sporťák v podobě P16s, většinu soupeřů porazí taky, ale dá se s tím jezdit i ve městě, aniž byste za sebou nechávali ohořelé chodníky a ohluchlé chodce.

PS: K mému velkému potěšení jsem dostal možnost vyzkoušet ještě úplně nový model ThinkPad Z16 AMD. Můžete se tedy těšit ještě na třetí pokračování mé výběrové anabáze.