مطالب
HTML5 Web Component - قسمت اول - معرفی و مفاهیم اولیه
Web Components مجموعه‌ای از تکنولوژی‌هایی می‌باشند که امکان ساخت المان‌های سفارشی با قابلیت استفاده‌ی مجدد و به همراه کپسوله‌سازی ساختار، استایل و عاملیت (Functionality) متناظر با المان ایجاد شده را در اختیار شما قرار می‌دهد. 

A Path to Standard Components

در این سری چند قسمتی، ابتدا روش ساخت Web Components را بدون استفاده از ابزار خاصی بررسی کرده و در ادامه با معرفی Stenciljs، چند کامپوننت سفارشی را طراحی خواهیم کرد.

سه تکنولوژی اصلی مورد استفاده برای ساخت Web Components عبارتند از:

  • Custom Elements
  • Shadow DOM
  • HTML Templates


Custom Elements

مجموعه‌ای از API‌های جاوااسکریپتی هستند که امکان تعریف یکسری المان معتبر HTML را با قالب‌، رفتار و نام سفارشی، فراهم می‌کنند. علاوه بر اینکه می‌توان یک المان سفارشی مستقل (Autonomous custom elements) را تعریف کرد، امکان سفارشی‌سازی و گسترش المان‌های موجود (Customized built-in elements) را نیز خواهیم داشت. 
المان‌های سفارشی تعریف شده را مانند کامپوننت‌های Angular و یا React تصور کنید؛ با این تفاوت که هیچ وابستگی به Angular و یا React ندارند. همچنین امکان استفاده از آنها در انوع و اقسام فریمورک‌های فرانت-اند وجود دارد.
شکل ساده‌ی یک Custom Element، متشکل است از کلاسی که کلاس HTMLElement را گسترش می‌دهد و یک نام یکتا که باید حتما دارای یک «-» باشد (kebab-case). برای مثال:
//app.component.js
class AppComponent extends HTMLElement {
  static is = 'app-root'
  connectedCallback(){
    this.innerHTML=`<h1>Hello World!</h1>`
  }
}

customElements.define(AppComponent.is, AppComponent)

//index.html
<app-root></app-root>



در تکه کد بالا، از متد connectedCallback به عنوان یکی از متدهای چرخه‌ی حیات یک المان سفارشی، برای تنظیم innerHTML آن استفاده شده است. سپس با استفاده متد define مربوط به CustomElementRegistry که از طریق window.customeElements قابل دسترسی می‌باشد و با مشخص کردن نام و کلاس مرتبط، المان مورد نظر را ثبت و معرفی کردیم.

برای سفارشی‌سازی یک المان موجود، کار با ارث‌بری از کلاس متناظر با آن المان شروع می‌شود. به عنوان مثال در اینجا قصد داریم با کلیک بر روی لینک‌های موجود در صفحه و قبل از هدایت به آدرس مقصد، یک تأییدیه را از کاربر بگیریم:
//confirm-link.component.js
class ConfirmLinkComponent extends HTMLAnchorElement {
  static is = "confim-link";
  connectedCallback() {
    this.addEventListener("click", e => {
      if (!confirm("Are you sure?")) {
        e.preventDefault();
      }
    });
  }
}
customElements.define(ConfirmLinkComponent.is, ConfirmLinkComponent, {
  extends: "a"
});
<a href="http://google.com" is='confirm-link'>
google.com
</a>
در اینجا در بدنه‌ی متد connectedCallback، مشترک رخداد کلیک المان جاری شده و براساس نتیجه‌ی تأییدیه، تصمیم به ادامه یا لغو رفتار پیش‌فرض آن گرفته‌ایم. برای معرفی این المان جدید، کافی است از طریق آرگومان سوم متد define، مشخص کنیم که قصد گسترش چه المانی را داریم. از این پس اگر لینک‌های موجود را از طریق ویژگی is با "confirm-link" تزئین کرده باشید، شاهد رفتار سفارشی جدید خواهیم بود.

Shadow DOM

