<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های محمد واحدی</title><link>https://virgool.ir/feed/@vahedi.ce</link><description>برنامه نویس معمولی</description><language>fa</language><pubDate>2026-11-12 00:23:26</pubDate><image><url>https://files.virgool.ir/upload/users/20178/avatar/BmuUvS.png</url><title>محمد واحدی</title><link>https://virgool.ir/@vahedi.ce</link></image><item><title>مفهوم Reactive Programming به زبان ساده</title><link>https://virgool.ir/@vahedi.ce/reactive-z0dycjew5j7m</link><description>مقدمهاز روزی که به شرکت بله و تیم شهریار پیوستم متوجه شدم که یکی از ابزارهایی که باید کار کنم RXJS هست و به نوعی باید Reactive کد بزنم! از اونجایی که من عاشق یادگیری چیزهای جدیدم و کنجکاوی خاصی دارم تا بتونم زیر و بم همه چیز رو در بیارم و در این مورد اتفاقا وسواس هم دارم خواستم اول بدونم Reactive کد زدن یعنی چی؟ اما بعد از سرچ های متوالی و گشت و گذار در سایت های مختلف متوجه شدم که این مفهوم رو خیلی سخت توضیح دادن و یا حداقل برای من درک کردنش یکم سخت بود برای همین تصمیم گرفتم این مطلب رو بنویسم و خیلی کوتاه و ساده در مورد Reactive Programming صحبت کنم.برو بریم! آشنایی اولیهمفهوم Reactive Programming به معنای کدنویسی کردن توسط استریم هایی از داده ها به صورت ناهمزمان هست.جمله ی بالا احتمالا دارای عباراتی هست که برای اولین بار می خونید مثل : &#34; استریم هایی از داده ها &#34;شاید الان بگید این چه تعریف ساده ای بود دیگه بدتر گیجمون کردی ?خب پس برمیگردیم یکم عقب تر تا ابتدا با معماری message-driven آشنا بشیم اون موقع احتمالا فهمیدن جمله ی بالا خیلی ساده تر و راحت تر از الان بشه !معماری message-drivenهمه ی کارهایی که توی این دنیا انجام میدیم async هست !بیاید با یک مثال ادامه بدیم :فرض میکنیم شما میخواید قهوه خامه ای درست کنید. اما متوجه میشید که خامه و شکر ندارین.اینجا 2 تا سناریو پیش رو داریم !سناریوی اول: شما زیر کتری رو روشن می کنید و تا وقتی که قهوه داره دم می کشه سری به سوپرمارکت محل می زنید و خامه و شکر می خرید ، وقتی برگردید قهوه هم دم کشیده و خامه و شکر رو بهش اضافه می کنید و نوش جان می کنید و از زندگی لذت می برید ☕️سناریوی دوم:ابتدا به سوپرمارکت میرید و بعد از خرید خامه و شکر به خونه برمیگردید و تازه قهوه رو دم می کنید و هنگامی که زل زدید به کتری همزمان به بدهی هاتون فکر میکنید تا قهوه حاضر بشه و در آخر اگه از افسردگی جان سالم به در ببرید می تونید یه قهوه بخورید ?همونطوری که در دو سناریوی بالا دیدید معماری message-driven شما رو از مکان و زمان جدا می کنه!یک مرز async براتون ایجاد میکنه و می تونه event-driven باشه و یا actor-base (در مقاله های بعدی مفصل بهشون می پردازیم اما فقط بدونید در مدل event-driven ، این event های تولید شده تبدیل به یک جریان داده ی بی انتها میشن ( یعنی عمل streaming اتفاق میوفته ) و سرویس های نرم افزاری در راستای این جریان اطلاعات اقدام به Validation , Enrichment, Filtering, Processing … و حتی تولید رویداد های جدید می کنند.)مفهوم Event Driven Based Servicesمفهوم streamحالا وقتشه برگردیم و یک بار دیگه این بیسیک ترین تعریف reactive programming رو بخونیم :Reactive programming is programming with asynchronous data streams.توی این جمله احتمالا مبهم ترین قسمت همون data stream باشه ? ( خب طبیعتا داخل data stream هم دوباره مبهم ترین قسمت خود stream باشه ) !احتمالا اگر قبلا در مورد stream جست و جو کرده باشید به رایج ترین تعریف اون یعنی جمله ی زیر رسیدید:A stream is a sequence of ongoing events (state changes) ordered in time.یک محور زمان در نظر بگیرید. به مجموعه event ها ( اتفاقاتی که منجر به تغییر وضعیت میشن ) یِ متوالی و پشت سر هم میگن stream !اگه بخوام صرفا یه تصور ذهنی براتون ایجاد کنم می تونم بگم زندگی هر آدم از لحظه ی تولدش تا مرگ (complete ) بر محور زمان یک جور stream به حساب میاد !حالا بریم وارد دنیای برنامه نویسی بشیم و چند تا مثال واقعی تر هم از stream باهم ببینیم ?// a number that goes up by 1 every second&#xA;[0,1,2,3,4]&#xA;&#xA;// a sequence of x and y positions of mouse click events&#xA;[(12,34), (345,22), (1,993)]&#xA;&#xA;// a json representation of the whole form as the user enters data&#xA;[&#xA; { &#34;name&#34;: &#34;A&#34; },&#xA; { &#34;name&#34;: &#34;As&#34; },&#xA;{ &#34;name&#34;: &#34;Asi&#34; },&#xA;{ &#34;name&#34;: &#34;Asim&#34; }&#xA;]هر کدوم از این مثال هایی که زدم می تونن یه stream باشن ! در واقع stream هر چیزی می تونه باشه ! ?یعنی ما می تونیم stream ای از دیتا ، از کلیک موس ، از Network Request و ... داشته باشیم.حالا برگردیم سر بحث اصلی یعنی Reactive Programmingایده ی اصلی Reactive Programming پیرامون ساختن stream های متنوع و کنترل کردن اون ها توسط operation های متفاوت می چرخه ( حالا تعریف بهتر و ملموس تری شد نه؟?)این operation ها اغلب توابع pure functional ای هستند که توسط ابزارهایی برای Reactive کد زدن در اختیار شما قرار داده میشه!خب حالا که فهمیدیم Reactive Programming یعنی چی سوال مهم بعدی پیش میاد ❓چطوری Reactive فکر کنیم؟خب اگه شما اولین باره که reactive programming به چشمتون میخوره باید بگم که احتمالا تا قبل از این فقط Imperative کد می زدین ( یعنی همون شکل سنتی و دستوری سابق )حالا اگه میخواید پارادایم های برنامه نویسی رو بهتر بشناسید توصیه میکنم این لینک ? رو بخونید!خب برگردیم سر بحث اصلیمون ! چطوری وقتی تا حالا Imperative کد می زنیم ذهنیتمون رو تغییر بدیم و Reactive کد بزنیم؟با یک مثال شروع می کنیم ?تابع add رو در نظر بگیرید.مقدار c مستقیما به مجموع مقادیر A و B مربوطه ! و اگر این بین B تغییر کنه دوتا اتفاق پیش میاد :1- ما باید بفهمیم که B تغییر کرده !2- ما باید بفهمیم که تغییر کردنِ B روی تغییر کردنِ C هم تاثیر گذاره !خب در دنیای وب اپلیکیشن های امروزی این کار خیلی رایجه که دیتاها توسط کاربران به صورت لحظه ای و مداوم تغییر کنند. از طرفی اگر بخوایم به صورت Imperative متوجه این تغییر کردن ها بشیم به callback-hell می رسیم ? ( که خب این پروژه رو پیچیده و به مرور از دسترس خارج می کنه )خب ما در reactive programming قراره به همه چیز به چشم stream نگاه کنیم.پس A و B و C دیگه یک value نیستن بلکه یک stream محسوب میشن ?اینجا فانکشن add دقیقا همون operation مد نظر ماست که ارتباط و کنترل A , B و C رو به عهده میگیره!خب مفتخرم شما رو با شغل جدیدتون آشنا کنم ! شما لوله کش هستید ?این stream ها حکم لوله هایی رو دارند که شما تصمیم میگیرید کی و کجا بهم وصل بشن و نتیجه رو که همون آب باشه کجا و چجوری مشاهده کنیم ( تا بحث لوله کشی داغه بگم که شما همونطور که می تونید هم لوله ی آب داشته باشید هم تصفیه ی آب، اینجا هم می تونید چندین operation برای کنترل stream هاتون داشته باشید)خب حالا دیگه خیلی راحته و هر زمان که این stream ها آپدیت بشن نتیجه رو به صورت خودکار خواهیم دید ?این یک gif هست اگر نمی تونید ببینید اینجـا کلیک کنید.هر گردی گردو نیست !هر کسی که Reactive کد زد نمی تونه ادعا کنه که داره یک سیستم Reactive رو توسعه میده !این دو مفهوم باهم تفاوت زیادی دارند از جمله اینکه در یک سیستم Reactive ما پیرامون 4 تا مفهوم میچرخیم :که در مقاله ی بعدی مشخصه های یک سیستم Reactive رو با مثال و مرور تاریخ حوادث دنیای نرم افزار ادامه میدیم.امیدوارم از مقاله لذت برده باشید. سعی کردم کوتاه و مفید توضیح بدم! متاسفانه پیرامون این مطلب توضیحاتی در وب فارسی نیست و در وب انگلیسی هم اکثرا سیستماتیک بودن یک Reactive Application رو بررسی کردند و با تعاریف سخت باعث شدن که این توهم بوجود بیاد Reactive Programming یک مفهوم سخت و غیرقابل فهمه در حالی که اینطوری نیست ?اگه سوالی داشتید در نظر ها بپرسید جواب میدم ?دوست دارید ویدیوهای آموزشی Reactive Programming رو با آموزش RXJS استارت بزنیم؟ ?راه های ارتباطی با من :GMail | LinkedIn | Bale </description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Mon, 07 Dec 2020 22:08:03 +0330</pubDate></item><item><title>تنبل سازی بدون پکیج</title><link>https://virgool.ir/@vahedi.ce/تنبل-سازی-بدون-پکیج-y0d6qda6gr4x</link><description>? کاور رو حال میکنین؟ تنبل بودن بین وبسایت ها بر عکس ما آدمیزادها یه خاصیت مهم و با کلاس محسوب میشهچون باعث میشه زودتر لود بشن و توی گوگل هم اون بالا مالاها بشینن.مقدمهزبانِ سخن در این نوشتار کاملا محاوره ای بوده و قرار نیست ویرایش ادبی روش صورت بگیره پس پیشاپیش اگه زبان فارسی رو همیشه 20 می گرفتید ازتون عذرخواهی میکنم.حتما اصلاح Lazy Load تا بارگزاری تنبل رو مکرر در جاهای مختلف شنیدید.من قراره توی این مقاله با معرفی یک API و تشریح خلاصه ی اون به همراه یک مثال عملی در کتابخونه ی ری اکت بهتون نشون بدم که همیشه لازم نیست واسه این جنگولک بازیا پکیج به پروژتون اضافه کنید و احتمالا حجم باندلتون رو ببرید بالاپس تا پایان همراه من باشید ? اصلا LazyLoad چی چی هس عامو؟به طور کاملا خلاصه به عکس زیر نگاه کنید :اونایی که میگن کو نمونه؟ اینم نمونهخب همونطور که احتمالا ملاحظه می کنید ما اینجا 6 تا عکس داریم که تمایل نداریم بلافاصله لود بشناین تمایل نداشتن بخاطر اینه که این عکس ها باید توسط مرورگر دانلود بشن و بعد به عنوان ریسورس در مرحله ی painting به مرورگر اضافه بشن ( اگه نمیدونید painting چیه توصیه میکنم اول این مقاله ی من رو بخونید و بدونید مرورگر ها چطوری کار میکنند )گرچه شاید توی تعداد  6 عکس یا حتی 60 عکس هم اونقدر performance سایت شما تحت تاثیر قرار نگیرهاما فرض کنید تعداد بسیار زیادی عکس دارید مثل اینستاگرام وب :آیا بنظر شما منطقیه که همه ی تصاویر از ابتدا بهشون ریکوئست زده بشه و لود بشن؟ حتی وقتی توی viewport کاربر نیستن؟مطمئنا جواب شما نه! خواهد بود. اما خب راه حلتون چیه؟اگه راه حلتون Lazy Load کردن تصاویر با استفاده از attribute ای به نام loading در تگ img به صورت زیر هست باید عرض کنم که خیر ! این توسط همه ی مرورگر ها ساپورت نمیشه فعلا !&lt;img src=&#34;felan&#34; alt=&#34;bisan&#34; loading=&#34;lazy&#34; /&gt;راه حل بدون درد و خون ریزیمیخوام بهتون یه API معرفی کنم که با اون می تونید کارهای زیر رو انجام بدید :بارگزاری تنبل تصاویر وبسایتتونپیاده سازی infinity scrollتشخیص مشاهده ی کاربر از یک قسمت خاص از سایتتون ( درست مثل تبلیغات اینترنتی و کاری که یکتانت انجام میده )پیاده سازی انیمیشن بعضی المنت های صفحه تنها در صورتی که در دید کاربر قرار داده باشند.خب این اعجوبه ی جادوگر کسی نیست جز Intersection Observer APIhttps://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_APIبرای استفاده از این API لازمه که یک instance ازش بسازید و به constructor اون یک callback و یک option پاس بدیدزمانی که شرط های option شما pass بشه callback مورد نظر اجرا میشه و می تونید فرآیند های مدنظرتون رو انجام بدید ( تصویر رو لود کنید ، ریکوئست بزنید و...)let observer = new IntersectionObserver(callback, options);حالا محتوای option شما می تونه شامل یک object با مقادیر زیر باشه :let options = {&#xA;  // root: the target element in viewport&#xA;  // rootMargin: margin around the root&#xA;  // threshold: either a single number or an array of numbers which indicate at what &#xA;      percentage of the target&#39;s visibility the observer&#39;s callback should be executed.&#xA;}و به همین سادگی می تونید کاری که پکیج های زیادی انجام میدن رو خودتون بدون درد و خون ریزی انجام بدید ?توضیحش که راحته یه مثال عملی نشونمون بده بله از قدیم و ندیم گفتن تا وقتی یه چیزی رو تجربه نکنی درست یادش نمیگیری پس این شما و این هم یک مثال عملی در ری اکتاول پیشنهاد میکنم دمو رو ببینید تا دقیق تر متوجه بشید منظورم چیه و سپس به سراغ سورس کد برید :دمو :  https://mvahedii.github.io/lazy-images/سورس کد :   https://github.com/Mvahedii/lazy-imagesارتباط با من :LinkedIn | Gmail </description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Wed, 21 Oct 2020 19:30:38 +0330</pubDate></item><item><title>مرورگرها چطوری کار می کنند؟</title><link>https://virgool.ir/@vahedi.ce/مرورگرها-چطوری-کار-می-کنند-zgmjuznkkecl</link><description>مرورگرها چطوری کار می کنند؟مقدمهمرورگرها مهم ترین نقش رو در دنیای انتقال اطلاعات امروز ایفا می کنند و هرچقدر زمان بیشتری میگذره با پیشرفته تر شدن مرورگرها می تونن کارهایی رو انجام بدن که بیشتر به وجد بیایم ! امروز هم تصمیم گرفتم باهم از تاریخچه و چگونگی نمایش یک سایت در مرورگر ( بدون وابستگی به نوع مرورگر ) صحبت کنیم.خیلی خودمونی تصمیم گرفتم مطالبی رو بگم که توی وب فارسی در موردش کمتر کار شده باشه و دربرگیرنده ی مسائل پایه ای باشه. سعی می کنم که کوتاه تر، جذاب تر و با لحن صمیمی تری بنویسم تا خسته نشید.لیست مطالبی که قراره در این مقاله باهاش صحبت کنیم :معرفی معماری یک مرورگرمعرفی Rendering Engine مرورگرهای مختلفبررسی فرآیند DNS lookup بررسی کوتاه پروتکل HTTPآغاز یک سفر با Responseفرآیند Parsingفرآیند Rendering فرآیند Paintفرایند ترکیبخلاصه ی کوتاهچند نکتهو در انتها بگم این مقاله بالاخره باعث میشه که مباحث دانشگاه یکم به دردتون بخوره :ديمعرفی معماری یک مرورگربرای همه ی مرورگر ها می تونیم معماری زیر رو در نظر بگیریم :معماری مرورگرهامعرفی User Interface : خب این User Interface ها همون interaction هایی هستن که کاربر با مرورگر داره. به عنوان مثال دکمه ی back ، دکمه ی refresh ، آدرس بار و...معرفی Browser Engine : موتور هر مرورگر نقش واسطه ای میان موتور رندر و عملیات درخواستی کاربر رو داره. به عبارت دیگه وقتی کاربر روی دکمه ی refresh کلیک میکنه وظیفه ی Browser Engine شروع میشه و این عملیات رو برای موتور رندر قابل فهم میکنه تا عملیات refresh صورت بگیره.معرفی Rendering Engine : وظیفه ی این قسمت تولید Render Tree و سپس نمایش صفحه هست که در ادامه مفصل در موردش صحبت خواهیم کرد.معرفی Networking : این بخش همونطور که مشخص هست وظیفه ی ارتباط با شبکه و Network و همچنین فرآیند DNS Lookup رو بر عهده داره که باز هم در ادامه در موردش صحبت خواهیم کرد.معرفی Javascript Interpreter : این بخش نیز وظیفه ی Parse کردن کدهای جاوا اسکریپت برای مرورگر رو بر عهده داره.معرفی Ui Backend : دکمه های هر مرورگر در پنجره ی مربوط به خودش در هر سیستم عامل مختلفه و ظاهر متفاوتی داره همینطور نمایش یک input ساده در سیستم عامل مک تفاوت ظاهری بسیاری با نمایش همان input در سیستم عامل ویندوز داره و این دقیقا همان تعریف Ui Backend هست که با توجه به سیستم عامل کاربر قابل تعریف هست.معرفی Data persistence : بخش هایی مثل کوکی و Web Storage ها در این قسمت قرار دارند.معرفی Rendering Engine مرورگرهای مختلفخب مرورگر های مختلف Rendering Engine های مختلفی هم دارند که در زیر توفیق آشنایی باهاشون نصیبمون میشه.گوگل کروم : ابتدا از WebKit استفاده می کرد اما بعد ها تصمیم گرفت که از این موتور یک fork بگیره و موتور دلخواه خودش با نام Blink رو بسازه.موزیلا : از موتوری به نام Gecko استفاده می کنه.سافاری : از موتوری که توسط خود شرکت اپل توسعه داده میشه به نام WebKit استفاده می کنه.اوپرا : این مرورگر کلا Chrome Base هست.و اما Microsoft Edge : این مرورگر هم re build میشه روی Chromium و در نتیجه از موتور Blink استفاده می کنه.بررسی فرآیند DNS lookupتا حالا فکر کردید وقتی آدرس یک سایت رو می زنید چه عواملی اون پشت زحمت می کشند که سایت به شما نمایش داده بشه؟ از این قسمت به بعد قراره که این عوامل پشت صحنه رو معرفی کنیم و در نهایت از خانواده ی آقای رجبی هم تشکر کنیم.خب هر سایت یک شناسنامه داره و مرورگر ها مثل ما نمیفهمن که google.com یعنی چی ! چون از ضریب هوشی پایین تری برخوردار هستند فقط آدرس IP رو متوجه میشن. خب پس چی میشه که شما با وارد کردن google.com توی آدرس بار مرورگر به اون سایت دسترسی پیدا می کنید؟اینجا مرورگر شما یک مسیری رو طی می کنه که به ترتیب شامل مراحل زیره :1- اول دنبال آی پی آدرسی که شما وارد کردید در کش خودش می گرده2- اگر پیدا نکنه به آقای سیستم عامل میگه شما نمیدونی آی پی این آدرس چیه؟3- اگر اونم ندونه میره سراغ recursive resolver در سیستم عامل تا کش رو بررسی کنه و ببینه قبلا هیچ احد الناسی نخواسته بره این سایت؟ ( که این resolver رو میتونه ISP به شما بده و یا خودتون ست کنید و یا اپلیکیشن های دیگه ست کرده باشند )4- در صورتی که هنوز پیدا نکرده باشه چمدوناشو می بنده و میره سراغ root server تا به TLD برسه. در این جا باید بدونید که هر کدوم از دامنه ها ( com،net،org،ir و .. ) توسط Top Level Domain کنترل می شن که کلا 13 تا  Root Servers داریم و خب هدف از این قسمت اینه که بتونه TLD Server مدنظر خودش رو پیدا کنه تا به name server هاش دسترسی داشته باشه. ( اگه بخوام ساده تر بگم اینجا میره و دنبال TLD دامنه com می گرده )5- اینجا میره به TLD میگه شما google.com می شناسید؟ من رو root server فرستاده و اون هم با بررسی name server هاش متوجه میشه که فرضا یک ns1.google.com ثبت شده و خب این مقدار یک ip متناظر داره که همون آی پی name server گوگل هست و به مرورگر ما میده و میگه بفرمایید لطفا رسیدشم امضا کنید.6- مرورگر ما با اولین پرواز برمیگرده به خونه اش و حالا به اون IP مد نظر یک request می زنه.پ.ن : این داستان کوتاه یک برداشت آزاد از سایت howdns.works بود.بررسی کوتاه پروتکل HTTPخب HTTP یک کلاینت - سرور پروتکل هست. این به این معنیه که اصولا یک ریکوئست از طرف یک user agent ( که اغلب مرورگر هست ولی می تونه فقط مرورگر نباشه ( مثلا crawler باشه )) به سمت سرور ارسال میشه و سرور هم یک ریسپانس یا پاسخ به این درخواست می فرسته.زمانی که مرورگر ما آدرس IP سایت مورد نظر رو پیدا کرد توسط یک ارتباط TCP 3 way تلاش می کنه به سرور متصل بشه در این نوع ارتباط ابتدا لازمه که درستی و صحت ارتباط تایید بشه پس در 3 مرحله این اتفاق صورت می گیره ابتدا مرورگر یک درخواست SYNchronize  می فرسته و وقتی سرور این packet رو دریافت کرد به مبدا با استفاده از یک Synchronization Acknowledge Packet پاسخ میده و در نهایت از سمت مبدا Acknowledge Packet به سمت سرور ارسال میشه که میگه بسته ای که فرستادی رسید !حالا شما در فرآیند بالا مبدا رو مرورگر در نظر بگیرید و مقصد رو یک وب سرور که البته امروزه چون از پروتکل HTTPS استفاده میشه پس یک بخش دیگه اضافه میشه به این صورت که سرور سرتیفیکیت TLS خودش رو برای کلاینت می فرسته و کلاینت هم ابتدا توسط یک جفت Key عملیات احراز هویت رو انجام میده و پس از اون هم یک symmetrically key می سازند. ( بخاطر وجود همین یک فرآیند اضافه تر هست که میگن HTTPS از HTTP کندتر هست اما خب این کند بودن به اون میزانی نیست که شما احساسش کنید و همچنین مزایایی که داره خیلی بیشتر هست )آغاز یک سفر با Responseپس از برقراری یک اتصال بین کلاینت و سرور، از سمت سرور یک Response به سمت کلاینت ارسال میشه که یک سند مبتنی بر HTML هست. به زمانی که طول میکشه تا اولین دیتا برای ریکوئست اولیه ارسال بشه میگن Time To First Byte یا به صورت اختصار TTFB که این دیتا طی قانون 14kb ارسال میشه بدین صورت که ابتدا 14kb از سند ارسال میشه (1460 بایت) و سپس این میزان دو برابر میشه تا به پهنای باند کاربر برسه.فرآیند Parsing زمانی که مرورگر اولین بسته از دیتاها رو دریافت می کنه شروع می کنه به Parse کردن و این فرآیند به این معنیه که ما میخوایم DOM و CSSOM رو بسازیم تا به مراحل رندرینگ و Paint برسیم.فرآیند Parsingحالا به مباحث شیرین دانشگاهی می رسیم اگر رشتتون نرم افزار باشه و کامپایلر پاس کرده باشید می دونید که در علم کامپیوتر Parse کردن به معنای تقسیم عبارات ورودی را به بخش هاییه که برای کامپیوتر مفید باشند همچنین وظیفه ی دیگه ی Parser اینه که دیتای ورودی که دنباله ای از توکن هاست رو بگیره و تعیین کنه که آیا این عبارت می تونه به وسیله ی گرامر زبان مورد نظر تولید بشه یا نه.اولین مرحله ی Parse کردن HTML ، تحلیل واژگان یا Lexicon هست. همونطور که می تونید واژگان HTML شامل موارد زیر هست :DocTypeStartTagEndTagCommentCharacterEndOfFileزمانی که یک سند HTML در حال Parse شدن هست عبارات اون توسط Finite-state machine میان و توکن ها رو تشخیص میدن. توکن ها حاوی همین مقادیری هستند که بالاتر لیست شده ( تگ شروع و پایان ، attribute name ها و مقادیر اون ها ) و اگر اون فایل HTML درست نوشته شده باشه، تجزیه کننده اون نشانه گذاری هایی رو که انجام داده توسط توکن ها درون داکیومنت قرار میده !زمانی که HTML تجزیه شد DOM Tree ساخته میشه ! اما اشتباه نکنید همه ی HTML تجزیه شده ی ما DOM Tree رو شامل نمیشه بلکه ممکنه چیزهایی در HTML ما وجود داشته باشه که در DOM ما وجود نداشته باشه.در عکس زیر نمای یک DOM Tree رو می بینید :در DOM Tree ما میتونیم نحوه ی ارتباط تگ ها و همچنین سلسله مراتب اون ها رو بدونیم.دومین مرحله Parse کردن CSS هست که منجر به ساخت CSSOM Tree میشه. فرآیند Parse کردن CSS تقریبا سر راست تر است ( نسبت به HTML ) که وارد این مقوله نمیشیم ولی بخش منابع رو مطالعه بفرمایید. ساختن CSSOM Tree بسیار بسیار سریع انجام میگیره.در عکس زیر نمای یک CSSOM Tree رو می بینید: یک فقره CSSOM Tree پردازش های دیگر :به گفته ی Tali Garsiel مدل وب یک مدل همزمانی و sync هست.پس زمانی که داره CSSOM Tree ساخته میشه assest هایی مثل فایل های جاوا اسکریپت دانلود میشن ( با تشکر از preload scanner ) همچنین در این مرحله مرورگر یک accessibility tree هم می سازه که ورژن هوشمند و همروند DOM هست که یک Experimantal Javascript API هم براش داریم که باز هم در منابع می تونید بیشتر ازش بخونید.فرآیند Rendering در مرحله ی قبل CSSOM Tree و DOM Tree ساخته شدند و با استفاده از این دو ما میتونیم Render Tree رو بسازیم تا بتونیم layout موردنظرمون ( آن چیز هایی که قابل دیدن هستند ) رو بسازیم.پس خیلی طبیعیه که گزاره ی DOM Tree === Render Tree همیشه درست نیست و گاها چیزهایی در DOM Tree وجود دارند که visible نیستند. ( همچنین تگ هایی که display:none شدند هم در Render Tree وجود ندارند اما تگ هایی که visibility: hidden شدند در Render Tree قرار می گیرند)این مرحله اختصارا Style نامیده میشه و حالا میخوایم به سراغ مرحله ی Layout بریم.در مرحله ی Style مرورگر مشخص کرده که چه node هایی قراره نمایش داده بشن ( حتی اگه invisible باشند )اما در مرحله ی Layout اندازه ی طول عرض و همچنین جایگاه هر node ای که در Render Tree مشخص شده تعیین میشه و به تکرار این مرحله در دفعات بعدی میگن Reflow !فرآیند Paintدر این مرحله مرورگر تمام layout هایی که در مرحله ی قبلی محاسبه شده بودند رو به صورت پیکسل های واقعی روی صفحه نمایش نشون میده. این مرحله از اون چیزی که فکر می کنید بسیار سریع تر انجام میشه پس احتمالا برای پرفومنس سایتتون جزو اولویت های اولیه می تونه نباشه. و به انجام دوباره ی این فرآیند میگن Repaint !فرآیند ترکیبخب تبریک میگم سایت آماده ی نمایشه و تمام اجزایی که در مراحل قبلی به Render Tree پیوستند و سپس با Style مشخص شدند و با Layout بندی از جایگاه خودشون باخبر شدن و در نهایت با Paint رنگ آمیزی شدند و به پیکسل های قابل نمایش درومدند در این مرحله باهم ترکیب میشن و هر بار که لازم باشه این فرآیند ها تکرار بشن ما Reflow و Repaint و Re-composite رو خواهیم داشت.خلاصه ی کوتاههر ریکوئستی به سمت وب سرور با یک درخواست HTTP شروع میشه سپس از سمت سرور یک response حاوی دیتا و مقادیری مانند header ارسال میشه. مرورگر شروع به Parse کردن HTML می کنه و با استفاده از اون DOM Tree رو میسازه . اصولا در ریکوئست اولیه تعدادی منابع خارجی یا External resource هم پیدا میکنه که بعضی هاشون خاصیت بلاک رو دارند یعنی Parse کردن HTML رو تا زمانی که اون فایل موردنظر هندل نشه متوقف می کنند و بعضی از این External Resource ها هم خاصیت none Blocking دارند. بعد از این اتفاقات به شکل مشابه CSSOM Tree ساخته میشه و از ترکیب این دو Render Tree بوجود میاد که با استفاده از Style دهی ابتدا مشخص می کنه چه node های قابل نمایشی داریم و سپس با layout بندی جایگاه و اندازه ی هر node رو تعیین می کنه و در مرحله ی paint اون ها رو به پیکسل هایی قابل نمایش در میاره.چند نکتهسعی کنید از منابع خارجی با دامنه هایی غیر از دامنه ی خودتون استفاده نکنید چون فرآیند DNS Lookup مجددا تکرار میشه.از display:none استفاده نکنید چون باعث میشه مجددا Render Tree ساخته بشه و پرفومنس سایتتون رو کاهش میده به جاش از visibility : hidden استفاده کنید.در مرحله ی Parsing ابتدا این Parser هست که درخواست Token رو به Lexer می فرسته و بعد Lexer توکن رو برای Parser می فرسته و اینجا Parser تصمیم میگیره که از این توکن استفاده کنه یا برای خودش ذخیره کنه.در مرحله Layout دو اتفاق میوفته یکی Global Layout هست که مقادیری مثل font-size رو برای صفحه اعمال می کنه و دیگری Incremental Layout هست که بالا در موردش صحبت کردیم.و در آخر بریم که reflow گوگل رو ببینیم :در انتهای مقاله باید تشکر کنم از دوست عزیزم بهنام علیزاده که با دلسوزی متن من رو خوندن و اشکالات علمی رو بهم متذکر شدند و باعث شدند که من اصلاحشون کنم تا مقاله ی بهتری داشته باشیم.امیدوارم شما هم تو زندگیتون یه بهنام علیزاده داشته باشید که علمشو رایگان در اختیارتون بزاره. ?ممنونم که این مقاله رو مطالعه کردید در قسمت نظرات به سوالاتتون پاسخ میدم.تا مقاله ی بعد زکات علم رو فراموش نکنید.من در شبکه های اجتماعی :LinkedIn | Gmail | منابع مفید برای مطالعه ی بیشتر :Notes on “How Browsers Work”How Browsers Work: Behind the scenes of modern web browsers</description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Mon, 13 Apr 2020 02:29:25 +0430</pubDate></item><item><title>رفقای خوب (Gatsby+Netlify)</title><link>https://virgool.ir/iran-react-community/رفقای-خوب-gatsbynetlify-mwarqiiut4yt</link><description>goodfellasاحتمالا عنوان این پست شما رو به یاد یکی از شاهکار های مارتین اسکورسیزی بندازه ! اگه حتی این فیلم رو ندیدید و یا رابرت دنیرو رو یادتون نمیاد نگران نباشید :) قراره این بار یک رفقای خوب دیگه رو بخونید به کارگردانی جاوا اسکریپت و تولد یک ستاره ی جدید به نام گتسبی !اول از همه باید بهتون بگم که این پست خیلی طولانی میشه چون قراره یک پروژه رو با گتسبی و نتلیفای بالا بیاریم و کامل توضیح بدیم پس اگه الان فرصتش رو ندارید حتما این مقاله رو بوکمارک کنید تا بعد ها به سراغش بیاید.مقدمهچند وقتی هست که مبحثی به نام JAM Stack روز به روز ترند تر میشه. قطعا تا الان با استک های مختلفی مثل MERN،MEAN و یا حتی LAMP آشنایی دارید.اما JAM Stack مخفف شده ی عبارت Javascript API Markup هست که برخلاف باقی استک ها قصد معرفی ابزار نداره و یک جور طرز تفکرهقسمت  که خب کاملا مشخصه قراره بر محور جاوا اسکریپت و فریمورک ها و کتابخونه هاش بچرخیم.قسمت API : یه سری reusable API ها هست که عمدتا می تونید از api as service ها استفاده کنید.قسمت Markup : اگه با مجموعه زبان Markup آشنایی ندارید توصیه میکنم این مقاله رو بخونید. اما به صورت خلاصه می تونم بگم که یک مجموعه زبان نشانه گذاری هست برای توصیف متن ها در علم کامپیوتر که بهش شبه زبان برنامه نویسی ام میگن.حالا JAM Stack مگه چیه که داره ترند میشه؟خب این معماری وب یک سری مزایایی داره که دیگر معماری ها ندارن مثل :پرفومنس بیشترخیلی خیلی ایمن ترارزانترسرعت توسعه و تجربه ی توسعه ی بهترمقیاس پذیریبرای توضیح بیشتر هر کدوم از این دلایل می تونید به این سایت مراجعه کنید و یا منتظر بمونید تا انتهای مقاله که موارد بالا رو درک کنیم باهم :)تیتراژ ابتدایی با گتسبیخب ما واسه ی پیاده سازی یک JAM Stack ساده از گتسبی و نتلیفای استفاده می کنیم.گتسبی چیه : گتسبی یک فریمورک بر پایه ی ری اکت هست که باهاش می تونید SSG درست کنید.نتلیفای چیه: یک شرکت کلاود کامپیوتینگ هست که به automate کردن وب اپلیکیشن های مدرن می پردازه.ما قصد داریم با استفاده از Gatsby به عنوان بخش Javasciprt و Netlify CMS به عنوان بخش reusable API به تولید Markup بپردازیم و یک وبلاگ ساده رو با این معماری وب بسازیم.قبل از هرچیزی چند خط بالاتر از کلمه ی SSG استفاده کردم که برای اینکه هم بیشتر با گتسبی آشنا بشید و هم برخی از مزیت های استفاده از اون رو درک کنید توصیه میکنم ابتدا دموی پروژه مون رو ببینید و مقاله ی مندرج شده در اون رو بخونید و دوباره به همین جا برگردید.دموی پروژه( برای خوندن مقاله روی عنوان مقاله کلیک کنید )شروع پروژه با ایجاد ساختارخب برگشتید؟ چطور بود دمو؟ بنظر من که این SSG ها ( در vue.js مانند Gridsome ) خیلی حس بهتری به کاربر ارائه میدن :دی !اول از همه باید بگم پیش نیاز این پروژه آشنایی شما با ری اکت هست و بسو اما چیز هایی که برای شروع این پروژه نیاز دارید :یک پروژه ی گتسبی ( که باهم ایجادش می کنیم )یک اکانت گیت هابیک اکانت Netlifyایجاد یک پروژه گتسبیابتدا لازم هست که gatsby-cli رو نصب کنید مانند دستور زیر :npm install -g gatsby-cliببینید گتسبی یه سری استارتر داره یعنی یه سری پروژه های از قبل کانفیگ شده ی آماده برای شروع کارشما با دستور زیر می تونید یک پروژه گتسبی بسازید که از استارتر دیفالت استفاده می کنه اما من توصیه میکنم این کار رو نکنید و برای این پروژه از استارتر hello world استفاده کنید تا تموم فایل ها و کانفیگ های پروژه رو خودمون انجام بدیم ( بنده به بیماری خود کانفیگی دچار هستم )// uses default starter&#xA;gatsby new [project-name]&#xA;// Follow these instructions&#xA;gatsby new hello-world https://github.com/gatsbyjs/gatsby-starter-hello-world&#xA;cd hello-world&#xA;gatsby developخب تا الان شما یک پروژه گتسبی رو بالا آوردید و ظاهرش رو مشاهده می کنید.بریم به قسمت دوم و پروژه رو بیاریم روی گیت :git remote add origin https://github.com/[YOUR-GITHUB-USERNAME]/[YOUR-REPO-NAME].git&#xA;git push -u origin masterحالا بریم سراغ ساخت یک اکانت توی نتلیفایبه سایت نتلیفای برید.یک اکانت بسازید و لاگین کنید.روی New site from Git کلیک کنید.روی گیت هاب که زیر Continuous Deployment قرار داره کلیک کنید. ( خب الان نیازه که به نتلیفای اجازه بدید تا به گیت هابتون دسترسی داشته باشه )حالا ریپوی مربوط به پروژتون رو انتخاب کنید.و در آخر روی Deploy site کلیک کنید.خب الان برای شما یک سابدومین ساخته شده در نتلیفای و همچنین لینک شده به برنچ مستر ریپوی پروژتون به این منظور که هر تغییراتی که توی برنچ مستر ریپوی شما انجام بشه به صورت اتوماتیک نتلیفای یک بیلد میگیره و شما نتایج رو توی این سابدومین مشاهده خواهید کرد.اما این رو باید هم به گیتهاب هم به نتلیفای بفهمونیمچطوری به گیتهاب بفهمونیم : وارد گیتاب بشید در قسمت setting و developer setting روی OAuth app کلیک کنید و یکی جدید بسازید. اسمش هرچیزی می تونه باشه و برای home page url همون آدرس سابدومینی که نتلیفای براتون ساخته رو بزارید و در قسمت authorisation callback URL مقدار زیر رو بزارید و روی Register Application بزنید.https://api.netlify.com/auth/doneخب حالا بهتون یک client ID و یک client secret میده که داشته باشیدش نیازش داریم :دیچطوری به نتلیفای بفهمونیم: وارد نتلیفای بشید و به قسمت تنظیمات سایتتون برید در منوی Access control بر روی OAuth کلیک کنید. روی Install Provider کلیک کنید و پس از انتخاب گیتهاب client ID و client secret رو وارد کنید.نصب کردن Netlify CMSخب دوستان قبل از نصب سیستم مدیریت محتوای نتلیفای ( یا خدا فارسیش چقدر طولانیه :)) ) باید بهتون بگم که گتسبی یک سری پلاگین داره که برای ارتباط با API هاش ازشون استفاده می کنه و تقریبا برای هرچیزی که فکرشو بکنید یک پلاگین داره اما اگر نداشت هم نگران نباشید چون به راحتی میتونید براش بنویسید :)برای نصب Netlify CMS و پلاگینش از دستور زیر استفاده می کنیم:npm install --save netlify-cms gatsby-plugin-netlify-cmsپس از نصب هر پلاگین در گتسبی شما باید به گتسبی بفهمونید که این پلاگین نصب شده پس در فایل gatsby-config.js باید کانفیگ پلاگین رو وارد کنید ( نگران نباشید چون همه ی این کانفیگ ها به همراه پلاگین در اینجا قرار دارند )پس تنظیمات زیر رو در فایل gatsby-config.js خودتون وارد کنید :// In your gatsby-config.js file&#xA;module.exports = {&#xA;plugins: [&#xA;// ... other plugins&#xA; `gatsby-plugin-netlify-cms`&#xA;// ... other plugins&#xA;],&#xA;}خب دست به گیرنده هاتون نزنید تا اینجا ما ساختار پروژمون رو ساختیم و اما یه توضیح کوچیک در مورد فایل هایی که توی گتسبی می بینید بدم و بریم سراغ ادامه ی پروژه :src : هسته ی تمام کدهایی که شما می نویسید توی این پوشه است که از چند زیر پوشه تشکیل شدهsrc/components : دقیقا مثل ری اکت اینجا هم قراره کامپوننت بنویسیمsrc/pages : هر فایلی که در این پوشه قرار بگیره یک صفحه جداگانه میسازه و دیگه لازم نیست شما از پکیج های روتر استفاده کنید.git-config.js : منبع اصلی کانفیگ پلاگین های شما و همچنین به صورت کلی هر کانفیگی که در مورد اپ دارید.و باقی فایل ها که فایل های مرسوم پروژه ها هست و فایل هایی که بعد ها به پروژمون اضافه خواهد شد.تا اینجا ساختار فایل های پروژه ی شما باید مثل زیر باشه :-node_modules&#xA;- src&#xA;   -components&#xA;   -pages&#xA;.gitignore&#xA;.prettierignore&#xA;.prettierrc&#xA;gatsby-config.js&#xA;LICENSE&#xA;package-lock.json&#xA;package.json&#xA;README.mdخب تازه میخوایم پروژه رو شروع کنیم و امیدوارم که خسته نشده باشید :دیواکنش اون دسته از دوستانی که خسته شدنپیکربندی Netlify CMSبعد از یک سری اتفاقات هیجان انگیز حالا وقت اون رسیده که Netlify CMS رو کانفیگ کنیم.و اما این فایل کانفیگ نمی تونه هرجایی قرار داشته باشه و یک مکان خاص میخواد.در روت پروژتون یک پوشه به نام static بسازید و داخل اون یک پوشه به نام admin بسازید و داخل admin یک فایل به نام config.yml ( اگه کنجکاو شدید که yml چیه این لینک رو بخونید )# In your static/admin/config.yml file&#xA;backend: &#xA;name: github&#xA;repo: [YOUR-GITHUB-USERNAME]/[YOUR-REPO-NAME]&#xA;media_folder: static/assets&#xA;public_folder: assetsنام ریپو و یوزنیم گیتهابتون رو در تنظیمات جایگذاری کنید.حالا وقت اون رسیده که یکی از انواع collection ها رو برای ادامه ی پروژه انتخاب کنیم.در Netlify CMS دو جور کالکشن داریم ۱- فولدر کالکشن و ۲- فایل کالکشناما فرقشون چیه؟فولدر کالکشن بیشتر زمانی استفاده میشن که محتوای شما از یک جنس و شبیه به هم باشه ( به عنوان مثال وبلاگ که از چندین پست با یک فرمت یکسان تشکیل میشه و یا یک سایت فروشگاهی که از چندین محصول با یک فرمت یکسان تشکیل میشه )فایل کالکشن بیشتر مربوط به زمانی هست که محتوای شما منحصر به فرد هستند.در این آموزش ما از فولدر کالکشن استفاده می کنیم و کانفیگ زیر رو به فایل config.yml اضافه می کنیم :متاسفانه ویرگول تورفتگی ها رو درست نمایش نمیداد و مجبورم کدها رو اینطوری بزارم.خب و اما معنی این ها چیه؟در این نوع پیکربندی ها هرچیزی نیاز داره که یک label و name داشته باشه.چیزی که در ادمین پنل نشون داده میشه label هست و چیزی که ما توی کد باهاش به عنوان متغیر کار داریم اسمش name هست.پس ما اومدیم لیبل و نام کالکشن رو Pages گذاشتیم.نوع کالکشنمون رو با :files مشخص کردیم که از نوع فایل کالکشن هست و مجددا همونطور که بالا گفتم نیاز داریم تا لیبل و نام رو بهش اختصاص بدیم.و زیرش یکی از پیج هامون رو معرفی کردیم بهش ( همون پیجی که ابتدای مطلب مقاله ی مفهوم SSG رو مطالعه کردید )و با :fields مشخص کردیم که چه فیلد هایی رو نیاز داریم تا در ادمین پنل این پیج قرار داشته باشن ( اگه متوجه نشدید مشکلی نداره، جلوتر که بریم با چشم خیلی چیزها رو می بینیم )یک نکته ی مهم : زمانی که از فایل کالکشن استفاده می کنید دقت داشته باشید که فایلی که تعریفش می کنید حتما باید وجود داشته حتی اگه خالی باشه ( در اینجا فایلی که ما تعریف کردیم content/ssg-concept.md هست ) پس یک پوشه در روت پروژتون به نام content بسازید و داخلش یک فایل خالی به نام ssg-concept.md رو بسازید.خب همه چیز خوبه. الان به آدرس زیر برید و لاگین کنید :[YOUR-NETLIFY-SUBDOMAIN]/admin/&#xA;// for example: https://frontcampigan.netlify.com/admin/الان باید تصویر زیر رو ببینید :داشبورد ادمین پنل مدیریت محتواو با کلیک کردن روی SSG Concept به حکمت اون field ها و widget هایی که تعریف کردیم پی می برید:ویجت هایی که تعریف کردیم در فیلدهای بالا اینجا کاملا خودنمایی می کننیکی از ضعف هایی که Netlify CMS داره اینه که ادیتور قدرتمندی مثل strapi نداره.و اما شاید الان براتون این سوال پیش بیاد که اگر بخواید فیلد ها و ویجت های متنوع تری اضافه کنید باید چیکار کنید که مفتخرم عرض کنم Netlify CMS یک داکیومنت خوب داره که در این قسمت می تونید فیلد ها و ویجت های مختلف رو ببینید و استفاده کنید.وارد کردن اطلاعاتدر این مرحله فیلد های مورد نظر رو پر کنید و به روی publish کلیک کنید.خطر ذوق مرگی: پس از publish کردن به ریپوی گیتهاب خود رفته و ببینید که چطور commit جدیدی خوردهنکته ی گیتی: وقتی ریپوی شما commit جدیدی میخوره اما کد لوکال شما همچنان sync نیست باید حتما دستور زیر رو اجرا کنید تا مطابق با آخرین تغییرات ریپو پیش برید و کد بزنید :git pullپس از انجام دستور بالا به همون فایلی که در config.yml تعریف کردیم برید و میبینید که اون فایل دیگه خالی نیست !گرفتن اطلاعاتخب تجربتون تا اینجا از این استک چی بوده؟ می دونید اگر قرار بود به صورت فرانت معمولی و عادی این پروسه رو طی کنیم باید فقط چه مدت زمانی منتظر می موندیم تا به این فاز برسیم؟ پس سرعت توسعه به شکل محسوسی بالا رفتهابتدای شروع نوشتن این مقاله فکر میکردم نمی تونم انقدر تایپ کنم :|خب تا اینجا ما تونستیم اطلاعات رو از پنل ادمین به ریپوی گیتهابمون بفرستیم اما همچنان چیزی در سایتمون نمی بینیم چون به گتسبی نگفتیم که این اطلاعات و دیتا رو چطور پیدا کنه و به صفحات ما اضافه کنه.برای این که بتونیم به گتسبی بگیم چطور این اعمال رو انجام بده نیاز داریم تا دوتا از پر کاربردترین پلاگین های گتسبی رو نصب کنیم پس دستور زیر رو بزنید :npm install --save gatsby-source-filesystem gatsby-transformer-remarkما از پلاگین gatsby-source-filesystem استفاده می کنیم تا به گتسبی بگیم فایل هامون کجاست.طبق فیلد هایی که گذاشتیم و تعریف کردیم ما دو جور فایل داریم یکی فایل های markup یا همون md. و یکی هم فایل های عکسمونپس توی فایل gatsby-config.js کدهای زیر رو اضافه می کنیماگه واستون سوال پیش اومد که dirname__ چی هست باید بگم این عبارت به پوشه ای که توش این فایل رو می نویسیم برمیگرده&#xA;اولین نمونه ی کانفیگ ما در کدهای بالا به دنبال تصاویر میگرده و دومیش به دنبال فایل های markdown ای که توسط CMS ساخته میشه.همچنین در مورد gatsby-transformer-remark نقش یک parse کننده برای فایل های markdown رو داره.بریم سراغ GraphQL ؟گراف کیوال یک Query Language برای API هاست که بر خلاف REST بسیار منعطف تر و بهینه تر و قدرتمند تره که در سال ۲۰۱۲ توسط فیسبوک ساخته شده و اگه باهاش آشنایی ندارید و میخواید یک مرور سریع بهش داشته باشید از این سایت دیدن کنید و تمرین هاش رو انجام بدید و بیاید بریم سراغ ادامه ی مقاله.ما اینطوری منتظر میمونیم تا شما برید بخونید و تمرین کنید و بیاید :))چون در این مقاله قرار نیست به آموزش گراف کیوال بپردازیم می تونید تموم کوئری ها رو کپی کنید و بنویسید.یکی از ابزارهایی که گتسبی داره و به نوعی کوئری زدن رو راحت تر کرده ابزاری هست به نام GraphiQL که می تونید اون رو در آدرس زیر پیدا کنید :http://localhost:8000/___graphqlحالا ما میخوایم node ای رو پیدا کنیم که بهمون ssg-concept.md رو بده.یه راه اینه با استفاده از sourceInstance فیلتر کنیم و بگیم دقیقا چه فایلی رو میخوایم اما این راه به قول برنامه نویس ها بدبوعه و زیاد خوشایند نیست.allFile (filter: {sourceInstanceName: {eq: &#34;content&#34;} name: {eq: &#34;ssg-concept&#34;}})پس ما یک کار زیباتر انجام میدیم و با استفاده از نود childMarkdownRemark شروع به خوندن فایل های markdown می کنیم این فایل ها رو توی frontmatter و html جداسازی می کنیم.اینطوری بدنه ی فایل های Markdown از طریق html در دسترس خواهد بود و چیزهای دیگر مثل رشته ها تاریخ و .. از طریق frontmatter در دسترس خواهد بود.از اونجایی که ما در body فایل های markdown چیزی نداشتیم پس به frontmatter کوئری می زنیم: نتیجه ای که به ما برمیگرده یک object هست که حاوی مقادیری هست که میخواستیم ( نه کمتر و نه بیشتر ) این دقیقا یکی از قدرت های GraphQL هست.نمایش اطلاعاتاین دیتایی که به ما برمیگرده در props قرار میگیره و ما می تونیم ازش برای نمایش اطلاعات استفاده کنیم.نکته مهم : حواستون باشه که edges یک ارایه است و باید روش map بزنید.پی نوشت : من چون یکم به سبک ری اکت نوشتم و از کامپوننت های مختلفی استفاده کردم جهت نمایش گذاشتن کدهام شما رو گیج می کنه اما اگه بخواید می تونید آدرس گیت پروژه که در انتهای مطلب میگذارم رو بخونید و روش انتقال دیتا رو توسط من ببینید و خب حالا میریم سراغ قسمت آخر مقاله..حس دوستانی که بی وقفه تا اینجا مطالعه کردن مطلب رو :))ایجاد داینامیک صفحات با استفاده از اطلاعاتخب تا الان یک صفحه ی ایندکس خیلی قشنگ ساختیم که عنوان ، زمان مطالعه ( طبق تعداد کاراکتر می تونید با استفاده از این سایت زمان خوندن رو محاسبه کنید ) و یک خلاصه ی مقاله رو نمایش میده.اما ما نمی خوایم که فقط خلاصه یک مقاله رو بخونیم و تمایل داریم تا تموم مقاله رو بخونیم. درست مثل همون چیزی که در دمو دیدید تصمیم داریم یک صفحه ی کامل مقاله با استفاده از دیتا بسازیم.یک راهش اینه که به مسیر src/pages بریم و برای هر مقاله جداگانه یک صفحه بسازیم اما این خیلی هاردکده و از یه برنامه نویس به دوره پس ما راه دوم رو انتخاب می کنیم.راه دوم چیه؟ این که یک صفحه ی داینامیک بسازیم.مراحل ساخت یک صفحه ی داینامیک :ساخت یک مسیر یا path یا slug برای URL هر صفحهساختن صفحهساخت مسیر یا path یا slug برای URL هر صفحهاکثر Headless CMS ها این مورد رو به عنوان یک دیتا برمیگردونن و می تونید با کوئری زدن بهش دیتای مورد نظرتون رو دریافت کنید اما ما باز هم از Netlify CMS ها استفاده کردیم تا این مورد هم دستی انجام بدیم و بگیم ترسی نداره :دیبرای ساخت markdown page ها از دو API گتسبی به نام های onCreateNode و createPages استفاده می کنیم که در بسیاری از سایت ها و پلاگین ها این دو API رو مشاهده می کنید.اما برای کار با API های خود گتسبی مثل مواردی که بالا برشمردم لازمه که کانفیگ ها رو در فایلی به نام gatsby-node.js بنویسیم . پس این فایل رو در روت پروژه بسازید.سپس کد زیر رو در اون قرار بدید :exports.onCreateNode = ({ node }) =&gt; {&#xA;console.log(node.internal.type)&#xA;}خب ما از onCreateNode استفاده کردیم تا به گتسبی بگیم هر زمان یک node جدید ساخته شد و یا آپدیت شد به ما خبر بده.برای اینکه دقیق تر متوجه بشید یک بار development server رو متوقف و سپس مجدد ران کنید.حالا به ترمینال نگاه کنید و چیز هایی که لاگ انداخته شده رو ببینید.در مرحله ی بعدی ما میخوایم با استفاده از این API توسط Markdown Remark هامون به صفحات Markdown لینک بدیم و مسیر یا همون slug رو بسازیم.پس دوباره کد موجود در gatsby-node.js رو به کد زیر تغییر بدید :exports.onCreateNode = ({ node }) =&gt; {&#xA;if (node.internal.type === `MarkdownRemark`) {&#xA;console.log(node.internal.type)&#xA;}&#xA;}اما هدف صالی ما از این کار چیه؟ ما میخواهیم که اسم فایلمون اگر ssg-concept.md هست مسیر یا slug مورد نظرمون /ssg-concept/ باشه.اما بنظر شما باید چیکار کنیم تا اسم فایل markdown رو از node مورد نظرمون دریافت کنیم؟شما باید node graph رو مرور کنید و با استفاده از node-parent به نام فایل دسترسی پیدا کنید.برای این منظور فایل gatsby-node.js رو مجدد تغییر بدید:exports.onCreateNode = ({ node, getNode }) =&gt; {&#xA;if (node.internal.type === `MarkdownRemark`) {&#xA;const fileNode = getNode(node.parent)&#xA;console.log(`\n`, fileNode.relativePath)&#xA;}&#xA;}مجددا development server تون رو ری استارت کنید و در ترمینال لاگ مربوط به مسیر فایل markdown رو مشاهده می کنید.خب حالا زندگی شیرین شد نه؟ :دیالان با استفاده از gatsby-source-filesystem میایم و مسیر مدنظر برای URL هامون رو می سازیم:const { createFilePath } = require(`gatsby-source-filesystem`)&#xA;exports.onCreateNode = ({ node, getNode }) =&gt; {&#xA;if (node.internal.type === `MarkdownRemark`) {&#xA;console.log(createFilePath({ node, getNode, basePath: `pages` }))&#xA;}&#xA;}مجددا development server رو ری استارت کنید و به من بگید که لذت بخش بود یا نه؟ :)بسیار هم عالی الان شما یک مسیر دارید که باهاش می تونید به صورت داینامیک پیج بسازید و فقط لازمه که این مسیر رو به عنوان یک فیلد اضافه به node اضافه کنیم که این کار رو با createNodeField انجام میدیم پس دوباره به gatsby-node.js برید و این بار به صورت زیر ویرایشش کنید :const { createFilePath } = require(`gatsby-source-filesystem`)&#xA;exports.onCreateNode = ({ node, getNode, actions }) =&gt; {&#xA;const { createNodeField } = actions&#xA;if (node.internal.type === `MarkdownRemark`) {&#xA;const slug = createFilePath({ node, getNode, basePath: `pages` })&#xA;createNodeField({&#xA;node,&#xA;name: `slug`,&#xA;value: slug,&#xA;})&#xA;}&#xA;}پس از ری استارت کردن development server این بار ابزار GraphiQL رو باز کنید و نتیجه ی کوئری زیر رو ببینید:هووورررراااا ! شما مسیر رو ساختید ! دمتون گرم که تا اینجا اومدید.ساختن صفحاتبا استفاده از createPages API و کد زیر که در gatsby-node.js می نویسیم ( پایین تر از کدهای قبل ) به مسیر مورد نظرمون کوئری می زنیم و دوباره توی terminal  لاگ می زنیم ( یادتون نره که development server رو حتما ری استارت کنید )خب حالا ما همه ی دیتایی که می خوایم رو داریم پس کافیه که دیتامون رو map بزنیم و صفحات رو داینامیک بسازیم. برای این منظور یک template برای پست هامون می سازیم که یک کامپوننت ری اکتی هست و اون رو در مسیر src/template ایجاد می کنیم و نام دلخواهی مانند single-post.js براش انتخاب می کنیم. ( نوشتن این کامپوننت رو به سلیقه ی خودتون واگذار می کنم )و حالا این فایل رو به gatsby-node.js معرفی می کنیم و مجدد کل فایل رو بدین شکل آپدیت می کنیم :حالا development server رو ری استارت کنید و می بینید که پیجتون ساخته شده :)برای گرفتن دیتا در template post type مدنظر می تونید یه همچین کوئری ای بزنید :شما می تونید مقادیر دیگه ای رو هم بگیرید ( غیب گویی با چشمان بسته )الان صفحات شما کامل ساخته شدند :) فقط کافیه به title مقاله هاتون که در صفحه ی اصلی لیست شدند یک لینک با استفاده از Link خود گتسبی بدید و در صفحه ی اصلیتون کوئری بزنید و slug رو دریافت کنید تا به اون مسیر مورد نظر لینک بزنید.کوئری مورد نظر تقریبا یه همچین چیزی میشه ( بسته به نوع کامپوننت نویسی شما و همچنین مواردی که ممکنه کوئری بزنید قطعا متفاوت خواهد بود و کوئری زیر صرفا جهت اینه که نحوه ی کوئری زدن slug رو ببینیم ولی شما می تونید سورس کامل پروژه رو توی گیت ببینید )خط پایانرابرت دنیرو توی رفقای خوب میگه هیچوقت چغلی رفتار دوستانت رو نکن و همیشه دهنت رو بسته نگه داراما خب من توی این پست سعی کردم تا می تونم چغلی این دو رفیق رو بکنمکمی و کاستی های نگارش رو ببخشید سعی کردم خودمونی صحبت کنم تا خستتون نکنم و قطعا توی این حجم مقاله ممکنه برخی جاها براتون مبهم باشه که من با کمال میل به تمام سوالاتتون پاسخ میدم در نظرات بپرسید ازم :)سورس کامل پروژه رو می تونید از لینک زیر ببینید :https://github.com/Mvahedii/frontcampLinkedin | Github |</description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Mon, 03 Feb 2020 02:49:53 +0330</pubDate></item><item><title>با استفاده از Profiler، ری‌اکت را بهینه تر بنویسید!</title><link>https://virgool.ir/iran-react-community/با-استفاده-از-profiler-ریاکت-را-بهینه-تر-بنویسید-akaxvzbghcdg</link><description>مقدمهبا React ساختن وب اپلیکیشن ها از همیشه بهتر و بهینه تر شد. یکی از علت های بی‌شمار اون هم استفاده React از مفهومی به نام Virtual DOM یا دام مجازی هست که باعث میشه اون قسمت هایی از نود های DOM که توسط یک سری فعالیت های کاربر (user-event) تغییر کرده سریع تر شناسایی بشه !حالا اگر برنامه ای که شما با ری اکت نوشتید نتونه ۶۰ فریم در ثانیه رو پوشش بده باید نسبت به استانداردهایی که در برنامه نویسی این وب اپ رعایت کردید مشکوک بشید :)خیلی بدیهیه که اگر وب اپ شما کند بشه برای انجام دستور العمل های کاربر زمان بیشتری طول خواهد کشید و همین امر منجر به یک تجربه ی کاربری ضعیف میشه که میتونه روی سئو شما تاثیر منفی به سزایی بزاره.و اما ، React Profiler چیست؟و اما مشکلاتی که در بالا گفتیم می تونه به علت های مختلفی پیش بیاد مثلا رندر شدن بیش از اندازه و غیر نیاز بعضی کامپوننت ها و یا مدیریت نشدن درست برخی state ها و ... که ما تصمیم داریم با Profiler اونا رو ردیابی کنیم و با شناختشون بتونیم وب اپ بهینه تری داشته باشیم.The Profiler measures how often a React application renders and what the “cost” of rendering is. Its purpose is to help identify parts of an application that are slow and may benefit from optimizations such as memoizationطبق تعریف داکیومنت ری اکت، پروفایلر میخواد به ما بگه که اپلیکیشن ری اکتی ما چطور کار می کنه و هزینه ی هر رندرش برای ما چقدر هست و هدفش اینه که به ما کمک کنه که قسمت هایی از اپلیکیشنمون که کند هست و یا احتیاج به بهینه کردن داره رو بشناسیم و بتونیم با انتخاب روش هایی اون ها رو بهینه تر کنیم ( مثل استفاده از useMemo برای هوک ها، memo برای function component ها، و یا استفاده از pure component یا lifecylce ای مانند shouldComponentUpdate برای کلاس کامپوننت ها.)پ.ن : برای آشنایی بهتر با اصطلاحات بالا میتونید این مقاله عامر رو بخونید.نحوه استفاده Profiler در یک برنامه ری اکتیاین Api در نسخه ی 16.5 قرار گرفت و تا نسخه ی 16.9 یک experimental API بود ( یک API تجربی که برای ایمپورت کردن باید ابتدا unstable رو می نوشتید )خوشبختانه در زمان نگارش این متن که نسخه ی 16.9 ری اکت هستیم این API به صورت کاملا ثابت منتشر شده و کافیه برای ایمپورت از دستور زیر استفاده کنید.import {Profiler} from &#39;react&#39;البته که می تونید از React.Profiler هم استفاده کنید و خط بالا رو ننویسید :)این کامپوننت می تونه هرجای برنامه ری اکتی شما بشینه و کامپوننت های شما رو wrap کنه.به عنوان مثال :در حال پروفایل کردن کامپوننت Navigationدر مثال بالا Profiler در حال wrap کردن کامپوننت Navigation هست.اما حالت های دیگه ای هم وجود داره مثل استفاده از Profiler های چندگانه و یا Profiler های تو در تو که در زیر می بینید :پروفایلر های چندگانهپروفایلرهای تو در تو برای اندازه گیری هزینه قسمت های مختلف اپلیکیشناگرچه پروفایلر یک کامپوننت اصطلاحا سبک وزن به حساب میاد اما در استفاده از اون دقت کنید! چون مقداری CPU و Memory سربار به اپلیکیشن شما اضافه می کند.بررسی Profiler Props همونطور که در تمامی مثال های بالا دیدید این کامپوننت ۲ تا Prop داره که id و onRender هستند.خب id مشخص کننده ی این هست که این نتیجه ای که بعدا میبینیم چیه مربوط به کدوم پروفایلر هست.و اما onRender : یک callback function هست که ری اکت هر بار کامپوننتی که توسط پروفایلر ، wrap شده ، commit update میشه صداش می زنه تا اطلاعاتی در مورد چگونگی رندر و زمانی که طول کشیده به ما بده.ممکنه این توضیح یکم گیجتون کرده باشه پس سعی میکنم کامل تر و جزئی تر توضیح بدم. به مثال اولیمون برگردین. کامپوننتی که پروفایلر اون رو wrap کرده Navigation هست. هر زمان که این کامپوننت آپدیت بشه ( یا حتی mount بشه ) ، ری اکت میاد و onRender رو صدا می زنه.پارامترهای onRender :حال به بررسی تک تک پارامتر های آن می پردازیم :پارامتر id = مشخص می کنه دقیقا اطلاعاتی که لاگ میندازید مربوط به کدوم پروفایلر هست ( اشاره به پروفایلرهای چندگانه و تو در تو )پارامتر phase = دارای دو مقدار mount و update هست. کلا یک کامپوننت در ری اکت در یکی از این ۲ فاز قرار داره که یا برای اولین بار mount شده و یا بر اثر تغییر props هاش و یا state ها update شده. پس همیشه هنگام لاگ انداختن این پارامتر انتظار یکی از این مقادیر رو داشته باشید.پارامتر actualDuration = پروفایلر و تمام فرزندانش رو درنظر بگیرید. زمان سپری شده برای آپدیت فعلی رو با این پارامتر می تونید بدست بیارید. نکته ای که حائز اهمیت هست اینه که در حالت ایده آل انتظار میره که actualDuration در فاز mount بیشترین مقدار رو داشته باشه و در باقی حالات مقدارش کمتر باشه ( به علت اینکه در آپدیت های بعدی ممکنه بعضی از فرزندان نیاز به رندر شدن نداشته باشند ) همچنین اینجا جاییه که می تونید به استفاده کردن از اون حالت های بهینه ی ابتدای مقاله فکر کنید.پارامتر baseDuration = پروفایلر و تمام فرزندانش رو در نظر بگیرید. زمان سپری شده برای هر کامپوننت در آخرین رندر رو به ما میده. نکته هایی که وجود داره اینه که اگر یک کامپوننت ری-رندر نشه از ارائه ی زمان برای این کامپوننت خودداری میکنه. و اگه زمان ارائه شده در رندرهای بعدی کمتر از زمان ارائه شده در یک commit update خاص باشه از نمایش اون ها هم صرف نظر می کنه به همین دلیل هست که Brain Vaughn اعتقاد داره که این مقدار در واقع بدترین زمان برای رندر رو برآورد می کنه.پارامتر startTime = زمانی که ری اکت شروع به رندر میکنه رو به صورت TimeStamp در اختیار ما قرار میده.پارامتر commitTime = زمانی که آپدیت کاملا انجام شده رو به صورت TimeStamp در اختیار ما قرار میده و اگر چندین پروفایلر رندر بشن این زمان بین همشون مشترک خواهد بود و در صورت تمایل میتونید اون ها رو گروه بندی کنید.پارامتر interaction = زمانی که متد render و یا setState در کلاس ( و معادل هاشون در Hook ) صدا زده میشه این پارامتر میاد و علت به روزرسانی رو مشخص میکنه. که هنوز به صورت experimental API هست.اضافه شدن Profiler به React Dev Toolsعلاوه بر مشاهده ی گزارشات توسط لاگ انداختن در متد onRender ، میتونیم از افزونه ی محبوب React Dev Tools برای برنامه های ری اکتیمون استفاده کنیم و خیلی چیز ها رو به صورت ویژوال ببینیم.پس اول این افزونه رو بسته به مرورگرتون دانلود و نصب کنید.برای کرومبرای فایرفاکس ♥️پس از نصب و استفاده از پروفایلر پروژتون رو ران کنید و با inspect گرفتن دو تا تب می بینید که مربوط به این افزونه هست : یکی component و دیگری profiler که خب ما در این جا با دومی کار داریم :)برای پروفایل کردن کافیه که روی دایره آبی کلیک کنید تا رکورد شروع بشه و بعد از شروع شدن رکورد کاملا عادی و بدون استرس با اپلیکیشنتون کار کنید :دیزمانی که کارتون تموم شد و یا اون بخش های مدنظر اپتون رو تست کردید ریکورد رو استاپ کنید و به اینجا برگردین تا باهم بتونیم نتایجی که میده رو درست بخونیم و تحلیل کنیم :)نتایجی که به من در هنگام استفاده از یک Counter ساده داد اینه :حالا بریم این اطلاعات رو تقسیر کنیم.پیمایش بین آپدیت ها یا همان Browsing Commitsدر این قسمت هر کدام از این مستطیل ها یک single commit هستند و می تونید با کلیک بر روی هر کدوم اطلاعات مربوط به هر commit رو جداگانه ببینید.حجم و رنگ هر کدوم از این مستطیل ها نشان دهنده ی هزینه ی رندر و زمان سپری شده است.اصولا رنگ زرد بیشترین هزینه و رنگ آبی کمترین هزینه رو داره :)فیلتر کردن Commit هابا کلیک روی چرخ دنده و بعد انتخاب تب Profiler به تنظیمات جالبی می رسید.- گزینه ی اول رو در صورتی که تیک بزنید باعث میشه که علت هر رندر رو هنگام پروفایل کردن ریکورد کنه.- گزینه ی دوم و کاربردی تر اینه که شما فرضا می خواید بدونید کامپوننت هایی که از ۱۶ میلی ثانیه بیشتر طول می کشند و باعث مموری لیک می شوند رو شناسایی کنید پس این مقدار رو بر روی ۱۵ قرار میدید و یه فیلترینگ خوب خواهید داشت.با نقل قول از عامر عزیز باید بگم تا قبل از وجود این افزونه برای بحث بهینه بودن باید تب Performance رو چک می کردیم که در اون تب هم تغییرات کلی DOM داده می شد و نه کامپوننت یا V-DOMGraphبررسی Flamegraphدر این تب از زیر مجموعه ی Profiler در افزونه ی React Dev Tools مستطیل هایی رو می بینید که هرکدوم نمایانگر یک کامپوننت هستند. که همانطور که پیشتر عرض کردم رنگ و سایز هر کدوم از این مستطیل ها بیانگر مدت زمانی است که آخرین رندر این کامپوننت و فرزندان آن به طول انجامیده است. که با کلیک بر روی هر کدوم از کامپوننت ها در سمت راست یک تب شامل اطلاعات Commit Information می بینید.توجه داشته باشید که طول هر مستطیل بیانگر زمان آخرین رندر کامپوننت و فرزندانش هست پس اگر یک کامپوننت در Commit های بعدی مجددا رندر نشه باز هم عدد مربوط به آخرین رندر اون کامپوننت و فرزندانش نمایش داده میشه.نکته ی دیگه هم اینه که رنگ های خاکستری ای که ملاحظه می کنید بیانگر این است در این Commit رندر نشده اند.بررسی Ranked Chartدر این چارت هر کدام از مستطیل ها نمایانگر یک کامپوننت هستند که به ترتیب زمان سپری شده ( نزولی ) مرتب شدند.یک نکته قابل ذکره، مدت زمانی که با استفاده از Profiler نمایش داده میشه ، در اصل مدت زمانی هست که کامپوننت و فرزندانش رندر شدند پس طبیعیه که هرچه کامپوننتی مدت زمان بیشتری طول بکشه فرزندان بیشتری داره یا به عبارتی دیگه به شاخه ی درخت Profiler نزدیک تره.بررسی Interactionبه سراغ تب سوم میریم :) همونطور که بالاتر هم گفتیم ری اکت اخیرا یک experimental API برای بررسی علت آپدیت ها اضافه کرده که همونطور که در تصویر پایین مشخص هست علت هر آپدیت رو مشخص میکنه.برای توضیح بیشتر باید عرض کنم که یک تابعی به نام trace که دارای ۳ پارامتر هست میتونه به دور render شما بشینه و یا هنگام به روزرسانی state ها استفاده بشه و یا حتی میتونه به صورت async استفاده بشه.این سه پارامتر هم به ترتیب یک string برای علت آپدیت شدن هست که بعدا قراره به ما در Profiler نشون داده بشه. پارامتر دوم تابع performance.now هست که زمانی که یک آپدیت commit میشه یا ثبت میشه این تابع صدا زده میشه ( بعدا ازش چیزهای بیشتری خواهم نوشت ) و یک callback function هست.هر کدام از این نقطه ها نمایانگر Commit ای هستند که مربوط به Interaction مربوطه بوده.بررسی React Profiler در پروداکشنهمونطور که در بالاتر هم گفتیم پروفایلر به علت اضافه کردن مقداری اورهد به برنامه ی شما به صورت پیش فرض در نسخه ی پروداکشن غیرفعال شده.اما اگه همچنان اصرار دارید که در نسخه پروداکشن از پروفایلر استفاده کنید ری اکت یک کانفیگ ویژه برای شما در نظر گرفته :)در صورتی که پروژه ی شما با CRA بالا اومده تنها راهی به صورت همیشگی پروفایلر در پروداکشن شما فعال بشه ایجکت کردن هست و سپس وب پک رو به در مسیر زیر تغییر بدید :config/webpack.config.prod.jsحالا تغییرات زیر رو در این فایل انجام بدید :module.exports = {&#xA;  //...&#xA;  resolve: {&#xA;    alias: {&#xA;      &#39;react-dom$&#39;: &#39;react-dom/profiling&#39;,&#xA;      &#39;scheduler/tracing&#39;: &#39;scheduler/tracing-profiling&#39;,&#xA;    }&#xA;  }&#xA;};نکته ی اول اینکه حتما ورژن react-dom شما باید حداقل 16.6.0 باشه.نکته ی دوم اینکه حتما ورژن scheduler شما باید حداقل 0.10.0 باشهبررسی React Profiler در React-Nativeتا به این لحظه ( زمان نگارش مقاله ) امکان استفاده از این api در ری اکت نیتیو وجود ندارد و به محض اینکه اطلاعات بیشتری در این مورد بدست بیاورم در این پست برای RN ای ها خواهم نوشت :)امیدوارم که خستتون نکرده باشم و این مطلب به دردتون بخوره.هر سوالی داشتید من در خدمتتون هستم ♥️Linked-in : mohammad-vahediTwitter : @mvahediiiimail : vahedi.ce@gmail.com</description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Sat, 21 Sep 2019 23:17:15 +0330</pubDate></item><item><title>برنامه نویسای خوب چطوری برنامه نویس شدن؟</title><link>https://virgool.ir/@vahedi.ce/برنامه-نویسای-خوب-چطوری-برنامه-نویس-شدن-eymwk3o5vmv1</link><description>ایده ی نوشتن این پست برمیگرده به مواجه شدن همیشگی با این سوال : &#34; از کجا شروع کنم؟&#34; یا مثلا سوالاتی مثل این : &#34; من میخوام برنامه نویسی رو شروع کنم اما نمیدونم از کجا شروع کنم؟&#34; شما هم حتما تا به حال به این نوع سوالا برخورد کردید و یا بخشی از جوونیتون رو پای رسیدن به یک راه درست از دست دادید ( که اگه اینطوره تبریک میگم شما حالا یک کارکشته هستید )مخاطب این پست فقط برنامه نویسای مبتدی نیستن چه بسا که برخی از برنامه نویس های با سابقه ام با خوندن این پست یاد خاطراتشون بیوفتن و چیزهایی به گفته های من اضافه کنند.پس بریم سراغ مراحل و از این خط به بعد با یک مخاطب فرضی که یکی از سوالای بالا رو پرسیده رو به رو هستیم و جوابش رو میخواهیم هرچه دقیق تر بدیم.مرحله اول : تعیین هدفخب شما چرا میخوای برنامه نویس بشی ؟! اصلا چی شد که خلا برنامه نویس شدن رو توی وجودت حس کردی؟شنیده میشه این روز ها با مقالاتی که وجود داره اغلب میگن بخاطر درامد برنامه نویسی ، بخاطر پول ، نون تو این شغله داداش ! و ازین حرفا که اگه علت برنامه نویس شدنتون اینه باید عرض کنم شما در مشاغل دیگه قطعا موفق تر از برنامه نویسی خواهید بود.اما اگر دلایلی مانند علاقه ، کنجکاوی ، احساس نیاز به خلق یک ایده و ... رو دلیل برای ورود به دنیای برنامه نویسی می دونید باید بگم که خوش اومدید و می تونید به مرحله ی بعدی برید.مرحله دوم : تعیین پلتفرمدنیای برنامه نویسی یک دنیای خیلی بزرگه و مهم ترین چیز اینه که مشخص کنی برای چه پلتفرم هایی میخوای برنامه نویسی کنی؟توسعه وب، توسعه اپلیکیشن، توسعه برنامه های مخصوص ویندوز/مک/لینوکس، هوش مصنوعی، پردازش تصویر، حوزه های مهندسی، هک، بیگ دیتا و ... از جمله شاخه های دنیای برنامه نویسی به حساب میان.یادتون باشه برای انتخاب یک شاخه ی خوب باز هم پول رو ملاک قرار ندید! شما توی هر حوزه ای بهترین باشید حتی توی همین ایران هم دنبالتون میوفتن برای کار پس باز هم علاقه رو در نظر بگیرید تا از پس چالش های راه به سادگی بر بیاید.مرحله سوم : انتخاب راه درستاین مهم ترین مرحله هست ! توصیه میکنم اگه میخواید برنامه نویس خوبی باشید حتما زبان انگلیسی خودتون رو تقویت کنید.چندین ترم به کلاس زبان برید و لازم نیست که مثل بلبل انگلیسی صحبت کنید اینکه توانایی Reading خوبی داشته باشید و بتونید نیازهاتون رو در Writing برطرف کنید کافیه.سپس واقعا بهتون توصیه میکنم دور منابع ایرانی رو خط بکشید ! 99 درصد منابع ایرانی فقط برای سود مالی تشکیل شدند و هیچ اهمیتی به کیفیت آموزش نمیدن و تنها یک Doc مطالعه کردند یا یک فیلم از یوتیوب دیدند و عین همون رو پیاده سازی می کنن یا دیگه خیلی لطف کنند نمونه مثال های خود Doc رو میزنن!فرق زیادی بین یک برنامه نویس و کد نویس هست که امیدوارم در پایان این مقاله بهش پی ببرید.اما لازمه بدونید هیچ منبع ایرانی ای خوب نیست ! به سراغ Doc اصلی زبان و یا کتابخانه و یا فریمورک مورد نظرتون برید و بخونید و در Community هاش شرکت کنید و فعال باشید.مرحله چهارم : لطفا شکست بخوریدخواهش میکنم شکست بخورید. شکست باعث میشه که اعتماد به نفس کاذب شما در اوایل برنامه نویسی خرد بشه و این جا یا تلاش می کنید و ادامه میدید و اون توهمی که از خودتون داشتید رو به واقعیت تبدیل می کنید یا شما مناسب برنامه نویسی نبودید و میدان رو برای حضور دیگران خالی می کنید.مرحله پنجم : رفتار تارزان را نداشته باشیدخیلی از دوستان هستند که با یادگرفتن Base یک زبان و یا خسته شدن از آن و یا تعریف های بی جای دیگران از زبان های دیگه سریعا کوچ می کنند و به قولی ازین شاخه به اون شاخه می پرند مثل تارزان! لطفا اینطور نباشید و بدونید که یادگرفتن یک زبان برنامه نویسی تنها نحوه ی نوشتن اون زبان نیست بلکه شما باید ساختار اون زبان رو بشناسید باید مفهوم برنامه نویسی رو درک کنید و در انتها باید یک آرشیتکت در زبان مورد نظرتون باشید تا زمانش فرا برسه که بدونید چطوری زبان های دیگه رو هم امتحان کنید.مرحله ششم : گیت را شخم بزنیدبه ریپو های مختلف گیت هاب برید و کد های زیادی رو مطالعه کنید و سعی کنید تا جایی که می تونید اون ها رو تغییر بدید و با روش خودتون بنویسید حتی اگه شده یک کامنت اضافه کنید تا با روش های مختلف حل مسئله آشنا بشید.مرحله هفتم : به روز بمانیدرپوهای گیت هاب ، وبسایت medium ، همین ویرگول خودمون ، انجمن های تخصصی ، یوتیوب ، وبسایت اصلی یا همون Doc رسمی زبان شما و ... محل مناسبی هستند که شما را به روز نگه دارند.باید بدونید در برنامه نویسی هیچ روزی نیست که بیدار بشید و بگید خب دیگه از امروز هیچی لازم نیست یاد بگیرم و فقط کد میزنم ! نه این تصور اشتباهههمیشه برای یادگیری Best Practice ها و Design Pattern ها و داشتن یک Performance بهتر، باید در طول روز یک چهارم وقتتون رو به مطالعه اختصاص بدید و تاثیرش رو در کدها و پیشرفتتون ببینید.مرحله هشتم : به دیگران کمک کنیدباور کنید اگر حتی همه ی جمعیت کره زمین هم برنامه نویس بشوند قرار نیست جای شما رو تنگ کنند پس به دیگران کمک کنید و بدونید با کمک کردن به دیگران می تونید دنیای بهتری بسازید.در انتها هم لازمه بگم از حاشیه دوری کنید!هیچوقت در بحث هایی مثل این که چه زبانی بهتره چه زبانی بدتره شرکت نکنید.برای وقتتون ارزش قائل باشید و همیشه در حال یادگیری :)</description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Mon, 18 Mar 2019 01:24:16 +0330</pubDate></item><item><title>بی پناه ترین مغزهای ایران</title><link>https://virgool.ir/@vahedi.ce/the-most-shelter-of-irans-brains-h87ocubnihdc</link><description>قضیه از جایی شروع میشه که توی سایت های فریلنسری ، گروه ها و کانال های تلگرامی گشت و گذار می زدم و یه نگاهی به شبکه های اجتماعی مخصوص استخدام مینداختم !یه سری پروژه ها رو میبینم که تعریف شدن و براشون بازه ی قیمتی تعریف شده ! خب بگذار یه نگاهی بندازم... طراحی یک سایت + SEO ( تا اینجاش جالبه و روی لینک کلیک میکنم تا جزئیات بیشتری رو بفهمم ) خب بازه ی قیمتی مدنظر کارفرما : 100/000 تومان الی 300/000 تومان !هر طور فکر می کنم میبینم هزینه ی هاست و دامنه به تنهایی شاید حدود 80% این مبلغ باشه :/تب مرورگر رو می بندم و میرم سراغ VsCode و شروع میکنم به ادامه ی پروژه هاماما این بار نا امیدانه تر !و البته اندکی هم متفکرانه...تفکر به اینکه چرا ما برنامه نویس ها #صنف نداریم؟! چرا هیچ جایی نیست که برای ما قیمت تعیین کنه؟!چرا حضور دلال ها با درصدهای بالا توی این حوزه عادی شده؟! ( اکثر تحصیل کرده های رشته های دیگه شغل شریف دلالی در عرصه ی پروژه های کامپیوتری و برنامه نویسی دارن ) !!چرا واقعا هیچ جایی نیست که از ما حمایت کنه!؟ولش کن..!چرا زیاده واسه گفتن..!برنامه نویس حرفاشو توی ادیتور می زنه.اینجا #ایران ، صدایِ بردگی برنامه نویسان</description><category>محمد واحدی</category><author>محمد واحدی</author><pubDate>Fri, 02 Nov 2018 18:10:22 +0330</pubDate></item></channel></rss>