جنبه‌ی بسیار مهم Web Components، کپسوله‌سازی می‌باشد که امکان مخفی کردن ساختار، استایل و رفتار متناظر با المان سفارشی را مهیا می‌کند تا با سایر قسمت‌های کد تداخلی نداشته باشد. در این میان Shadow DOM نقش اصلی را برای رسیدن به این سطح از کپسوله‌سازی ایفا خواهد کرد. Shadow DOM به عنوان یک نسخه‌ی کپسوله شده‌ی DOM می‌باشد که امکان کپسوله‌سازی Markup & Styling و همچنین کاهش پیچیدگی استایل‌دهی را مهیا خواهد کرد. می‌توان Shadow DOM را همانند iframe تصور کرد که امکان نشتی استایل‌ها و سلکتورها از Light DOM (همان DOM اصلی) به داخل و از داخل به Light DOM وجود ندارد؛ ولی برخلاف iframe همچنان Shadow Rootهای (المان ریشه Shadow DOM) متناظر، در همان کانتکست DOM اصلی قرار دارند و همچنین در اینجا برای دسترسی به مقادیر المان‌های موجود در Shadow DOM، می‌توان یک API مناسب را در سطح المان سفارشی در نظر گرفت، ولی در مقابل برای همین کار در یک iframe نیاز است تا DOM متناظر با آن را Traverse کنیم که البته به عمد به این صورت طراحی شده است؛ چرا که اهداف دیگری را نیز دنبال می‌کند.

به تصویر زیر توجه نمائید:

برای مشاهده‌ی Shadow DOM متناظر با یکسری المان توکار مانند input.range یا input.date در مرورگر کروم، لازم است به قسمت Developer tools آن مراجعه کرده و سپس با فشردن دکمه‌ی F1 به قسمت تنظیمات آن مراجعه کرده و در قسمت Preferences آن و بخش Elements گزینه "Show user agent shadow DOM" را انتخاب کنید. در اینجا input به عنوان المانی که Shadow DOM به آن متصل شده (attach) نقش Shadow Host را ایفا می‌کند.
برای اتصال یک Shadow DOM به یک المان، به شکل زیر می‌توان عمل کرد:
var div = document.createElement('div');
var shadowRoot = div.attachShadow({mode: 'open'}); //or mode: 'closed'
shadowRoot.innerHTML = '<h1>Hello Shadow DOM</h1>';

متد attachShadow یک Shadow DOM Tree جدید را به div متصل کرده و ارجاعی به shadowRoot آن را برمی‌گرداند. این shadowRoot از طریق خصوصیت host نیز ارجاعی را به میزبان خود دارد. از این پس نیز از طریق خصوصیت div.shadowRoot امکان دسترسی به Shadow DOM ایجاد شده خواهیم داشت. البته به دلیل اینکه در اینجا با حالت 'open' استفاده شده است، این دسترسی به shadowRoot از طریق المان وجود دارد، در غیر این صورت اگر با 'closed' مقداردهی شود، خصوصیت div.shadowRoot مقدار نال خواهد داشت و امکان دسترسی به المان‌های داخلی از طریق جاوااسکریپت ممکن نخواهد بود. 
نکته: 'user-agent' نیز حالتی است که برای المان‌های توکار مانند input.range و ... مورد استفاده قرار می‌گیرد و رفتاری شبیه به حالت 'closed' را دارد.
نکته: امکان اتصال Shadow DOM به المان‌های خاصی از جمله div و یا المان‌های سفارشی که کلاس HTMLElement را گسترش می‌دهند (این اتصال در زمان پیاده‌سازی آنها انجام خواهد شد)، وجود دارد.
در زمان استفاده از متد attachShadow، علاوه بر امکان تعیین حالت آن، امکان تنظیم delegatesFocus برای برطرف کردن موضوعات مرتبط با focus در زمان توسعه‌ی المان‌های سفارشی مورد استفاده قرار می‌گیرد. به این صورت که اگر در قسمتی از المان سفارشی که خاصیت و قابلیت focus را ندارد، کلیک شود، focus به اولین المان با قابلیت focus داخل المان سفارشی خواهد رسید و از این پس امکان استایل‌دهی با استفاده از سلکتور custom-element:focus را خواهیم داشت.

مفهوم دیگری وجود دارد تحت عنوان Shadow Boundary که تعیین کننده‌ی مرز بین Light DOM و Shadow DOM و همان لایه‌ی مهیا کننده‌ی کپسوله‌سازی Styling و Markup می‌باشد. در مطالب آتی خواهیم دید که به چه شکلی رخدادهای سفارشی ما قابلیت عبور از این لایه را خواهند داشت.


HTML Templates 

تا قبل از اینکه المان template معرفی شود، از یکی از روش‌های زیر برای استفاده‌ی مجدد از یک قالب HTML عمل می‌کردیم:
1- استفاده از یک المان خاص با ویژگی hidden یا استایل display:none 
  • استفاده از DOM و آگاه بودن مرورگر از وجود آن، عملیات clone را ساده خواهد کرد.
  • محتوای داخل آن رندر نخواهد شد.
  • اگرچه محتوای آن مخفی می‌باشد، با این حال درخواست‌های مرتبط با تصاویر یا اسکریپت‌ها انجام خواهد شد.
<div id="template" hidden>
  <img src="logo.png">
  <div class="comment"></div>
</div>

2- استفاده از تگ script با یک type سفارشی
<script id="template" type="text/x-template">
  <img src="logo.png">
  <div class="comment"></div>
</script>

<script id="template" type="text/x-kendo-template">
        <ul>
            # for (var i = 0; i < data.length; i++) { #
            <li>#= data[i] #</li>
            # } #
        </ul>
</script>
  • از آنجا که تگ script به صورت پیش‌فرض دارای استایل display:none می‌باشد، محتوای داخل آن رندر نخواهد شد.
  • به دلیل عدم مقداردهی ویژگی type آن با "text/javascript"، مرورگر محتوای آن را به عنوان کد جاوااسکریپت parse نخواهد کرد.
  • استفاده از خصوصیت innerHTML مشکل امنیتی XSS را بدنبال خواهد داشت .
HTML Template ویژگی‌های مثبت هر دو روش قبل را دارد. از طریق کد امکان clone و رندر کردن آن وجود دارد و همچنین کوئری المان‌های داخل آن نیز ممکن نیست:
<template id="template">
  <img src="logo.png">
  <div class="comment"></div>
</template>
و برای فعال‌سازی آن از طریق متد cloneNode متناظر با خصوصیت content به شکل زیر عمل خواهیم کرد:
  var template = document.querySelector("template");
  var clonedNode = template.content.cloneNode(true); //deep:true
  document.body.appendChild(clonedNode);
نکته: امکان تعریف قالب‌های تودرتو نیز وجود دارد که در این صورت به شکل جداگانه‌ای باید عملیات فعال‌سازی هر کدام از آنها انجام گیرد.
نظرات مطالب
آشنایی با قابلیت FileStream اس کیوال سرور 2008 - قسمت سوم
برای سناریویی که تصاویر زیادی لازم است در هر بار واکشی ( مانند یک گالری تصاویر که حجم آنها بالاتر از 256 کیلو بایت) نمایش داده شوند، آیا باز هم استفاده از این روش پیشنهاد میشود؟ با توجه به اینکه به دلیل اجرای کوئری برای واکشی بایت‌های مرتبط با هرکدام از فایل‌ها نسبت به حالت استفاده از فایل سیستم معمولی کند‌تر خواهد بود.
البته با در نظر گرفتن مباحث کشینگ.
نظرات مطالب
تغییر اندازه تصاویر #1
لطفا در مورد اینکه در زمان واکشی تصاویر از دیتابیس (کش کنیم ) توضیح دهید
چون خیلی سرعت کار با سایت پایین میاد
مثلا هر بار کاربر که بخواد از صفحه ای به صفحه ای دیگه بره تصاویر از نو بارگزاری میشن و این سرعت سایت رو کند میکنه
مطالب
چگونه نرم افزارهای تحت وب سریعتری داشته باشیم؟ قسمت هفتم
قسمت ششم 

20.اسکریپت در پایین صفحه
لینک‌های مربوطه به javascript‌های خود را تا جای ممکن در پایین صفحه قرار دهید. وقتی parser مرورگر به فایل‌های javascript می‌رسد، تمامی فعالیت‌ها را متوقف کرده و سعی در دانلود و سپس اجرای آن دارد. برخلاف اینکه مرورگرها امکان دانلود چند فایل را به صورت همزمان از سرور دارند، هنگامی که به اسکریپت‌ها می‌رسند، تنها یک فایل را دانلود می‌کنند. یعنی اجرای برنامه و دانلودهای مرتبط با صفحه شما متوقف شده و پس از دانلود و اجرای اسکریپت اجرای آنها ادامه پیدا می‌کند. این مسئله وقتی نمود بیشتری پیدا می‌کند که شما فایل هغای اسکریپت با حجم و تعداد بالا در برنامه خود استفاده می‌کنید.
برای فرار از این مشکل می‌توانید تگهای مربوط به اسکریپت را در آخر صفحات خود بگذارید. فقط دقت کنید اگر نیاز است که قبل از نمایش صفحه تغییری ذر DOM ایجاد کنید، باید حتما اسکریپت‌های مربوطه را بالای صفحه قرار دهید.
روش دیگر دانلود فایل‌های اسکریپت به وسیله AJAX است که انشاء الله در آینده مقاله ای در این رابطه خواهم نوشت.

21.CDN
CDN یا Content Delivery Network سرورهای توزیع شده ای در سطح دنیا هستند که یک نسخه از برنامه شما برای اجرا بر روی آن قرار دارد. هنگامی که کاربر می‌خواهد به سایت شما دسترسی پیدا کند به صورت خودکار به نزدیکترین سرور منتقل می‌شود تا بتواند سرعت بیشتری را تجربه کند. علاوه بر این CDN باعث بالانس شدن بار ترافیک شبکه شما شده خط حملات D.O.S و D.D.O.S را به حداقل می‌رساند.

زمانیکه شما یک سیستم CDN را فعال میکنید تاثیر آن بصورت زیر خواهد بود:
۱- شبکه توزیع محتوا یا همان CDN تمامی سرورهای شبکه جهانی اینترنت را پوشش میدهد. بنابراین زمانیکه شما این سیستم را برای سایت خود فعال میکنید اطلاعات شما بر روی تمامی این سرورها کپی و ذخیره میشود و زمانیکه یک بازدیدکننده به سایت یا وبلاگ شما وارد میشود محتوای سایت شامل تصاویر و متون را از نزدیک‌ترین سرور نزدیک به خود دریافت میکند و مستقیما به هاست یا سرور شما متصل نمیشود. این کار موجب بهبودی چشمگیر در عملکرد سایت شما خواهد شد.
۲- CDN تمام اطلاعات ثابت شما مانند تصاویر، کدهای CSS و javascript، mp3، pdf و فایلهای ویدئویی شما را پشتیبانی میکند و تنها اطلاعاتی که قابل تغییر و بروزرسانی هستند مانند متون و کدهای HTML از سرور اصلی شما فراخوان میشوند. با این کار مصرف پهنای باند هاست شما کاهش یافته و هزینه ای که سالانه برای آن میپردازید کاهش چشمگیری خواهد داشت.
۳- تفاوت سرعت و عملکرد برای خودتان یا افرادی که در نزدیکی سرور اصلی شما هستند تفاوت زیادی نخواهد داشت ولی برای کسانی که ار نقاط مختلف جهان به سایت شما وارد میشوند این افزایش سرعت ناشی از CDN کاملا محسوس خواهد بود، با توجه به اینکه سایتهای ایرانی معمولا سرور و هاست خود را از خارج و کشورهایی مانند آلمان و آمریکا تهیه میکنند و عموم بازدیدکنندگان از داخل کشور هستند استفاده از CDN میتواند بسیار موثر باشد. برای تعیین تاثیر CDN بر سرعت سایت میتوانید عملکرد خود را با ابزارهایی مانند Pingdom و GTmetrix بعد و قبل از فعال سازی CDN بررسی و مقایسه کنید. 
ابزارها، تکنیک‌ها و روش‌های متفاوتی برای راه اندازی CDN وجود دارد که نیازمند مقاله ای مجزا می‌باشد.